2026年9月前端面试题整理:200道前端高频面试题复习清单
这份清单整理了 200道前端面试题,覆盖HTML、CSS、JavaScript、浏览器与网络、Vue、React、TypeScript、工程化、性能和算法,适合面试前查漏补缺。也包含项目表达、可访问性和安全等实践问题。
自测时,试着回答三个问题:结论是什么?为什么?能举个例子吗? 把每题标成“能讲清楚 / 讲不完整 / 还不会”,优先复习后两类。
题目选自我们维护的免费「面试题」。本篇按21个知识领域精选,包含基础与进阶题,不按面试频次排名。
复习目录
- 项目表达与业务场景:第1—8题。
- HTML、语义化与可访问性:第9—16题。
- CSS、布局与视觉系统:第17—26题。
- JavaScript 类型与语言语义:第27—36题。
- 函数、作用域与 this:第37—46题。
- 对象、原型与元编程:第47—54题。
- 集合、字符串与迭代协议:第55—62题。
- 异步编程与事件循环:第63—72题。
- DOM、事件与交互实现:第73—80题。
- 浏览器运行时与 Web API:第81—89题。
- 网络、缓存与 Web 安全:第90—101题。
- 模块化、构建与编译工具:第102—111题。
- 性能、内存与可观测性:第112—121题。
- Vue 基础与应用模型:第122—131题。
- Vue 组件与复用设计:第132—139题。
- Vue 响应式原理:第140—147题。
- Vue 渲染器与编译原理:第148—155题。
- Vue Router 与状态管理:第156—163题。
- React 与跨框架理解:第164—179题。
- TypeScript 与工程质量:第180—188题。
- 数据结构、算法与手写题:第189—200题。
项目表达与业务场景
-
请用 3 分钟完成一段面向前端岗位的自我介绍。
-
选择一个最能代表你的项目,说明业务目标、用户和最终结果。
-
画出项目的前端架构,并说明一次用户操作如何流经页面、状态和接口。
-
你在项目中具体负责什么?如何证明这是你的个人贡献?
-
项目中最难的前端问题是什么?你如何定位并解决?
-
为什么选择当前框架和状态方案?当时比较过哪些替代方案?
-
你做过哪项性能优化?优化前后的指标分别是什么?
-
线上出现 Bug 但本地正常时,你会如何止损、取证、还原差异并安全发布修复?
HTML、语义化与可访问性
-
HTML 语义化解决什么问题?你会如何选择 section、article、nav 和 div?
-
块级元素、行内元素和行内块元素的布局行为有什么区别?
-
script 的 defer、async 和 type=module 分别如何影响加载与执行?
-
如何让表单的标签、错误提示和键盘操作对辅助技术可用?
-
图片的 alt、srcset、sizes 和 loading 属性应如何使用?
-
ARIA 应在什么情况下使用?为什么不能用 ARIA 代替原生语义?
-
如何设计一个可用键盘完整操作的弹窗,并正确管理焦点?
-
SSR 页面如何兼顾首屏、SEO、交互和 hydration 一致性?
CSS、布局与视觉系统
-
标准盒模型和替代盒模型有什么区别?box-sizing 如何影响尺寸计算?
-
什么是 BFC?它会在什么场景中创建并解决哪些布局问题?
-
Flex 布局的主轴、交叉轴、伸缩和收缩是如何计算的?
-
Grid 与 Flex 各适合什么布局?如何实现稳定的两栏工作台?
-
定位、包含块和 z-index 如何共同决定元素的位置与层级?
-
如何用移动优先策略和媒体查询实现响应式布局?
-
层叠上下文是如何形成的?为什么很大的 z-index 仍可能被遮挡?
-
CSS 动画和 JavaScript 动画如何选择?transform 为什么通常更流畅?
-
如何用 CSS 变量和设计令牌实现明暗主题与多品牌皮肤?
-
contain、content-visibility 和容器查询分别适合解决什么性能或布局问题?
JavaScript 类型与语言语义
-
JavaScript 有哪些原始类型?原始值和对象在赋值与传参时有何不同?
-
隐式类型转换在加法、比较和布尔判断中分别如何发生?
-
== 和 === 有什么区别?哪些场景下宽松相等容易出错?
-
NaN 有哪些特殊行为?Object.is 与 === 的差异是什么?
-
var、let 和 const 在作用域、提升与重复声明上有什么区别?
-
什么是暂时性死区?为什么声明提升不等于可以提前访问?
-
浅拷贝和深拷贝有什么区别?展开语法能复制到什么程度?
-
可选链和空值合并与传统 &&、|| 写法有什么语义差异?
-
为什么 0.1 + 0.2 不等于 0.3?金额计算应如何设计?
-
structuredClone、JSON 序列化和自定义深拷贝各有哪些能力边界?
函数、作用域与 this
-
词法作用域和作用域链是什么?变量查找按什么顺序发生?
-
什么是闭包?它解决什么问题,又可能造成什么内存风险?
-
不同调用方式下 this 如何确定?
-
call、apply 和 bind 有什么区别?分别适合什么场景?
-
箭头函数与普通函数在 this、arguments 和构造能力上有何不同?
-
函数声明和函数表达式的提升行为有什么区别?
-
请实现防抖和节流,并说明立即执行、取消和尾调用如何处理。
-
请手写 new,并解释构造函数显式返回对象时的结果。
-
执行上下文、词法环境和调用栈在函数执行中如何协作?
-
如何定位由闭包、监听器或定时器导致的页面内存泄漏?
对象、原型与元编程
-
对象属性访问时,原型链是如何参与查找的?
-
prototype、proto 和 constructor 分别表示什么?
-
ES Class 与构造函数加原型的关系是什么?
-
Object.create、Object.assign 和对象展开分别做了什么?
-
如何判断属性属于对象自身还是来自原型,并判断它是否可枚举?
-
Proxy 和 Object.defineProperty 的能力边界有什么不同?
-
Reflect 为什么常与 Proxy 配合使用?
-
如何设计不可变更新,避免深层对象修改造成状态污染?
集合、字符串与迭代协议
-
map、filter、reduce、some、every 和 forEach 应如何选择?
-
for...in、for...of 和传统 for 循环分别遍历什么?
-
Array.prototype.sort 的比较函数如何工作?默认排序有什么陷阱?
-
JavaScript 字符串长度为什么不总等于用户看到的字符数?
-
Map 与普通对象如何选择?WeakMap 为什么不会阻止键被回收?
-
Set 适合解决哪些去重和集合运算问题?
-
迭代器协议和可迭代协议是什么?如何让自定义对象支持 for...of?
-
请基于 Map 实现一个有容量限制的 LRU 缓存。
异步编程与事件循环
-
JavaScript 为什么采用单线程执行模型?浏览器如何完成异步任务?
-
宏任务、微任务和渲染时机在一次事件循环中如何排序?
-
Promise 有哪些状态?状态为什么不可逆?
-
.then 返回普通值、抛出异常和返回 Promise 时,后续链分别如何变化?
-
Promise.all、race、allSettled 和 any 分别适合什么场景?
-
async/await 如何建立在 Promise 之上?异常应如何捕获?
-
如何使用 AbortController 取消请求,并避免取消后继续更新页面?
-
请实现一个限制并发数的异步任务池。
-
接口重试应如何设计退避、抖动、超时和幂等边界?
-
如何避免串行 await 造成不必要的等待,同时控制服务端压力?
DOM、事件与交互实现
-
DOM 查询、创建、插入和删除节点时,如何减少不必要的布局计算?
-
事件捕获、目标和冒泡阶段分别如何执行?
-
事件委托为什么有效?哪些事件或场景不适合委托?
-
mouseenter 与 mouseover、mouseleave 与 mouseout 有什么区别?
-
input、change、compositionstart 和 compositionend 应如何配合处理中文输入?
-
preventDefault 和 stopPropagation 分别阻止什么?
-
MutationObserver、ResizeObserver 和 IntersectionObserver 如何选择?
-
如何实现一个高性能的长列表或虚拟列表?
浏览器运行时与 Web API
-
从输入 URL 到页面可交互,浏览器经历了哪些关键步骤?
-
浏览器的进程和线程如何分工?页面崩溃和隔离与此有何关系?
-
Cookie、localStorage、sessionStorage 和 IndexedDB 如何选择?
-
同源策略限制了什么?iframe 之间可以如何安全通信?
-
Web Worker 能做什么、不能做什么?数据如何在线程间传递?
-
Blob、File、ArrayBuffer 和 TypedArray 分别适合什么场景?
-
Service Worker 的生命周期和缓存边界是什么?
-
浏览器如何回收页面内存?如何用 DevTools 定位泄漏对象?
-
requestAnimationFrame、requestIdleCallback 和普通定时器如何选择?
网络、缓存与 Web 安全
-
HTTP 请求和响应由哪些部分组成?常见方法的语义与幂等性如何判断?
-
常见 HTTP 状态码分别表达什么?前端应如何处理可恢复与不可恢复错误?
-
HTTPS 的证书校验和 TLS 握手解决了什么问题?
-
强缓存和协商缓存如何配合?no-cache 与 no-store 有什么区别?
-
什么是 CORS?简单请求和预检请求分别何时出现?
-
Cookie 的 Secure、HttpOnly、SameSite、Domain 和 Path 分别控制什么?
-
HTTP/2 和 HTTP/3 相比 HTTP/1.1 改善了哪些问题?
-
XSS 的主要类型是什么?输出编码、CSP 和可信模板如何协同防护?
-
CSRF 为什么能发生?SameSite、Token 和来源校验如何防护?
-
轮询、长轮询、SSE 和 WebSocket 应如何选择?
-
如何为带 CDN 的静态资源和动态接口设计完整缓存策略与更新方案?
-
AI Agent 的模型文本、工具结果和高风险操作在前端应如何区分、审计与人工确认?
模块化、构建与编译工具
-
ES Module 和 CommonJS 在加载时机、导出语义和循环依赖上有何不同?
-
ES Module 的 live binding 是什么?为什么导入值不是普通拷贝?
-
dependencies、devDependencies 和 peerDependencies 应如何使用?
-
Vite 的开发模式为什么快?它与传统 bundle-first 开发服务有何差异?
-
Source Map 如何把产物错误映射回源代码?生产环境如何安全使用?
-
代码分割、动态 import 和预加载应如何设计?
-
Tree Shaking 生效需要哪些条件?哪些写法会让它失效?
-
Webpack loader 与 plugin 的职责有什么区别?
-
微前端在隔离、通信、路由、依赖和发布上要解决哪些问题?
-
前端如何通过 BFF 接入 Dify、Coze 或自研 Agent,并避免 UI 绑定某一家平台协议?
性能、内存与可观测性
-
LCP、INP、CLS 分别反映什么用户体验问题?
-
如何使用 Network、Performance 和 Lighthouse 定位首屏慢的原因?
-
CSS、JavaScript 和字体为什么可能阻塞渲染?
-
如何识别并拆分长任务,降低主线程阻塞?
-
图片应如何选择格式、尺寸、响应式加载和懒加载策略?
-
大列表、大表格和高频更新页面分别有哪些性能瓶颈?
-
如何分析 bundle 体积并决定拆包、替换依赖或延迟加载?
-
前端错误、性能和用户行为监控应采集哪些上下文并如何保护隐私?
-
流式 AI 对话应如何选择 SSE、Fetch Stream 或 WebSocket,并避免每个 token 都触发整棵消息列表渲染?
-
面对一个“页面很慢”的问题,你会如何建立性能基线、分层定位、实施优化并防止回退?
Vue 基础与应用模型
-
Vue 的声明式渲染和传统 DOM 操作相比改变了什么?
-
setup 的执行时机是什么?ref 和 reactive 应如何选择?
-
模板最终如何变成可执行的渲染逻辑?
-
v-if 和 v-show 有什么区别?应如何根据切换频率选择?
-
computed 与 watch 分别适合派生值和副作用中的哪些场景?
-
Vue 组件的创建、挂载、更新和卸载阶段有哪些关键生命周期?
-
nextTick 为什么存在?状态修改后什么时候可以读取更新后的 DOM?
-
v-for 为什么需要稳定 key?使用索引作为 key 会带来什么问题?
-
Vue 插件、组件、指令和 composable 的职责边界是什么?
-
如何组织一个中大型 Vue 应用的目录、领域模块和共享能力?
Vue 组件与复用设计
-
props 和 emits 如何共同定义组件的公开协议?
-
默认插槽、具名插槽和作用域插槽分别适合什么场景?
-
provide/inject 适合解决什么问题?为什么不应滥用为全局状态?
-
组件 v-model 在 Vue 3 中如何工作?如何支持多个绑定?
-
动态组件、异步组件和 KeepAlive 分别解决什么问题?
-
如何从重复组件逻辑中提取一个可测试的 composable?
-
父子通信、事件总线、provide/inject 和全局状态应如何选择?
-
如何设计一个支持校验、联动和异步选项的复杂表单组件?
Vue 响应式原理
-
Vue 2 的 Object.defineProperty 与 Vue 3 的 Proxy 方案有何差异?
-
依赖收集和触发更新的基本流程是什么?
-
ref 为什么需要 value?模板中为什么可以自动解包?
-
computed 如何实现惰性求值和缓存失效?
-
watch、watchEffect 的依赖来源和执行时机有何不同?
-
为什么解构 reactive 对象可能丢失响应性?如何避免?
-
shallowRef、shallowReactive、readonly 和 markRaw 分别适合什么场景?
-
如何清理 watch 中的异步副作用,避免旧请求覆盖新状态?
Vue 渲染器与编译原理
-
Vue 模板编译通常经历解析、转换和代码生成哪些阶段?
-
VNode 解决了什么问题?它与真实 DOM 是什么关系?
-
组件首次挂载和后续更新分别发生了什么?
-
同层 Diff 为什么依赖 key?最长递增子序列用于优化什么?
-
patch 如何处理元素、文本、Fragment 和组件?
-
Vue 的异步更新队列如何合并多次状态变化?
-
静态提升、PatchFlag 和 Block Tree 如何减少更新比较?
-
SSR hydration 如何复用服务端 DOM?不一致时会发生什么?
Vue Router 与状态管理
-
history、hash 和 memory 路由模式有什么区别?
-
全局、路由独享和组件内导航守卫的执行顺序是什么?
-
params、query 和路由 meta 分别适合承载什么信息?
-
动态路由和基于角色的权限路由应如何生成与撤销?
-
Vuex/Pinia 解决了什么问题?什么状态不应该放进全局 store?
-
Pinia 的 state、getter 和 action 应如何划分职责?
-
全局状态持久化如何处理版本、过期、敏感数据和多标签同步?
-
如何为复杂实时业务设计服务端状态、客户端状态和派生状态的边界?
React 与跨框架理解
-
JSX 如何转换为元素描述?React 元素与组件实例有什么区别?
-
函数组件在每次渲染时如何重新执行?
-
useState 的更新为什么可能被批处理?函数式更新解决什么问题?
-
useEffect 的依赖数组如何决定执行与清理?
-
受控组件和非受控组件分别适合什么表单场景?
-
列表 key 为什么必须稳定?它如何影响组件状态复用?
-
useMemo 和 useCallback 何时有价值?为什么不应默认到处使用?
-
Context、Redux 和局部状态应如何选择?
-
Hooks 中的闭包为什么可能读取旧状态?如何修复?
-
React 并发渲染改变了哪些关于副作用和外部状态的假设?
-
useState 与 useReducer 应如何选择?复杂工作流为什么更适合用事件和状态转移建模?
-
useEffect 什么时候该用?哪些派生数据和用户操作不应该放进 Effect?
-
useRef 适合保存哪些数据?为什么修改 ref 不会触发重新渲染?
-
useEffect 与 useLayoutEffect 的执行时机有何差异?Strict Mode 为什么会额外执行一次 setup 和 cleanup?
-
React.lazy、Suspense 与 Error Boundary 如何配合处理代码加载、等待状态和渲染错误?
-
React 19 的 Actions、useActionState、useOptimistic 和 useFormStatus 分别解决什么问题?它们不能替代哪些状态管理职责?
TypeScript 与工程质量
-
type 和 interface 有哪些差异?应如何选择?
-
泛型如何表达输入与输出之间的类型关系?
-
any、unknown、never 和 void 分别表达什么?
-
如何让前后端接口类型与运行时校验保持一致?
-
单元测试、组件测试和端到端测试分别覆盖什么风险?
-
如何测试异步组件、路由跳转和请求失败状态?
-
Monorepo 适合什么团队?包边界、依赖和发布如何治理?
-
CI/CD 中应如何安排类型检查、测试、构建、预览和回滚?
-
如何分层设计基础组件、无样式交互组件和领域组件,避免组件库与业务耦合?
数据结构、算法与手写题
-
如何分析一段代码的时间复杂度和空间复杂度?
-
数组、链表、栈、队列和哈希表分别适合什么访问模式?
-
二叉树的前序、中序、后序和层序遍历如何实现?
-
二分查找的循环不变量是什么?边界为什么容易写错?
-
常见排序算法的时间复杂度、稳定性和适用场景有何差异?
-
如何用哈希表解决两数之和、分组和计数类问题?
-
动态规划问题如何定义状态、转移方程和初始化?
-
回溯、贪心和动态规划应如何区分?
-
请手写 call、apply 和 bind,并处理返回值与构造调用。
-
请实现支持循环引用和常见内建类型的深拷贝。
-
如何求最长递增子序列,并把复杂度从 O(n²) 优化到 O(n log n)?
-
设计一个可取消、限并发、保序输出的异步请求调度题并实现核心代码。
讲不清楚的题,对照免费「面试题」。
浙公网安备 33010602011771号