JavaScript 面试题标准答案模板(对应前文核心考点)

以下模板按"考点分类+问题+标准答案"结构整理,覆盖中高级面试高频题,可直接背诵并结合实际场景调整,确保答题逻辑清晰、要点全面。

一、原型链与继承类面试题

  1. 问题:请解释 JS 中 prototype、proto、constructor 的关系

标准答案:

三者是构成 JS 原型链的核心,核心关系可总结为一句话:实例的 proto 指向其构造函数的 prototype,而原型对象的 constructor 指向关联的构造函数。

• prototype:仅函数独有,是构造函数的"原型对象",用于存储所有实例共享的属性和方法(如 Array.prototype.push),避免实例重复创建相同方法造成内存浪费;

proto:所有对象独有,是实例的"原型指针",本质是访问原型对象的内部属性(ES6 推荐用 Object.getPrototypeOf() 替代,避免直接操作),实例通过它关联到构造函数的 prototype;

• constructor:仅原型对象独有,默认指向创建该原型对象的构造函数(如 User.prototype.constructor === User),实例可通过原型链继承该属性,用于判断实例的构造函数类型。

  1. 问题:ES6 class 与 ES5 原型继承有什么区别?

标准答案:

ES6 class 是 ES5 原型继承的语法糖,底层仍基于原型链实现,但存在 3 个关键差异,让代码更符合传统 OOP 语法规范:

  1. 调用限制:class 不能像 ES5 构造函数一样直接调用(如 User() 会报错),必须用 new 关键字创建实例,避免误调用导致全局变量污染;

  2. 方法可枚举性:class 定义的方法默认不可枚举(无法通过 for...in 遍历),而 ES5 原型上的方法默认可枚举(需手动用 Object.defineProperty 设置不可枚举);

  3. 继承逻辑:class 继承需通过 extends 关键字声明,且子类构造函数必须调用 super()(本质是借调父类构造函数,等价于 ES5 的 Parent.call(this)),而 ES5 继承需手动修改子类原型指向(Child.prototype = Object.create(Parent.prototype))并修复 constructor 指向,步骤更繁琐。

二、事件循环(Event Loop)类面试题

  1. 问题:请描述 JS 事件循环的执行流程

标准答案:

JS 是单线程语言,事件循环是实现异步的核心机制,核心逻辑是"同步优先、微任务先于宏任务",具体流程分 4 步:

  1. 执行同步代码:所有同步代码按顺序进入调用栈(Call Stack)执行,遇到异步任务时,将宏任务(如 setTimeout)放入"宏任务队列",微任务(如 Promise.then)放入"微任务队列";

  2. 清空微任务队列:同步代码执行完毕后,立即遍历微任务队列,按顺序执行所有微任务(执行过程中产生的新微任务会追加到队列末尾,一并执行),直到微任务队列为空;

  3. 执行一个宏任务:微任务清空后,从宏任务队列头部取出一个宏任务执行(仅执行一个,而非全部);

  4. 循环重复:重复上述 1-3 步,形成"事件循环",直到所有任务执行完毕。

  5. 问题:setTimeout 为什么会出现延迟不准的情况?

标准答案:

setTimeout 的延迟时间(如 setTimeout(fn, 1000) 中的 1000ms)是"最小等待时间",而非"精确执行时间",延迟不准的核心原因有两点:

  1. 同步代码阻塞:若调用栈中存在耗时同步代码(如大型循环),setTimeout 会等待同步代码完全执行完毕后,才会将回调函数放入宏任务队列,导致实际等待时间超过设定延迟;

  2. 宏任务队列排队:setTimeout 属于宏任务,即使回调函数进入队列,也需等待队列中前面的宏任务(如 DOM 事件回调、其他 setTimeout)执行完毕后才能运行,进一步增加延迟。

例如:若同步代码执行耗时 2s,即使 setTimeout 设定 1s 延迟,回调也会在 2s 后才执行。

三、内存管理与泄漏类面试题

  1. 问题:JS 中常见的内存泄漏场景有哪些?如何解决?

标准答案:

内存泄漏是指"不再使用的对象仍被引用,无法被垃圾回收器(GC)释放",常见场景及解决方案如下:

  1. 意外全局变量:未用 let/const 声明的变量(如 a = 10)会自动成为全局变量,被 window 长期引用。解决:所有变量用 let/const 声明,减少不必要的全局变量,用模块封装代码;

  2. 闭包长期引用:闭包会保留外部变量引用,若闭包被全局变量持有(如 window.counter = 闭包函数),外部变量无法回收。解决:闭包使用完后主动解除引用(如 counter = null),避免将闭包赋值给全局变量;

  3. 未清理的 DOM 引用:DOM 元素被删除后,若仍有变量引用(如 let btn = document.getElementById("btn")),浏览器无法回收 DOM 内存。解决:删除 DOM 后将引用设为 null(btn = null),用 WeakMap 存储 DOM 引用(无引用时自动回收);

  4. 未清理的定时器/事件监听:setInterval、addEventListener 未清理,回调函数会一直被引用。解决:定时器用 clearInterval 清理,组件卸载时用 removeEventListener 移除监听。

  5. 问题:如何用 Chrome 开发者工具排查内存泄漏?

标准答案:

排查核心是"跟踪内存变化+定位泄漏对象",关键步骤如下:

  1. 打开工具:打开目标页面,按 F12 打开 Chrome 开发者工具,切换到 Memory 面板;

  2. 跟踪内存分配:选择 Allocation Instrumenter Timings 模式(可实时记录内存分配情况),点击 Start 开始记录;

  3. 模拟用户操作:重复触发可能导致泄漏的操作(如切换组件、点击按钮),观察内存曲线;

  4. 判断泄漏:若内存曲线持续上升且操作结束后不回落(无明显下降),说明存在内存泄漏;

  5. 定位泄漏对象:切换到 Heap snapshot 模式,点击 Take snapshot 拍摄内存快照,筛选"Detached DOM nodes"(脱离文档的 DOM 节点)或"Closures"(闭包),查看未被回收的大对象,结合代码定位引用源头(如全局变量、未清理的监听)。

四、工程化(模块化+Webpack)类面试题

  1. 问题:ES Module(ESM)与 CommonJS 有什么关键区别?

标准答案:

两者是 JS 主流模块化规范,核心区别体现在 3 个维度,也是 ESM 取代 CommonJS 的原因:

  1. 加载时机:ESM 是"编译时加载"(静态分析),在代码编译阶段就能确定依赖关系,支持 Tree-Shaking(剔除未使用代码);CommonJS 是"运行时加载"(动态加载),执行到 require 时才加载模块,无法做静态优化;

  2. 导出方式:ESM 导出的是"模块引用",模块内部值变化时,导入方会同步更新(如 export let a = 1,修改 a 后导入方的 a 也会变);CommonJS 导出的是"值的拷贝",导出后模块内部值变化不影响导入方;

  3. this 指向:ESM 模块中 this 是 undefined(避免全局污染);CommonJS 模块中 this 指向 module.exports(类似全局对象)。

  4. 问题:请简述 Webpack 的核心原理和打包流程

标准答案:

Webpack 是前端构建工具,核心是"将多个模块(JS/CSS/图片等)打包成浏览器可识别的 bundle 文件",核心原理基于"模块依赖解析+资源转换"。

核心概念:

• Entry:入口文件(如 src/index.js),Webpack 从这里开始递归解析所有依赖;

• Output:输出配置(如 dist/main.js),指定打包后文件的路径和名称;

• Loader:处理非 JS 模块的"转换器"(如 css-loader 解析 CSS,babel-loader 将 ES6 转 ES5);

• Plugin:扩展 Webpack 功能的"插件"(如 HtmlWebpackPlugin 生成 HTML 文件,TerserPlugin 压缩 JS)。

打包流程:

  1. 初始化:读取 Webpack 配置文件,确定 Entry、Output、Loader、Plugin 等配置;

  2. 解析依赖:从 Entry 出发,递归解析所有 import/require 依赖,生成模块依赖图谱;

  3. 资源转换:用对应 Loader 处理非 JS 模块(如 CSS 转成 JS 模块),将所有资源统一转为 JS 模块;

  4. 生成 AST 与优化:将 JS 模块转为抽象语法树(AST),分析依赖关系,执行 Tree-Shaking 剔除未使用代码;

  5. 生成 bundle:合并所有优化后的模块,生成最终的 bundle 文件(如 main.js),完成打包。

相关推荐
沐怡旸1 分钟前
【底层机制】垃圾回收(GC)底层原理深度解析
android·面试
Moonbit12 分钟前
MoonBit Pearls Vol.12:初探 MoonBit 中的 Javascript 交互
javascript·后端·面试
chenbin___20 分钟前
react native中 createAsyncThunk 的详细说明,及用法示例(转自通义千问)
javascript·react native·react.js
沐怡旸24 分钟前
【穿越Effective C++】条款13:以对象管理资源——RAII原则的基石
c++·面试
技术小丁1 小时前
使用 HTML + JavaScript 实现酒店订房日期选择器(附完整源码)
前端·javascript
hashiqimiya1 小时前
harmonyos的鸿蒙的跳转页面的部署
开发语言·前端·javascript
闭着眼睛学算法1 小时前
【双机位A卷】华为OD笔试之【排序】双机位A-银行插队【Py/Java/C++/C/JS/Go六种语言】【欧弟算法】全网注释最详细分类最全的华子OD真题题解
java·c语言·javascript·c++·python·算法·华为od
Drift_Dream1 小时前
深入浅出 requestAnimationFrame:让动画更流畅的利器
javascript
GIS瞧葩菜1 小时前
【无标题】
开发语言·前端·javascript·cesium
T___T1 小时前
彻底搞懂 CSS 盒子模型 box-sizing:小白也能看懂的布局核心
前端·面试