前端JS面试题终极整理(2025版)

802 阅读5分钟

本文汇总了100+高频前端 JavaScript 面试题,涵盖基础、进阶、性能、工程化、安全、框架等方向。每道题均给出「核心概念 + 代码示例 + 一句话总结」,确保 3 分钟速读、30 秒速记。
先理解,再背诵;让记忆成为理解的副产品。考前翻一遍,答题像呼吸。建议收藏,面试前 1 晚过一遍,命中率≈90%。


一、语言基础(1~30)

#题目 & 一句话答案
1闭包 → 函数能访问其词法作用域外的变量,常用于私有变量、防抖/节流。
2作用域链 → 变量查找沿作用域逐级向上直到全局,不可向下。
3原型链 → 对象查找属性时沿 __proto__ 逐级向上直到 null
4事件代理 → 把子元素事件委托给父元素,利用冒泡减少监听数量。
5继承 5 种 → 构造、原型、实例、拷贝、寄生组合;ES6 class extends 最常用。
6this 指向 → 谁调用指向谁;箭头函数继承外层;call/apply/bind 可改。
7事件模型 → 捕获 → 目标 → 冒泡;stopPropagation 阻止冒泡。
8new 过程 → 创建空对象 → 绑定 this → 执行构造函数 → 隐式返回。
9AJAX 原理 → 浏览器通过 XHR/fetch 异步发 HTTP 请求并局部更新页面。
10跨域方案 → JSONP、CORS、postMessage、nginx 反向代理、WebSocket。
11模块化 → 立即执行函数 → AMD/CMD → CommonJS → ES6 Module。
12异步加载 JSdeferasync、动态 createElement('script')、XHR 注入。
13内存泄漏 → 意外全局变量、闭包引用 DOM、未清理定时器、循环引用。
14XML vs JSON → JSON 体积小、解析快;XML 可扩展、描述性强。
15Webpack 作用 → 模块打包器,把一切资源视为模块,输出优化后的静态文件。

二、ES6+ & 新特性(31~60)

#题目 & 一句话答案
31let / const / var → let/const 块级作用域、无提升、暂存死区;const 只读引用。
32箭头函数特点 → 无 this/arguments、不可 new、语法简洁。
33Promise 链.then 返回新 Promise,支持链式;微任务队列优先宏任务。
34async/await → Promise 语法糖,同步写法处理异步;错误用 try/catch。
35Set / Map → Set 去重、Map 键可为对象;均支持 O(1) 增删查。
36Symbol → 唯一标识,可创建私有属性;内置 Symbol.iterator 定义迭代。
37数组去重[...new Set(arr)] 一行流;或 filter + indexOf
38深拷贝JSON.parse(JSON.stringify(obj)) 简单但有局限;完整方案用递归或 structuredClone
39防抖 vs 节流 → 防抖合并多次触发为最后一次;节流按固定间隔触发。
40严格模式限制 → 变量须声明、禁用 with、this 默认 undefined、函数参数不重名。

三、DOM / BOM / 性能(61~90)

#题目 & 一句话答案
61offset/client/scroll 区别 → offset = border+padding+content;client = padding+content;scroll = 实际内容高。
62事件坐标 → client 相对视口、page 相对文档、screen 相对屏幕。
63渲染流程 → HTML → DOM + CSSOM → Render Tree → Layout → Paint → Composite。
64重绘 vs 回流 → 改变外观不触发布局叫重绘;几何信息改变触发布局叫回流。
65性能优化 10 连 → 压缩资源、懒加载、CDN、缓存、雪碧图、减少 DOM、节流、SSR、HTTP2、WebP。
66浏览器缓存 → 强缓存(Expires/Cache-Control) + 协商缓存(ETag/Last-Modified)。
67垃圾回收 → 标记清除(常用)+ 引用计数(IE 旧);避免闭包泄漏。
68WebSocket → 全双工、ws 协议、无跨域、服务端推送首选。
69懒加载实现IntersectionObserver 检测进入视口再替换 data-src
70首屏优化 → 资源预加载、SSR、骨架屏、代码分割、关键 CSS 内联。

四、框架 & 工程化(91~120)

#题目 & 一句话答案
91MVVM 原理 → View ↔ ViewModel(数据劫持/脏检查) ↔ Model;数据驱动视图。
92Vue 双向绑定Object.defineProperty 劫持 getter/setter → Dep + Watcher。
93React 调和算法 → Diff 三策略(同级比较、类型不同替换、key 复用)。
94虚拟 DOM 优势 → 减少真实 DOM 操作、跨平台、批量更新。
95组件通信 → 父子 props/$emit;兄弟 EventBus;跨层级 provide/inject、Redux/Vuex。
96Vue 生命周期 → beforeCreate → created → beforeMount → mounted → updated → destroyed。
97React Hook 规则 → 只在顶层调用、只在函数组件/自定义 Hook 中调用。
98Webpack 优化 → 分包(SplitChunksPlugin)、Tree-Shaking、DllPlugin、多进程压缩、缓存。
99Babel 作用 → ES6+ 转 ES5、语法转换、Polyfill、代码压缩。
100CI/CD 流程 → 代码提交 → 自动化测试 → 构建 → 部署 → 回滚。

五、手写代码片段(121~154)

面试高频“手写题”速记,背住即可秒写。

// 121 防抖
const debounce = (fn, wait) => {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), wait);
  };
};

// 122 节流
const throttle = (fn, wait) => {
  let prev = 0;
  return (...args) => {
    const now = Date.now();
    if (now - prev > wait) {
      prev = now;
      fn.apply(this, args);
    }
  };
};

// 123 深拷贝
function deepClone(obj, hash = new WeakMap()) {
  if (obj == null || typeof obj !== 'object') return obj;
  if (hash.has(obj)) return hash.get(obj);
  const res = new obj.constructor();
  hash.set(obj, res);
  for (let key of Reflect.ownKeys(obj)) {
    res[key] = deepClone(obj[key], hash);
  }
  return res;
}

// 124 手写 Promise.all
Promise.myAll = (promises) =>
  new Promise((resolve, reject) => {
    const res = [], len = promises.length;
    let count = 0;
    promises.forEach((p, i) =>
      Promise.resolve(p).then(
        (val) => ((res[i] = val), ++count === len && resolve(res)),
        reject
      )
    );
  });

// 125 手写 instanceof
const myInstanceof = (obj, ctor) => {
  let proto = Object.getPrototypeOf(obj);
  while (proto) {
    if (proto === ctor.prototype) return true;
    proto = Object.getPrototypeOf(proto);
  }
  return false;
};

// 126 手写 new
function myNew(ctor, ...args) {
  const obj = Object.create(ctor.prototype);
  const res = ctor.apply(obj, args);
  return res !== null && (typeof res === 'object' || typeof res === 'function') ? res : obj;
}

// 127 手写 call / apply / bind
Function.prototype.myCall = function (ctx, ...args) {
  ctx = ctx || window;
  const key = Symbol();
  ctx[key] = this;
  const res = ctx[key](...args);
  delete ctx[key];
  return res;
};

// 128 数组扁平化
const flat = (arr, depth = 1) =>
  depth > 0
    ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flat(val, depth - 1) : val), [])
    : arr.slice();

// 129 柯里化
const curry = (fn) =>
  (...args) => (args.length >= fn.length ? fn(...args) : curry(fn).bind(null, ...args));

// 130 模板引擎简易实现
function render(template, obj) {
  return template.replace(/\{\{(\w+)\}\}/g, (_, key) => obj[key.trim()]);
}

六、速查表:面试 1 分钟背诵版

Topic关键词
闭包函数 + 词法作用域 → 私有变量 / 防抖节流
原型链obj → __proto__ → Constructor.prototype → Object.prototype → null
event loop宏任务 → 微任务 → 渲染 → 下一轮
跨域CORS、JSONP、postMessage、代理
继承ES6 class extends + super;寄生组合继承
性能懒加载、缓存、防抖、节流、Tree-Shaking
MVVM数据劫持 + 发布订阅 → 双向绑定
安全XSS(转义输入)、CSRF(Token 校验)、CSP

七、结语

把本文打印成 PDF,面试排队时反复背诵;
把代码片段手敲 3 遍,肌肉记忆永不遗忘。
祝你 2025 金三银四,Offer 多多!

(完)