2025前端面试题—JavaScript篇

好的,下面是 JavaScript 部分的经典面试题 + 中文解析 + 示例代码(demo)。这部分内容偏重核心机制与实战能力,适合系统复习、面试冲刺。


🧠 JavaScript 面试题(共 30 题)+ 详细解析与 Demo


1. JavaScript 有哪些数据类型?

答:

  • 基本类型(值类型)numberstringbooleanundefinednullsymbolbigint

  • 引用类型object(包括数组、函数、对象等)


2. typeof null 是什么?为什么?

答:
typeof null === 'object'
这是 JS 语言早期的设计缺陷,历史遗留问题。


3. 判断数组的方法有哪些?

答:

Array.isArray(arr);        // ✅ 推荐
Object.prototype.toString.call(arr) === '[object Array]'
arr instanceof Array

4. == 和 === 有什么区别?

答:

  • == 会进行类型转换

  • === 不进行类型转换,类型和值都必须相等

0 == '0'      // true
0 === '0'     // false

5. 什么是闭包?有什么作用?

答:
闭包是函数和其词法作用域的组合。
作用是:保护变量不被销毁、实现私有变量、缓存变量

示例:

function outer() {
  let count = 0;
  return function () {
    return ++count;
  };
}
const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2

6. 什么是作用域链?

答:
当访问变量时,JS 会从当前作用域向上查找,直到全局作用域,形成链式结构,称为作用域链。


7. 什么是原型和原型链?

答:

  • 每个对象都有一个 __proto__ 指向其构造函数的 prototype

  • 多个对象通过原型链连接,实现继承查找


8. 什么是 this?它是如何绑定的?

答:
this 指向取决于调用方式:

调用方式this 指向
普通函数调用 全局对象(严格模式下是 undefined
方法调用 谁调用指向谁
构造函数 new 指向新创建的实例对象
箭头函数 没有自己的 this,继承外层
call/apply/bind 显式绑定

9. 如何实现函数防抖和节流?

答:

  • 防抖(debounce):最后一次触发后一段时间才执行

  • 节流(throttle):规定间隔时间执行一次

function debounce(fn, delay) {
  let timer;
  return function () {
    clearTimeout(timer);
    timer = setTimeout(fn, delay);
  };
}

10. 什么是浅拷贝和深拷贝?

答:

  • 浅拷贝:只复制一层属性,引用类型共享

  • 深拷贝:递归复制所有层级

// 浅拷贝
const shallow = Object.assign({}, obj);

// 深拷贝(简单场景)
const deep = JSON.parse(JSON.stringify(obj));

11. 如何判断一个对象是空对象?

答:

Object.keys(obj).length === 0;
JSON.stringify(obj) === '{}';

12. 事件冒泡与捕获是什么?

答:

  • 捕获阶段:从 document 一直向目标元素传播

  • 冒泡阶段:从目标元素向上传播到 document

默认执行的是冒泡阶段,可用 addEventListener('click', fn, true) 监听捕获。


13. 什么是事件委托?

答:
通过将事件绑定在父级,利用事件冒泡,处理子元素的事件,提高性能。

document.getElementById('list').addEventListener('click', e => {
  if (e.target.tagName === 'LI') {
    console.log(e.target.innerText);
  }
});

14. setTimeout 和 setInterval 的区别?

答:

  • setTimeout(fn, t):延迟执行一次

  • setInterval(fn, t):每隔 t 毫秒重复执行


15. Promise 是什么?有哪些状态?

答:

  • Promise 是异步编程解决方案,有三种状态:

    • pending(进行中)

    • fulfilled(已成功)

    • rejected(已失败)

new Promise((resolve, reject) => {
  // ...
})
.then(res => {})
.catch(err => {});

16. async/await 的本质?

答:
是基于 Promise 的语法糖,使异步代码看起来像同步写法。

async function fetchData() {
  const res = await fetch(url);
  const data = await res.json();
}

17. var、let、const 有何区别?

特性varlet/const
作用域 函数级 块级作用域
提升 有,初始化为 undefined 有但不初始化,存在暂时性死区
重复声明 允许 不允许
const 不可变 不能重新赋值

18. new 操作符的原理?

答:

  1. 创建空对象

  2. 绑定 this

  3. 执行构造函数

  4. 返回对象


19. 手写 call、apply、bind 简化版

Function.prototype.myCall = function (ctx, ...args) {
  ctx = ctx || window;
  ctx.fn = this;
  const result = ctx.fn(...args);
  delete ctx.fn;
  return result;
};

20. 常见数组方法有哪些?

  • 遍历类:forEachmapfilterreduce

  • 查找类:findincludesindexOf

  • 变异类:pushpopsplicesort

  • 不变类:sliceconcat


21. 如何实现数组去重?

[...new Set(arr)]

或使用:

arr.filter((item, index) => arr.indexOf(item) === index)

22. JS 如何判断变量是对象?

typeof obj === 'object' && obj !== null

23. JSON.stringify 中不能序列化哪些?

  • undefined

  • function

  • symbol


24. Symbol 有什么作用?

答:
创建独一无二的值,常用于对象属性,避免冲突。


25. 什么是内存泄漏?

答:
不再使用的对象仍被引用,无法释放内存。常见场景:全局变量、闭包、定时器未清除、DOM 引用未释放。


26. 什么是垃圾回收机制?

答:
浏览器采用标记清除算法或引用计数,自动释放不再被引用的对象。


27. 事件循环(event loop)是什么?

答:
JS 单线程通过事件循环机制处理异步任务。主线程先执行同步任务,然后处理微任务(如 Promise)、再处理宏任务(如 setTimeout)。


28. 什么是微任务和宏任务?

答:

  • 微任务Promise.thenMutationObserver

  • 宏任务setTimeoutsetIntervalrequestAnimationFrame


29. 解释节流函数 throttle 的实现原理

function throttle(fn, delay) {
  let last = 0;
  return function () {
    const now = Date.now();
    if (now - last >= delay) {
      fn.apply(this, arguments);
      last = now;
    }
  };
}

30. 深拷贝如何实现?

简单版本:

JSON.parse(JSON.stringify(obj));

通用版本:

function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  const copy = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    copy[key] = deepClone(obj[key]);
  }
  return copy;
}

 

posted @ 2025-06-09 10:57  星米尔工作室  阅读(1740)  评论(0)    收藏  举报