共 65 道 JavaScript 方向的面试题,每题附完整答案与代码示例。点击右侧方框可标记掌握度。
JavaScript 共有 8 种数据类型 ,分为两大类: 原始类型(7种) - number — 数字 - string — 字符串 - boolean — 布尔值 - undefined — 未定…
== vs === - ===(严格相等):不进行类型转换,类型不同直接返回 false - ==(宽松相等):会先进行类型转换再比较 == 的转换规则 1. null == undefined → …
对象转原始类型会调用内部方法 ToPrimitive,过程如下: 转换流程 1. 调用 Symbol.toPrimitive()(如果存在) 2. 否则根据上下文调用 valueOf() 和 toSt…
核心区别 特性 原始类型 引用类型 ------ ---------- ---------- 存储位置 栈内存 (Stack) 堆内存 (Heap) 存储内容 值本身 指向堆内存的引用地址 赋值行为 …
逐个分析 1. [] + {} - + 运算符:左右都转原始类型 - [] → ToPrimitive('default') → toString() → '' - {} → ToPrimitive(…
闭包 是指一个函数能够访问其外部函数作用域中的变量,即使外部函数已经执行完毕。 形成条件 1. 函数嵌套 2. 内部函数引用外部函数的变量 3. 内部函数被返回或传递到外部 经典示例 应用场景 1. …
var vs let vs const 特性 var let const ------ ----- ----- ------- 作用域 函数作用域 块级作用域 块级作用域 变量提升 ✅ 提升且初始化为…
闭包 本身不是 内存泄漏,它只是让变量的生命周期延长到与闭包一致。但如果闭包长期存在且不再需要引用的变量,就会造成 实际的内存泄漏 。 什么情况下闭包会导致内存泄漏 如何避免 1. 及时清除引用 :用…
作用域链 是 JavaScript 在查找变量时,从内到外依次查找的作用域链表。 执行上下文与作用域 每个函数在创建时会保存一个 [[Environment]] 内部属性,指向定义时的词法环境。函数调…
IIFE (Immediately Invoked Function Expression)是在定义后立即执行的函数表达式。 语法 用途 1. 创建独立作用域 (避免污染全局) 2. 模块模式 (ES…
原型链 是 JavaScript 实现继承的机制。每个对象都有一个 proto (即 [[Prototype]])指向其构造函数的 prototype 对象。 原型链结构 具体示例 属性查找过程 访问…
new 做了 4 件事 1. 创建一个新的空对象 2. 将新对象的 proto 指向构造函数的 prototype 3. 将构造函数的 this 绑定到新对象并执行 4. 如果构造函数返回对象,则返回…
1. 原型链继承 - ✅ 简单,能继承原型方法 - ❌ 引用类型属性被所有实例共享,无法传参 2. 构造函数继承(call/apply) - ✅ 解决引用类型共享问题,可传参 - ❌ 无法继承原型上的…
class 是构造函数的语法糖,但有一些关键区别: 主要区别 特性 ES5 构造函数 ES6 class ------ ------------- ----------- 声明提升 ✅ 有提升 ❌ 无…
核心区别 - {}:原型指向 Object.prototype,继承了 toString、hasOwnProperty 等方法 - Object.create(null):原型为 null,是一个 纯…
this 的指向取决于 函数的调用方式 ,有 4 种绑定规则: 1. 默认绑定(独立调用) 2. 隐式绑定(作为对象方法) 3. 显式绑定(call/apply/bind) 4. new 绑定 优先级…
三者对比 方法 参数 执行时机 返回值 ------ ------ ---------- -------- call (thisArg, arg1, arg2, ...) 立即执行 函数返回值 app…
核心区别 特性 普通函数 箭头函数 ------ ---------- ---------- this 动态绑定,由调用方式决定 词法 this ,继承外层作用域 arguments 有自己的 arg…
逐行分析 obj.fn1() → 'obj' 普通函数,隐式绑定,this → obj obj.fn2() → 'window' 箭头函数没有自己的 this,继承外层作用域(全局),this → w…
这是一个增强版 bind,确保即使在后续被 call/apply 或作为方法调用时,this 仍然不变: 进阶版:支持 new 调用 实际应用 - React 早期(class 组件)在 constr…
JavaScript 是 单线程 语言,通过 事件循环 实现异步非阻塞。 执行栈与任务队列 1. 执行栈 (Call Stack):同步代码按顺序入栈执行 2. 微任务队列 (Microtask Qu…
三种状态 - pending (等待中)→ 初始状态 - fulfilled (已成功)→ resolve() 触发 - rejected (已失败)→ reject() 触发 状态一旦改变就 不可逆…
async/await 是 Generator + Promise 的 语法糖 ,让异步代码看起来像同步代码。 原理 async 函数返回一个 Promise,await 暂停函数执行直到 Promi…
输出结果 详细分析 1. 同步代码执行 - script start — 同步 - async1() 调用: - async1 start — 同步 - await async2() — async2…
方案:维护一个执行队列 使用示例 进阶版:支持回调通知 实际应用场景 - 批量上传文件 - 爬虫控制并发 - 大量 API 请求需要限流
使用示例 进阶:指数退避 async/await 版
输出结果 分析 同步阶段: 1. new Promise 的 executor 同步执行 → p1 constructor 2. p2 的 executor 同步执行 → p2 constructor…
常用 ES6+ 特性 1. let / const — 块级作用域变量声明 2. 箭头函数 — (a, b) = a + b 3. 解构赋值 4. 模板字符串 5. 展开运算符 6. 默认参数 7. …
Proxy Proxy 用于创建一个对象的代理,可以拦截对该对象的基本操作(属性查找、赋值、枚举、函数调用等)。 常用拦截器(Trap) Trap 拦截操作 ------ ---------- get…
对比表 特性 Map WeakMap Set WeakSet ------ ----- --------- ----- --------- 键类型 任意 仅对象 — — 值类型 任意 任意 — 仅对象…
Iterator(迭代器) 迭代器是一个对象,实现了 next() 方法,返回 { value, done }。 可迭代协议(Iterable) 实现了 [Symbol.iterator] 方法的对象…
可选链 ?. 安全地访问深层嵌套的属性,遇到 null/undefined 时短路返回 undefined,不会报错。 空值合并 ?? 当左侧为 null 或 undefined 时返回右侧值。 注意…
装饰器模式 :在不修改原函数的前提下,动态扩展其功能。 函数装饰器(高阶函数) 类装饰器(TC39 提案 / TypeScript) 实际应用 防抖 / 节流 本质上就是装饰器: 核心思想 - 开闭原…
map — 映射 对每个元素执行函数,返回 新数组 ,长度不变。 filter — 过滤 返回满足条件的元素组成的新数组。 reduce — 归约 将数组归约为单个值,最灵活但也最复杂。 对比 方法 …
区别 - 浅拷贝 :只复制第一层,嵌套的引用类型仍共享地址 - 深拷贝 :递归复制所有层级,完全独立 浅拷贝方法 深拷贝方法 1. structuredClone(推荐,现代浏览器原生支持) 2. J…
防抖(Debounce) 事件停止触发 n 秒后 执行,如果在 n 秒内再次触发则重新计时。 应用场景 :搜索框输入、窗口 resize、表单验证 节流(Throttle) 每 n 秒最多执行一次 ,…
JavaScript 内置错误类型 异常处理 自定义错误 Promise 错误处理 全局错误捕获 最佳实践 1. 不要吞掉错误 :catch 中至少要有日志 2. 区分错误类型 :自定义错误类便于分类…
V8 垃圾回收策略 V8 采用 分代回收 机制,将堆内存分为 新生代 和 老生代 。 新生代(Scavenge 算法) - 存放存活时间短的对象(1 8MB) - 分为 From 空间 和 To 空间…
浏览器事件循环 微任务 :Promise.then、queueMicrotask、MutationObserver 宏任务 :setTimeout、setInterval、I/O、UI 渲染 Node…
这是 fetch 最容易踩的坑之一。 原因:fetch 只在「网络层失败」时才 reject fetch 的设计是: 只有在网络请求本身失败(断网、DNS 解析失败、CORS 被拦截、请求被 abor…
三者的本质区别 维度 requestAnimationFrame setTimeout setInterval ------ ---------------------- ----------- --…
基于 setTimeout 递归(后台仍可计时) 用 时间戳 计算剩余时间,而不是简单递减,避免定时器漂移: 基于 requestAnimationFrame(与渲染帧同步,后台暂停) 两者差异 维度…
思路 给定 SKU 列表(每个 SKU 是一组规格的组合)和 当前已选规格 ,对每一个 未选中的规格维度 的选项,模拟把它加入已选集合,看是否能匹配到某个存在的 SKU;匹配不到就禁用。 关键点 - …
实现 使用示例 考察点 - 时间戳驱动 :用 now - startTime 算进度,避免依赖固定帧间隔,切后台也不会错乱。 - 缓动函数 :把线性进度 t 映射成非线性,实现加速 / 减速。 - 可…
核心区别 特性 CommonJS (CJS) ES Modules (ESM) ------ ---------------- ------------------- 语法 require/modul…
require 的执行过程 1. 路径解析 查找顺序: 2. 模块缓存 3. 模块包装 Node.js 将模块代码包裹在函数中: 这解释了为什么模块中有 require、module、 dirname…
ESM 加载流程 与 CommonJS 的关键区别 CommonJS 的步骤是 交织 的:加载→执行→导出,同步完成。 ESM 的步骤是 分离 的:先加载所有依赖,再建立绑定,最后执行。 1. Con…
ESM 导入 CJS 坑 1:命名导入不一定可用 CJS 的 module.exports 是运行时确定的,ESM 的 import {} 是编译时确定的。Node.js 通过静态分析尝试提供命名导入…
循环依赖 模块 A 依赖 B,B 又依赖 A,形成循环。 CommonJS 的处理 CJS 返回 已执行部分 的导出: ESM 的处理 ESM 返回 引用绑定 ,可以获取最终值: ESM 的执行顺序:…
require 路径解析 1. 内置模块 2. 相对/绝对路径 3. node modules 查找 4. 目录加载 exports 字段(Node.js 12+) exports 比 main 更强…
Tree Shaking 前提条件 1. 使用 ESM (CommonJS 不支持) 2. 生产模式构建 3. 标记 sideEffects sideEffects 详解 什么算副作用: 指定有副作用…
import() 是 ESM 的动态加载语法,返回 Promise,用于按需加载模块。 基本用法 使用场景 1. 路由懒加载 2. 条件加载 3. 按需加载大依赖 4. 加载语言包 import() …
检测循环依赖 1. madge 工具 2. Webpack 插件 3. ESLint 规则 常见循环依赖模式 1. 直接循环 2. 间接循环 解决方案 1. 提取共享模块(推荐) 2. 依赖注入 3.…
模块化发展历程 1. 全局变量(最早期) - ❌ 命名冲突 - ❌ 依赖管理困难 2. IIFE(立即执行函数) - ✅ 避免全局污染 - ❌ 依赖管理仍手动 3. CommonJS(Node.js)…
打包工具核心流程 1. 入口解析 从配置的 entry 开始,读取入口文件: 2. 依赖图构建 递归分析 import/require,构建模块依赖图: 简化实现: 3. 转换编译 对每个模块应用 l…
package.json 核心字段 入口字段 字段 作用 优先级 ------ ------ -------- main CJS 入口 基础 module ESM 入口(打包工具识别) 高于 main…
Monorepo 将多个项目/包放在同一个 Git 仓库中管理。 Monorepo vs Polyrepo 特性 Monorepo Polyrepo ------ ---------- -------…
Polyfill Polyfill (填充物):为旧浏览器提供新 API 的实现。 Polyfill vs Transpile 方式 作用 示例 ------ ------ ------ Transp…
1. 单一职责原则 每个模块只做一件事。 2. 显式依赖 3. 最小导出 只导出外部需要的 API,内部实现保持私有。 4. 统一导出入口 ⚠️ Barrel file 可能影响 Tree Shaki…
包管理器对比 特性 npm yarn (v1) pnpm ------ ----- ----------- ------ 安装速度 中 快 最快 磁盘空间 多 多 最少(硬链接) 幽灵依赖 ❌ 有 ❌…
Module Federation 模块联邦允许 多个独立构建的应用在运行时共享模块 ,是微前端的实现方案之一。 核心概念 概念 说明 ------ ------ Host 消费远程模块的应用(主应用…
区分方式 1. package.json type 字段 2. 文件扩展名(覆盖 type 设置) 3. 代码中的判断 环境差异 ESM 中使用 dirname ESM 中使用 require 顶层 …
按需加载维度 1. 路由级 :页面/路由按需加载 2. 组件级 :重组件按需加载 3. 依赖级 :大依赖按需加载 4. 资源级 :图片/字体按需加载 路由级懒加载 组件级懒加载 依赖级懒加载 资源级懒…
SSR 模块化挑战 1. Node.js 和浏览器环境差异 2. CJS vs ESM 在 SSR 中的处理 3. 模块副作用在服务端的行为 4. 条件导出的服务端入口 1. 环境差异 2. pack…