
“前端八股文”这个词圈里人听了都会心一笑。说白了就是面试里翻来覆去问的那批固定知识点闭包、原型链、事件循环、this 指向、Vue 响应式原理、浏览器从输入 URL 到页面展示发生了什么。背的人觉得枯燥问的人也觉得套路但现实就是——前端面试绕不开它。这篇文章我就结合自己这几年面试别人和被别人面试的经验聊聊前端八股文到底指什么、为什么它始终存在以及几个高频面试小例子的答法。如果你正在准备前端跳槽或者刚入行想搞明白“该背哪些东西”又或者已经工作几年想回头补补基础这篇文章应该都能给你一些参考。我尽量不讲虚的每个例子都按面试现场的实际答法来拆顺带会说说哪些地方容易翻车。1. 聊聊前端八股文它到底是什么1.1 “八股文”这个名字是怎么来的“八股文”原本是指明清科举考试里一种格式固定的文体考生必须按照破题、承题、起讲、入题、起股、中股、后股、束股这八个部分来写内容不能越界形式不能走样。后来技术圈借用这个词指代面试中那些反复出现、答案高度标准化的问题。前端八股文和科举八股文有一点很像问的人不问为什么非要这样问答的人也不管这个知识在真实项目里到底用不用得上。大家默认这套题是用来筛选人的。你说闭包的实际用途是什么很多人能背出“让函数记住外部变量”但问他在项目里哪个场景用到过就支支吾吾了。这其实暴露了一个真相八股文本身没有错错的是只背不理解。同样是问闭包真正理解的人能答出数据私有、柯里化、防抖节流的实现思路只背答案的人换一个问法就露馅。1.2 为什么前端面试离不开八股文前端的知识体系太杂了。一个项目里有 JavaScript、HTML、CSS、框架、工程化、性能优化、网络、浏览器原理甚至还要懂点 Node 和部署。面试官要在 40 分钟到 1 小时内判断你的水平怎么判断最有效的方式就是用一批标准化的问题去测你的基础深度。问“ let 和 const 的区别”如果你能自然延伸到暂时性死区、块级作用域、变量提升说明你基础是扎实的。如果你只能说“let 可以重新赋值const 不可以”那基本就能判断出你的水平线。从团队招聘的角度看八股题还是有它的客观性和公平性的。候选人背景千差万别有科班出身、有培训转行、有自学成才项目经历也很难横向对比。这种情况下一套统一的基础题反而是最不坏的筛选方式。1.3 哪些问题算前端八股文哪些不算我观察下来前端八股文大致有这几个边界算语言基础变量提升、闭包、原型链、this、异步机制事件循环、Promise、宏任务微任务、浏览器与网络渲染流程、HTTP 缓存、跨域、框架原理响应式、diff、虚拟 DOM 等、CSS 基础BFC、盒模型、Flex、Grid、工程化基础Webpack 构建流程、Vite 原理。不完全算但常被归入手写题防抖节流、深拷贝、Promise.all、安全XSS、CSRF、性能优化。不算算法题、项目深挖、场景设计题、系统设计题。注意这个边界是动态的。前些年 Vue 和 React 的原理还算新鲜题这两年已经成了标准八股。再过两年说不定 Vite 的预构建原理、React Compiler 的自动 memo 也会成为新一代八股。所以别指望背完一劳永逸几个月就得刷新一遍。2. 前端面试八股文的四个高频板块2.1 JavaScript 基础闭包、原型链、thisJS 基础是所有八股文的根。这块答不好后面全白搭。常见题型包括闭包的概念、用途、缺点原型和原型链的查找机制this 的四种绑定规则变量提升、作用域链、暂时性死区深拷贝与浅拷贝问闭包的时候面试官真正想听的是“你是否理解函数和其词法作用域之间的关系”。只背定义很容易被追问到内存泄漏问题上这时候就需要你解释“为什么闭包可能导致内存占用变大”“什么情况下闭包被回收”。问原型链的时候面试官想看你能不能自己画出obj - Object.prototype - null这条链。建议准备一个手写instanceof的代码这在很多手写题环节都会用到。2.2 异步编程事件循环、Promise、async/await异步这块是前端八股的重灾区。一方面是因为它确实重要另一方面是它概念多、容易绕晕。常见的考察点什么是微任务什么是宏任务两者执行顺序setTimeout 的最小延迟时间为什么是 4ms 左右Promise 的三种状态和链式调用async/await 的本质是什么错误怎么捕获经典代码题输出顺序题事件循环这个大题基本能把一个候选人至少三分钟。我之前在面试里经常让候选人写下面这段代码的输出顺序console.log(script start); setTimeout(() { console.log(setTimeout); }, 0); Promise.resolve() .then(() { console.log(promise1); }) .then(() { console.log(promise2); }); console.log(script end);大部分候选人都能答对script start、script end、promise1、promise2、setTimeout。但当我继续追问“为什么不先执行 setTimeout毕竟它写的 0 毫秒”时很多人就开始含糊了。这个问题你可以在文章第 3 部分看到详细拆解。2.3 浏览器与网络渲染原理、缓存、跨域现在的前端面试基本离不开浏览器。常见的八股题有从输入 URL 到页面展示中间发生了什么浏览器渲染流程中有哪些关键步骤回流和重绘的区别Cookie、localStorage、sessionStorage 的区别HTTP 缓存强缓存与协商缓存跨域是什么如何解决这类题的好处是答起来有清晰的层次先说大流程再逐步细化。坏处是如果只会背流程图被追问到“DOMContentLoaded 和 load 有什么区别”“defer 和 async 有什么不同”就很容易卡壳。2.4 框架八股Vue 响应式、diff 算法框架八股近几年占的权重越来越大。Vue 这边常问Vue 2 的响应式原理Vue 3 和 Vue 2 在响应式上的区别虚拟 DOM 是什么diff 算法做了什么为什么 Vue 3 用 Proxy 取代了 Object.definePropertywatch 和 computed 的区别nextTick 的原理React 那边常问fiber 是什么useState 的原理useEffect 的依赖数组到底是干什么的React 为什么需要 key这些题的特点是光靠背答案很容易被追问到底层。比如“Vue 3 用 Proxy 为什么能监听新增的属性”“diff 的复杂度从 O(n³) 降到 O(n) 的原理是什么”。建议对着源码或原理图理解而不是死记结论。2.5 工程化与手写题Webpack 的构建流程、Loader 和 Plugin 的区别、Vite 为什么快已经成了不少公司的必问题。手写题里防抖节流、深拷贝、Promise 系列、数组去重属于最常出现的几个。工程化这块的八股变得越来越像后端知识会问 Babel 编译原理、AST 是什么、Tree Shaking 的原理。偏重中大型公司的面试。如果是中小公司一般问得没那么深但要能说出 Loader 和 Plugin 各自的职责边界。3. 四个高频面试小例子按实战答法拆给你3.1 事件循环为什么 Promise 比 setTimeout 先输出这是一个非常典型的题基本上一场面试问 JS 异步必碰到。完整的答法应该包含三部分同步代码、微任务、宏任务。以刚才那段代码为例执行console.log(script start)输出 script start。遇到setTimeout把它放到宏任务队列继续往下走。遇到Promise.resolve().then(...)注册一个微任务但不立即执行。执行console.log(script end)输出 script end。当前宏任务执行完毕开始清空微任务队列。执行第一次then输出 promise1链式then注册的 promise2 也会被追加到微任务队列继续执行输出 promise2。微任务队列清空后再取出宏任务中的setTimeout回调输出 setTimeout。这里有个关键点事件循环的过程是“每执行完一个宏任务就去清空整个微任务队列”而不是“把所有宏任务执行完再执行微任务”。很多人背结论的时候死记“微任务先于宏任务”但真正的原因是“微任务队列在宏任务执行完后会立即被清空”。我自己在面试中还会追问一句“如果 setTimeout 的延迟改成 100ms输出顺序会变吗”答案是微任务仍然先输出因为 100ms 只是把宏任务的入队时间延后并不会改变“当前宏任务执行完就先清空微任务”的规则。注意Node.js 环境和浏览器环境的事件循环有差异。浏览器是每次取出一个宏任务Node 11 之前是每个阶段整体执行完再切下一个阶段。现在 Node 和浏览器行为基本一致了但如果面试官问老版本 Node 的差异也别慌说清“每个阶段有一个队列”即可。3.2 闭包除了背定义还要能说出实际用途闭包的教科书定义是一个函数引用了其外部作用域的变量那么这个函数就是一个闭包。但面试官听你说完这句话大概率会追问一句“那它有什么实际用途”这时候你不能再背定义要举例子。我来分享一个我常用的答法“常见的用途是数据私有化。比如我写一个计数器不想让别人直接修改 count 变量就用闭包来实现。”function createCounter() { let count 0; return { increment() { count; return count; }, decrement() { count--; return count; }, getCount() { return count; } }; } const counter createCounter(); counter.increment(); counter.increment(); console.log(counter.getCount()); // 2这个例子一眼就能看出闭包的三个价值第一count 对外不可直接访问只有通过接口操作第二每次调用 createCounter 都会创建独立的作用域互不干扰第三即使 createCounter 已经执行完count 依然存活在内存中因为返回的函数还持有对它的引用。但这里也会引来一个经典追问“那闭包会不会造成内存泄漏”答案是如果闭包长期持有大对象并且外部一直保留着对闭包函数的引用那确实会占用内存。但如果是合理使用闭包内部变量在闭包函数失去引用后也会被 GC 回收。Vue 3 的 compose 函数、React Hooks 里的大量实现底层都是闭包。3.3 Vue 响应式从 Object.defineProperty 到 ProxyVue 的响应式原理几乎是 Vue 面试必问的第一题。Vue 2 的实现机制是依赖Object.defineProperty对 data 中的每个属性做 getter/setter 劫持Vue 3 则改用Proxy对整个对象做代理两张方案有本质区别。Vue 2 的局限性要能说出来新增属性不会触发响应式更新因为 setter 是在初始化时定义好的。所以 Vue 2 才提供了Vue.set这个 API。通过下标修改数组元素同样无法触发更新。需要递归遍历对象的所有属性初始化性能开销大。Vue 3 用 Proxy 解决了这些问题const data { name: 张三, info: { age: 18 } }; const proxy new Proxy(data, { get(target, key, receiver) { console.log(读取了 ${String(key)}); return Reflect.get(target, key, receiver); }, set(target, key, value, receiver) { console.log(修改了 ${String(key)}新值为 ${value}); return Reflect.set(target, key, value, receiver); } }); proxy.age 19; // 即使 age 原本不存在也能触发 setProxy 的好处是懒劫持访问到嵌套对象时再去递归代理而不是初始化时就遍历全部属性。但请注意Proxy 只能代理一层对象嵌套对象其实是在 get 触发后对返回值再次reactive处理。我在面试中如果遇到候选人能主动提到“Reflect 的作用是什么”——保持 this 的指向正确这段回答质量就会上一个台阶。因为 Reflect 的 receiver 参数保证了在 getter 里访问 this 的时候不会出错。3.4 从输入 URL 到页面展示答出一个清晰的链路这道题很考验表达的结构化能力。推荐按“网络请求 浏览器渲染”两段式来答每一段都从宏观到微观。第一段网络请求部分浏览器解析输入的 URL判断协议、域名、端口、路径。如果协议或域名不合法浏览器会调用搜索引擎或补全默认配置。DNS 查找过程先查浏览器 DNS 缓存再查操作系统缓存hosts 文件然后查路由器缓存最后才是向 DNS 服务器发起递归查询。拿到服务器 IP 后建立 TCP 连接三次握手。如果是 HTTPS还需要 TLS 握手协商加密套件、交换证书、生成会话密钥。浏览器构造 HTTP 请求把请求行、请求头、请求体发送给服务器。服务器处理请求返回响应报文包括状态码、响应头和响应体。第二段渲染部分浏览器收到 HTML 后开始解析 HTML构建 DOM 树。解析过程中遇到 CSS 会构建 CSSOM 树遇到 JS 会暂停解析执行完再继续没有 defer/async 时。DOM 和 CSSOM 合并成渲染树Render Tree但注意display: none的元素不会出现在渲染树里。进行布局计算Layout确定每个元素的位置和尺寸。进行绘制Paint把元素画在多个图层上。最后执行合成Composite把图层合成为最终的页面。这个答法的好处是给了一个清晰的框架。有经验的候选人会在第二段主动提到“现代浏览器在解析 HTML 时遇到 JS 会阻塞所以会把 script 放在 body 尾部或者加 defer/async”这种补充会让面试官觉得你是真的做过性能优化而不是背来的。4. 如何准备八股文才不算白背4.1 先理解再记忆画一张知识连接图如果你现在刚开始准备前端面试千万别直接去背题。建议你先找一个思维导图工具把上面提到的四个板块列出来然后在每个板块下填子知识点。比如“JS 基础”下填“闭包”“原型链”“作用域”“this”“类型转换”“浏览器”下填“渲染流程”“缓存”“跨域”等。然后试着不看资料把每个知识点讲给自己听。讲不通的地方就是你的盲区。这不是浪费时间而是在做“主动回忆”。被动看 10 遍不如主动讲 1 遍。4.2 把八股文变成简历上的真实项目这一条是我特别想强调的。很多人背了八股但项目里完全没体现面试官一问项目就露馅。更好的做法是做一个小项目把八股文里那些知识点自然地用进去。举几个例子想体现闭包理解可以在项目里写一个自定义 Hook 或者状态管理器内部用闭包保存状态。想体现事件循环理解可以在上传大文件时用异步任务拆分、分片上传、进度回显。想体现渲染原理理解可以做性能优化专项减少回流重绘、懒加载、图片压缩。想体现浏览器缓存理解可以在部署时配置 CDN 和 nginx 的缓存策略。八股文本身不会成为你的竞争力但“会用八股文解决实际问题”会。4.3 面试回答的节奏和深度回答八股文问题时最忌“一锅端”。我建议按“结论先行 适当展开 等追问”的节奏来答。比如面试官问“为什么 Vue 3 用 Proxy 替代 Object.defineProperty”你第一句先说结论“因为 Proxy 能监听对象的新增和删除操作而且初始化时无需递归遍历性能更好。”然后停一下看面试官反应。如果面试官点头示意你继续说再展开聊聊对象遍历、数组监听、懒劫持这些细节。如果面试官只是问了这一句就跳到下一题说明他可能只需要你回答到这个层面你继续说反而显得啰嗦。这就引出了一个判断面试官问八股很多时候是想“分层”。第一层看你知不知道第二层看你理解得深不深。学会判断对方的引导方向比一股脑把你知道的全倒出来更重要。4.4 动手写不要只看前端八股里有很多题看起来会了一动手就废。我见过太多候选人嘴上说“我会深拷贝”“我会防抖”让他在编辑器里写一个写了三分钟写不出来。所以准备过程中至少要把下面这些手写题敲过一遍防抖函数、节流函数深拷贝要考虑循环引用、数组、对象、Date、RegExpPromise.all、Promise.race、Promise 的简易实现手写call、apply、bind简易的 reactive / watch 实现数组扁平化、去重、乱序敲完一遍之后还有一个更高阶的练习把每一段手写代码用嘴讲一遍讲它每一步在做什么、为什么这么做。能讲明白才说明你是真的消化了。5. 常见问题与避坑实录5.1 背得熟但一问“为什么”就卡住这是最常见的问题。很多候选人准备了几十道题的答案每一道都背得滚瓜烂熟但面试官换一个角度提问就答不上来。比如背了“Object.defineProperty 无法监听数组变化”面试官改问“那 Vue 2 是怎么实现对数组的监听的”如果你没有深入研究过 Vue 2 对数组原型方法的改写这里就卡住了。解决方案只有一个不要背答案去理解答案背后的推导过程。每看一个知识点都问自己三遍“为什么”。“为什么 Vue 要重写数组方法”“为什么需要有虚拟 DOM”“为什么需要 key”。把这三个为什么想透了八股文的题怎么变你都不怕。5.2 只会说名词不会用代码表达“我了解 promise”“我了解闭包”“我了解虚拟 DOM”这句话面试官一天能听几十次。上一句说完下一句肯定是“那请你写一下”。写不出来前面的话就等于白说了。而且面试官内心对你的评价可能更差不是能力不行而是不诚实。建议每次背一个概念都搭配一个几十行的小 demo。比如了解 Promise就写一个 Promise 构造函数实现了解虚拟 DOM就写一个简单的 h 函数和 render 函数。不需要追求完整实现但核心逻辑要能跑通。5.3 太早开始投简历准备八股是一个持续两周到一个月的过程。很多人刷了三天题感觉自己“差不多都看过”就急着投简历。结果被一个简单的问题难住心态崩溃。更好的节奏是先花一周时间把基础知识点整理出来再花一周时间做项目结合最后再花一周时间做模拟面试和手写题。别把模拟面试放在最后一步最好在准备中途就做一次找出薄弱点再针对性地补。5.4 忽略“项目深挖”和底层原理八股只是面试的第一关。如果一个候选人在八股环节表现优异面试官会立刻进入“项目深挖”环节通过聊项目来验证八股是不是背的。我自己的经验是面试官盘项目的逻辑一般是这个项目解决了什么问题你在里面扮演什么角色你做的这部分技术难点是什么有没有遇到过特别棘手的问题怎么排查的如果重新做这个项目你会怎么优化这些问题没有一个能从八股文里背出来。建议在准备八股的同时认认真真复盘你简历上的每个项目。能画架构图能说清接口设计能讲出埋点数据和性能指标比多背十道八股题更管用。5.5 关于手写题的一个补充建议手写题不是考核代码风格是考核思路。面试官通常更在意“解题的思考过程”而不是你写出的代码能否一键运行。建议不要闷头写而是先说解题思路、时间复杂度、边界条件再动手。比如深拷贝先说“我会用递归逐层拷贝要处理数组和对象另外要考虑循环引用用一个 WeakMap 记录已访问的对象。”这段话说完面试官心里的预期分数已经提高了。一些个人心得前两年我带过几个实习生每次问他们“准备得怎么样了”他们都说“背了不少题”。但一轮模拟面试下来暴露最多的问题不是知识量不够而是回答没有逻辑想到哪说到哪面试官听得很费劲。后来我带他们换了一种方式先把一个知识点讲给完全不懂前端的人听直到对方能听懂为止。这个练习看起来简单实际做起来非常难。它逼着你把术语翻译成大白话把结论拆成因果链。等到你能把一个知识点用三句话说清楚面试时面试官其实很难问倒你。还有一个小技巧面试前可以拿录屏软件录一个自己回答问题的视频回放看看。很多人事后看自己的视频才发现自己在不停“然后”、眼神漂移、语气词连篇。这些东西在紧张的面试现场自己完全感知不到却是面试官判断你沟通能力的重要指标。前端八股文这个东西它不完美但它确实是一个能逼你系统复习基础知识的框架。我的态度始终是别把它当负担也别把它当捷径。踏踏实实把每个知识点理解透、动手写出来再结合项目反复打磨面试那关反而没那么难。祝你能顺利搞定下一次面试。