跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScriptNode.js大前端算法

前端核心面试题详解:从闭包原理到性能优化实战

本文涵盖前端面试核心知识点,深入解析 JavaScript 闭包、事件循环、内存管理及原型链机制。重点阐述 Vue 框架的响应式原理、Diff 算法及组件通信方案。同时梳理 CSS 布局技巧、盒模型差异及性能优化策略。内容涉及网络协议 HTTP 缓存、跨域解决方案及安全防御措施。结合实际代码示例,提供 npm 依赖管理、ES6 模块化及打包配置的最佳实践指南,旨在帮助开发者系统性掌握前端核心技术栈与工程化能力。

灵魂伴侣发布于 2026/3/27更新于 2026/10/370 浏览
前端核心面试题详解:从闭包原理到性能优化实战

前端核心面试题详解

闭包

定义与原理

闭包(Closure)是指函数能够访问并记住其外部作用域中的变量,即使外部函数已经执行完毕。它由两部分组成:一个内部函数和该函数被创建时的词法环境。

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

核心机制:

  • 作用域链:函数定义时记录词法环境,访问变量时沿链向上查找。
  • 变量持久化:内部函数持有外部变量引用,阻止垃圾回收。
常见用途

1. 私有变量封装 通过闭包隐藏内部状态,仅暴露操作接口:

function createCounter() {
  let count = 0;
  return {
    increment: () => count++,
    getValue: () => count
  };
}

2. 函数柯里化 将多参数函数转换为单参数链式调用:

function add(a) {
  return function(b) {
    return a + b;
  };
}
const add5 = add(5);
console.log(add5(3)); // 8

3. 事件处理 在监听器中保留上下文变量:

function setupButton() {
  const button = document.getElementById('myButton');
  let clicks = 0;
  button.addEventListener('click', function() {
    clicks++;
    console.log(`按钮被点击了 ${clicks} 次`);
  });
}
陷阱与解决方案

循环中的闭包问题 使用 var 声明的变量在循环中共享同一个引用,导致结果异常:

for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i); // 输出 3, 3, 3
  }, 100);
}

解决:使用 let 或 IIFE 创建块级作用域隔离变量。

内存泄漏 闭包长期持有大对象引用会导致内存无法释放。需在不使用时解除引用:

leak = null; // 手动解除引用

事件循环(Event Loop)

JavaScript 是单线程语言,事件循环通过任务队列协作实现异步执行。

核心概念

  • 调用栈:存储函数调用,后进先出。
  • 任务队列:分为宏任务(Macro Task)和微任务(Micro Task)。
    • 宏任务:setTimeout, setInterval, I/O, UI 渲染。
    • 微任务:Promise.then, MutationObserver, process.nextTick。

执行流程

  1. 执行同步代码直到调用栈为空。
  2. 执行所有微任务。
  3. 执行一个宏任务。
  4. 重复上述步骤。

示例解析

console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
// 输出顺序:1 → 4 → 3 → 2

应用场景

  • 异步编程避免回调地狱。
  • 性能优化拆分耗时任务。
  • 动画渲染配合 requestAnimationFrame。

BFC(块级格式化上下文)

BFC 是独立的渲染区域,内部布局不影响外部元素。

触发条件

  • 根元素、float 不为 none、position 为 absolute/fixed、display 为 inline-block/table-cell/flex/grid、overflow 不为 visible。

特性与应用

  • 包含浮动:防止父元素高度塌陷。
  • 避免外边距重叠:相邻元素 margin 不合并。
  • 隔离布局:适合独立 UI 组件。

清除浮动示例

.parent { overflow: hidden; /* 触发 BFC */ }

内存泄漏

内存泄漏指已不再使用的内存未被释放,通常由不当引用管理引起。

常见场景

  • 未释放缓存:Map/Cache 未及时清理。
  • DOM 引用:移除 DOM 后仍持有引用。
  • 闭包引用:闭包保留不必要的外部变量。
  • 定时器/监听器:未清除 setInterval 或 addEventListener。
  • 意外全局变量:未声明变量挂载到 window。

排查与预防

  • 使用 Chrome DevTools Memory 面板分析 Heap Snapshot。
  • 优先使用 WeakMap/WeakSet。
  • 及时清除定时器和事件监听。

Vue 虚拟 DOM 与 MVVM

虚拟 DOM 用 JS 对象描述真实 DOM,通过 Diff 算法最小化更新开销。

  • 优点:减少直接 DOM 操作,跨平台能力强。
  • 局限:首次渲染有开销,不适合简单静态页。

MVVM 模式 Model-View-ViewModel 分离 UI 与业务逻辑。

  • 双向绑定:数据变化自动更新视图。
  • 命令绑定:用户操作触发 ViewModel 方法。

Vue2 与 Vue3 响应式原理

Vue2 使用 Object.defineProperty 劫持属性。

  • 局限:无法检测新增/删除属性,数组索引修改需特殊处理。

Vue3 使用 Proxy 代理整个对象。

  • 优势:全面拦截,支持新增/删除,性能更优。

对比

特性Vue2Vue3
劫持方式属性劫持对象代理
新增属性不支持支持
数组响应重写方法直接拦截

深拷贝与浅拷贝

  • 浅拷贝:只复制第一层,引用类型共享地址(如 ...obj, Object.assign)。
  • 深拷贝:递归复制所有层级,完全独立(如 JSON.parse(JSON.stringify()), lodash.cloneDeep)。

注意:JSON 序列化无法处理函数、undefined、循环引用;手动递归需处理循环引用逻辑。


npm 依赖管理

开发依赖 (devDependencies) 仅用于开发环境(构建、测试),不发布到生产。

npm install eslint --save-dev

生产依赖 (dependencies) 项目运行必需,随项目发布。

npm install vue

版本符号

  • ^:允许次版本更新(兼容变更)。
  • ~:仅允许修订版本更新(修复 bug)。

ES6 模块化

ES6 引入 import/export 静态模块系统。

  • 特点:编译时加载,支持 Tree-shaking,严格模式。
  • 导出:命名导出 export const 或默认导出 export default。
  • 导入:import { name } from 'module' 或 import mod from 'module'。

Vue key 的作用

key 用于唯一标识虚拟 DOM 节点,帮助 Diff 算法高效复用。

  • 为什么不用 index:列表顺序变化时,index 会重新分配,导致节点错误复用或状态混乱。
  • 最佳实践:使用唯一 ID 作为 key,避免动态生成随机值。

CSS 选择器优先级

权重从高到低:内联样式 > ID > 类/伪类 > 元素/伪元素。

  • 计算:按位权相加,同权重后定义的覆盖前者。
  • 建议:避免滥用 !important 和 ID 选择器,多用类选择器。

JavaScript 阻塞与优化

JS 单线程,同步长任务会阻塞主线程。

  • 表现:页面卡顿,交互无响应。
  • 解决:
    • 异步 API (setTimeout, Promise)。
    • Web Workers 后台处理。
    • 任务分片执行。
    • requestAnimationFrame 优化动画。

Promise 用法

Promise 解决回调地狱,提供链式调用。

  • 状态:Pending -> Fulfilled/Rejected(不可逆)。
  • 方法:.then(), .catch(), .finally()。
  • 静态方法:all, race, allSettled。

大量数据处理策略

  • 加载:分页、懒加载。
  • 处理:Web Workers 分片处理,哈希表替代数组查找。
  • 存储:IndexedDB 存大量数据,TypedArray 存数值。
  • 渲染:虚拟列表,减少 DOM 操作。

兼容性处理

  • 浏览器:Polyfill 新特性,Autoprefixer 加前缀,Babel 转译语法。
  • 设备:媒体查询适配屏幕,Flex/Grid 布局。
  • 操作系统:安全字体,正斜杠路径。

CSS 绘制椭圆

  • border-radius:宽高不等且 border-radius: 50%。
  • clip-path:ellipse(50% 50% at 50% 50%)。
  • SVG:<ellipse> 标签精确控制。

setTimeout vs setInterval

  • setTimeout:延迟一次执行,设为 0 进入下一轮事件循环。
  • setInterval:周期性执行,需注意回调堆积问题。
  • 建议:递归使用 setTimeout 替代 setInterval 保证间隔准确。

性能指标与检测

核心指标

  • LCP, FID, CLS, TBT。

工具

  • Lighthouse, WebPageTest, Chrome DevTools Performance 面板。
  • performance.now(), console.time。

HTTP 状态码

  • 2xx:成功(200 OK, 201 Created)。
  • 3xx:重定向(301, 302)。
  • 4xx:客户端错误(400, 404)。
  • 5xx:服务器错误(500, 502, 503)。

箭头函数 vs 普通函数

  • this:箭头函数继承外层,普通函数指向调用者。
  • arguments:箭头函数无,需用剩余参数。
  • 构造:箭头函数不能作为构造函数。

防抖与节流

  • 防抖 (Debounce):停止触发后执行,适用于搜索框输入。
  • 节流 (Throttle):固定频率执行,适用于滚动事件。

宏任务与微任务

  • 微任务:优先级高,当前宏任务后立即执行(Promise)。
  • 宏任务:下一轮执行(setTimeout)。
  • 目的:区分任务粒度,优化调度与用户体验。

跨域解决方案

  • CORS:服务端设置响应头。
  • JSONP:利用 script 标签(仅 GET)。
  • 代理:后端转发请求。
  • PostMessage:跨窗口通信。

加载速度优化

  • 资源:压缩,CDN,图片格式优化(WebP)。
  • 请求:合并文件,HTTP/2,雪碧图。
  • 代码:Code Splitting, Tree Shaking, 懒加载。
  • 缓存:Service Worker, Cache-Control。

页签消息传递

  • localStorage:监听 storage 事件。
  • BroadcastChannel:专用通道通信。
  • SharedWorker:共享后台线程。
  • postMessage:跨窗口通信。

元素水平居中

  • Flexbox:justify-content: center。
  • Grid:place-items: center。
  • 绝对定位:left: 50%; transform: translateX(-50%)。
  • 行内元素:text-align: center。

let, const, var

  • 作用域:var 函数作用域,let/const 块级作用域。
  • 提升:var 可访问 undefined,let/const 存在 TDZ。
  • 声明:var 可重复,let/const 不可。

作用域与作用域链

  • 作用域:变量可访问范围(全局/函数/块级)。
  • 作用域链:变量查找机制,从当前作用域向上传递至全局。

继承方式

  • 原型链:子类原型指向父类实例。
  • 构造函数:call 父类构造函数。
  • 组合继承:结合两者。
  • 寄生组合:最优解,避免重复调用构造函数。
  • ES6 Class:语法糖,底层仍是原型。

缓存与持久化

  • HTTP 缓存:强缓存 (Cache-Control), 协商缓存 (ETag)。
  • 本地存储:LocalStorage (持久), SessionStorage (会话), IndexedDB (结构化)。

require vs import

  • require:CommonJS,动态加载,Node.js 原生。
  • import:ES Modules,静态加载,编译时确定,支持 Tree-shaking。

px, em, rem

  • px:绝对单位,固定大小。
  • em:相对当前元素字体大小。
  • rem:相对根元素字体大小,适合全局布局。

盒模型

  • 标准:width 仅内容区。
  • IE:width 包含 padding/border。
  • 统一:box-sizing: border-box。

ES6 新特性

变量声明、箭头函数、模板字符串、解构赋值、默认参数、扩展运算符、Class、Module、Promise、Symbol、迭代器等。


HTTP 缓存策略

  • 强缓存:不发送请求,直接读取本地。
  • 协商缓存:发送请求,服务器判断是否更新。

Vue Router 模式

  • Hash:URL 含 #,无需服务器配置,兼容性好。
  • History:URL 美观,需服务器配置支持 fallback。

JavaScript 缺点

单线程阻塞、弱类型风险、兼容性差异、安全性挑战、调试难度等。


原型与原型链

每个对象都有原型,属性查找沿原型链向上直至 null。


XSS 与 CSRF

  • XSS:注入脚本,防御靠编码过滤、CSP、HttpOnly Cookie。
  • CSRF:伪造请求,防御靠 Token、Referer 检查、SameSite。

HTTP 详解

请求/响应结构、方法 (GET/POST)、状态码、版本演进 (1.0/1.1/2/3)。


分片技术

大数据集分割处理,如数组分片、文件分片、任务分片,避免内存溢出或阻塞。


懒加载原理

延迟加载非关键资源,进入可视区再加载。可用 Intersection Observer 优化 scroll 监听。


脱离文档流

position: absolute/fixed, float, display: none 使元素脱离正常流。


堆与栈

  • 栈:基本类型,函数调用栈,LIFO。
  • 堆:引用类型,动态分配,GC 管理。

v-model 原理

语法糖,等价于 v-bind:value + @input 事件监听。


组件通信

Props/$emit, Event Bus, Provide/Inject, Vuex, $refs。


Diff 算法

同层比较,Key 优化列表更新,批量应用差异。


Webpack 配置

Entry, Output, Loader, Plugin, Mode。常用插件包括 Babel, HTMLWebpackPlugin, Terser。


URL 到页面呈现

DNS 解析 -> TCP 握手 -> HTTP 请求 -> 服务器响应 -> 渲染树构建 -> 执行 JS。


前端优化总结

减少请求、利用缓存、代码压缩、图片优化、渲染性能调优、SEO 增强。

目录

  1. 前端核心面试题详解
  2. 闭包
  3. 定义与原理
  4. 常见用途
  5. 陷阱与解决方案
  6. 事件循环(Event Loop)
  7. BFC(块级格式化上下文)
  8. 内存泄漏
  9. Vue 虚拟 DOM 与 MVVM
  10. Vue2 与 Vue3 响应式原理
  11. 深拷贝与浅拷贝
  12. npm 依赖管理
  13. ES6 模块化
  14. Vue key 的作用
  15. CSS 选择器优先级
  16. JavaScript 阻塞与优化
  17. Promise 用法
  18. 大量数据处理策略
  19. 兼容性处理
  20. CSS 绘制椭圆
  21. setTimeout vs setInterval
  22. 性能指标与检测
  23. HTTP 状态码
  24. 箭头函数 vs 普通函数
  25. 防抖与节流
  26. 宏任务与微任务
  27. 跨域解决方案
  28. 加载速度优化
  29. 页签消息传递
  30. 元素水平居中
  31. let, const, var
  32. 作用域与作用域链
  33. 继承方式
  34. 缓存与持久化
  35. require vs import
  36. px, em, rem
  37. 盒模型
  38. ES6 新特性
  39. HTTP 缓存策略
  40. Vue Router 模式
  41. JavaScript 缺点
  42. 原型与原型链
  43. XSS 与 CSRF
  44. HTTP 详解
  45. 分片技术
  46. 懒加载原理
  47. 脱离文档流
  48. 堆与栈
  49. v-model 原理
  50. 组件通信
  51. Diff 算法
  52. Webpack 配置
  53. URL 到页面呈现
  54. 前端优化总结

更多推荐文章

查看全部
  • Docker 部署 AI 量化分析平台及波浪理论实战
  • Java 算法:模拟类题目实战
  • HarmonyOS NEXT 静默登录与多维数据同步体系构建
  • 大厂 HR 揭秘:为什么年底才是找工作的黄金期
  • Llama 3 大模型技术报告详解:架构、训练与评估
  • Java IO 流:核心原理与实战应用指南
  • 项目部署实战:Linux、Docker 与 Jenkins 流程
  • Stable Diffusion 3.5-FP8 模型是否支持 WebGPU 加速
  • 从 MVP 到千万级并发:AI 在前后端开发中的差异化落地指南
  • 实时口罩检测:修改 webui.py 适配自定义输入尺寸
  • 前端技术趋势:React 18、Server Components 与 AI 辅助
  • 文件上传同名冲突检测的前后端协同方案
  • MCP 插件实战:browser-tools-mcp 接入与配置指南
  • 基于 VSCODE、MarscodeAI 与 Embedded IDE 的嵌入式开发实践
  • 悬架系统与天棚控制算法详解
  • Python 基于 Transformer 的时序数据建模与实现详解
  • Python 协程的两种核心实现:生成器与原生协程对比
  • Python 数据统计指南:从基础配置到高级分析
  • Lostlife2.0 整合 LLama-Factory 引擎重塑 NPC 对话逻辑
  • AI 辅助游戏开发:使用 DeepSeek 构建贪吃蛇游戏

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online