大厂前端实习笔试攻略:JavaScript闭包、事件循环与布局方案全解析

发布时间:2026/10/28 18:59:45

大厂前端实习笔试攻略:JavaScript闭包、事件循环与布局方案全解析 2018年春天投小米前端实习生岗位的时候我还在学校啃JavaScript红宝书。当时做完笔试最大的感受就是题目覆盖面很广但几乎每道题都能在“前端开发skills”的底层能力里找到出处——语言基本功、异步机制、布局方案、工程化意识一个都没落下。这套题放到今天依然有很强的参考价值不是因为它多难而是因为它把“一个合格实习生该有的前端基础”考得很透彻。如果你正在准备前端实习或校招尤其是目标定在大厂的同学这篇内容非常值得看完。我会把当时笔试题背后的考察逻辑、典型题型、完整解题思路和踩坑经验全部拆开讲一遍不讲虚的直接对着题目来。1. 笔试背后的技术栈与考察逻辑1.1 大厂实习笔试到底想筛选什么很多人误以为实习笔试考的是“背得多不多”其实恰恰相反。大厂招实习生看的不是你会多少框架而是你在这个行业里有没有“干活的底子”。前端开发skills这个词听起来虚落到笔试里其实非常具体变量作用域清不清楚、类型转换会不会踩坑、异步回调能不能理顺、布局方案是不是只知道一种。小米这套笔试题以及同时期其他大厂的卷子有个共同特点不追新不炫技。它不会考你某个框架API的冷门参数而是把最基础、最能反映编码习惯的知识点翻来覆去地考。比如typeof的返回值、和的区别、let和var在循环里的表现——这些看起来简单但恰恰是很多简历上写着“精通JavaScript”的同学栽跟头的地方。实话说笔试筛人的核心逻辑就一条基本功决定上限工具决定下限。框架不会可以入职再学但作用域、闭包、事件循环这些如果不过关后续接需求、查bug会非常痛苦。所以笔试题的分布逻辑基本是按“语言基础 - 异步机制 - 布局能力 - 框架理解 - 工程意识”这条线铺开的。1.2 2018年前后的主流技术栈决定了考点范围看笔试题不能脱离时代背景。2018年前端技术栈处在一个比较关键的节点Vue 2.5 和 React 16 是绝对主流ES6 已经普及Webpack 4 刚出来HTTP/2 已经开始落地。这意味着笔试考点的选项池是比较明确的。JavaScript 基础部分ES6 的语法几乎是必考项包括let/const、箭头函数、解构赋值、模板字符串、rest 参数与展开运算符还记得热搜词里的“前端开发 函数 ...arg”吗这个点在笔试里出现的频率极高。异步部分Promise 已经取代回调成为主流问法async/await也已经开始进入题目。CSS 部分flex 布局已经普及grid虽然存在但还不是考试重点经典的盒子模型、BFC、双栏三栏布局仍然是主力题型。框架部分Vue 的生命周期、组件通信、v-if和v-show的区别是高频考点React 则是 state 和 props、生命周期函数。工程化方向Webpack 的核心概念entry、output、loader、plugin会被考到但不会深入细节HTTP 相关的基础状态码、跨域、缓存也在考察范围内因为这直接关系到前后端协作能力。1.3 从相关热词里嗅到的考点线索如果你仔细看当时技术圈的热搜词会发现很多词其实都在疯狂暗示考点。“前端开发规范vue”指向的是编码规范和框架理解“trea 开发 前端后端”和“hzero前端开发”说明笔试已经不只看纯前端前后端协作的基础知识比如跨域、接口联调、HTTP 状态码也会以选择题或简答题的形式出现。“前端开发 函数 ...arg”更直接rest 参数和展开运算符的用法、arguments对象的转换、函数式编程里的参数处理都是实打实的出题点。我当时复习的时候有个习惯把热词当成题目线索顺着关键词去延伸知识树。这个方法在后来的笔试里帮了大忙——很多看起来很偏的题其实都能在热词背后找到对应的知识点。所以下面我会顺着这条线索把核心题型一个一个拆开。2. 笔试题型拆解五个必刷的经典考点2.1 JavaScript 基础类型判断、作用域、闭包、this 指向JavaScript 基础部分是整个笔试的大头占比通常在 40% 左右。出题方式一般是选择题 代码输出题。选择题喜欢考typeof的返回值、instanceof的判断逻辑、null和undefined的区别、隐式类型转换的坑。代码输出题则集中在作用域、闭包和this的绑定规则上。先看类型判断。typeof有一个著名的坑typeof null object这是历史遗留问题。typeof function(){} function则是一个容易忽略的点因为函数也是一个对象。数组的判断推荐用Array.isArray()instanceof在跨 iframe 场景下会失效。这些细节在选择题里出现的概率非常高如果只看书不写代码很容易在这里丢分。作用域和闭包是必考中的必考。经典的for循环 setTimeout输出题几乎所有大厂笔试都出现过。考的不是你会不会写setTimeout而是你知不知道var没有块级作用域、函数作用域和词法作用域到底怎么工作。this的指向问题同样高频——普通函数调用、作为对象方法调用、call/apply/bind修改指向、箭头函数不绑定this这四种情况必须做到一眼能分辨。2.2 ES6 新特性let/const、解构、rest 参数与展开运算符ES6 在 2018 年的笔试里已经不是“新特性”而是“默认语法”了。出题重点集中在几个方向上let/const和var的区别尤其临时性死区、解构赋值的各种写法、rest 参数与展开运算符的使用场景。...arg这个语法糖几乎是笔试常客。rest 参数用于收集剩余参数返回一个真数组展开运算符则用于展开可迭代对象。有个经典陷阱题[...arguments]和Array.prototype.slice.call(arguments)有什么区别答案功能上等价但写法上arguments本身不是数组[...arguments]依赖可迭代协议在旧环境下可能不兼容。这种题考的就是你写代码时是否知道边界。箭头函数也是高频考点。箭头函数没有自己的this、不能用作构造函数、没有arguments对象可以用 rest 参数替代。笔试爱考的组合题是箭头函数里再嵌套箭头函数this指向谁答案是始终指向外层作用域的this不会因为调用方式变化而改变。2.3 异步与事件循环Promise、setTimeout、微任务与宏任务异步这块属于“看着简单一写就错”的重灾区。出题形式基本是给一段代码问输出顺序比如setTimeout和Promise.then混在一起让你猜打印顺序。核心知识点是事件循环Event Loop。JavaScript 是单线程的代码在执行时会先跑完同步代码然后处理微任务队列Promise.then、MutationObserver再取宏任务setTimeout、setInterval、事件回调执行。一个宏任务执行完后会清空微任务队列然后继续取下一个宏任务。如果你不理解这个循环机制基本上只要出现三个以上的异步任务就必错。比较典型的一道题setTimeout回调、Promise.resolve().then回调、普通console.log一起出现输出顺序永远是同步代码 - 微任务 - 宏任务。这个顺序不只笔试考实际开发里写异步逻辑时如果没概念很容易出现 bug 找不到原因。2.4 CSS 布局盒模型、居中方案、双栏三栏布局、flexCSS 部分的考察相对直白不会绕弯子但知识点密度很大。盒模型是必考的标准盒模型content-box和 IE 盒模型border-box的区别、box-sizing的作用这是基础中的基础。居中方案也是高频题。水平居中、垂直居中、水平垂直居中每种至少要知道两三种写法。flex 出现后居中变得非常容易但笔试可能会要求你“不用 flex 实现居中”考察你对 margin、定位、table 布局等老方案的理解。双栏和三栏布局同样如此flex 能轻松实现但 float margin、绝对定位、grid 这些方案也要能写出来。BFC块级格式化上下文也是出题点通常和“清除浮动”“外边距塌陷”绑在一起考。你要知道什么事情会触发 BFCoverflow 非 visible、float、position 为 absolute/fixed、display 为 inline-block/flex/grid以及 BFC 能解决什么问题。2.5 框架与工程化Vue 生命周期、组件通信、Webpack 基础框架部分对实习生的要求不太高主要是基础概念和生命周期理解。Vue 的话8 个生命周期钩子必须背下来created和mounted的区别要能用一句话说清楚一个是数据可用但 DOM 未挂载一个是 DOM 已挂载。v-if和v-show的区别一个操作 DOM 节点一个操作 display 属性也是高频题。组件通信是 Vue 笔试的核心。父传子用 props子传父用$emit兄弟组件通过事件总线或者 Vuex跨层级用 provide/inject。笔试喜欢出一个场景题A 组件嵌套 B 组件嵌套 C 组件C 要通知 A 更新数据问有哪些方案。答题的时候列出事件总线、Vuex 两种方案并说明各自适用场景基本能拿满分。工程化方向Webpack 的四大概念entry、output、loader、plugin是送分题loader 和 plugin 的区别要能说清楚loader 转换文件plugin 做打包之外的扩展。HMR热模块替换、source map 的作用也是常见选择题。3. 典型真题现场解题代码与思路完整记录3.1 作用域与闭包for 循环 setTimeout 输出题题目几乎长这样for (var i 0; i 5; i) { setTimeout(function() { console.log(i); }, 1000); }问输出什么如何修改才能输出 0、1、2、3、4第一问答案输出五次 5。原因在于var声明变量没有块级作用域setTimeout的回调函数在 1 秒后执行时循环早已结束i已经变成 5所有回调共享同一个变量所以打印的都是 5。第二问有至少三种改法。第一种最简单把var换成letfor (let i 0; i 5; i) { setTimeout(function() { console.log(i); }, 1000); }let每次循环都会创建一个新的绑定回调捕获的是每次迭代独立的i输出正确。第二种是用闭包传参for (var i 0; i 5; i) { (function(j) { setTimeout(function() { console.log(j); }, 1000); })(i); }通过立即执行函数把i作为参数传入每次迭代的值被固化到函数作用域里。第三种是利用setTimeout的第三个参数for (var i 0; i 5; i) { setTimeout(function(j) { console.log(j); }, 1000, i); }第三种很多人不知道能写出来会加分。这道题考察的其实是“变量作用域 异步回调 闭包捕获”三个知识点一次考全性价比极高属于“一定要拿分”的题。3.2 手写防抖函数timer 细节与 this 绑定手写题里出现频率最高的就是防抖和节流。题目一般会说实现一个debounce函数要求事件触发后 delay 毫秒执行期间重复触发则重新计时并且保证this指向正确、参数正确传递。一个完整的实现function debounce(fn, delay) { let timer null; return function() { const context this; const args arguments; clearTimeout(timer); timer setTimeout(function() { fn.apply(context, args); }, delay); }; }这里有几个关键点必须注意。第一返回的函数必须是普通函数而不是箭头函数因为需要访问动态的this如果外层用箭头函数this会被绑定到定义时的作用域。第二fn.apply(context, args)里的context和args必须在闭包里保存下来否则执行时this和参数都丢了。第三clearTimeout放在每次触发时确保上次的定时器被清掉这是防抖的核心逻辑。扩展题还会让你写节流throttle区别在于防抖是“最后一次触发有效”节流是“固定时间间隔内只能执行一次”。笔试如果出了防抖十有八九会追问题节流的区别建议两个都提前准备好。3.3 事件循环输出题Promise、setTimeout 与微任务题目一般长这样setTimeout(function() { console.log(a); }, 0); Promise.resolve().then(function() { console.log(b); }); console.log(c);问输出顺序。答案是c-b-a。整个执行流程是这样的同步代码先执行输出csetTimeout的回调进入宏任务队列Promise.then的回调进入微任务队列同步任务执行完毕后事件循环先清空微任务队列输出b然后再取宏任务队列的第一个任务输出a。如果把题目再复杂化加一个async/awaitasync function test() { console.log(1); await Promise.resolve(); console.log(2); } console.log(3); test(); console.log(4);输出顺序是3-1-4-2。await后面的代码相当于.then的逻辑进入微任务队列所以2在4之后打印。这个点很容易错很多人以为await是同步阻塞其实它是“让出线程”的语法糖。3.4 手写深拷贝处理数组、Date、循环引用深拷贝是手写题的常客难点不是写出来而是写得完整。一个初级版本的深拷贝很容易但一个能处理数组、Date、RegExp、Symbol key、循环引用的版本才能真正体现代码功底。我来写一个笔试能用的版本function deepClone(obj, map new WeakMap()) { if (obj null || typeof obj ! object) { return obj; } if (obj instanceof Date) { return new Date(obj); } if (obj instanceof RegExp) { return new RegExp(obj); } if (map.has(obj)) { return map.get(obj); } const clone Array.isArray(obj) ? [] : {}; map.set(obj, clone); Reflect.ownKeys(obj).forEach(key { clone[key] deepClone(obj[key], map); }); return clone; }关键点有三个。第一基本类型直接返回不用递归。第二Date 和 RegExp 要特殊处理用构造函数创建一个新对象不能直接复制引用。第三循环引用问题——用WeakMap保存已克隆的对象如果再次遇到直接返回缓存的结果否则深拷贝会无限递归导致栈溢出。Reflect.ownKeys可以拿到包括 Symbol 在内的所有自有属性比Object.keys更完整。函数一般不需要深拷贝直接引用即可所以typeof obj ! object的判断会把函数直接过滤掉这是合理的。3.5 CSS 双栏布局三种实现方案对比CSS 手写题一般会考双栏或三栏布局要求是“左侧固定宽度右侧自适应”。这种题最简单的答案是用 flex.container { display: flex; } .left { width: 200px; flex-shrink: 0; } .right { flex: 1; }但笔试通常会加一句“不能用 flex”这时候要准备 fallback 方案。经典的 float margin 方案.container { overflow: hidden; } .left { float: left; width: 200px; } .right { margin-left: 200px; }overflow: hidden触发了 BFC能清除浮动带来的高度塌陷问题。还有一种绝对定位方案父容器position: relative左侧position: absolute; left: 0; width: 200px右侧margin-left: 200px。这个方案需要注意父容器要设置padding-left或 overflow 处理否则右侧内容可能会被左侧遮挡。三栏布局中间自适应左右固定最常用的是圣杯布局和双飞翼布局现在用 flex 也可以轻松实现.container { display: flex; } .left { width: 200px; } .center { flex: 1; order: 2; } .right { width: 200px; }能写出一种方案并解释为什么这样能生效基本就能拿分。重点不是背代码而是说清楚“左侧浮动后脱离文档流右侧的 margin-left 把它让开的宽度补回来”这层逻辑。4. 笔试实战中的踩坑与避坑清单4.1 时间分配策略先拿送分题再啃硬骨头小米这套笔试题我记得总时长是一个半小时左右题量不算小。我在实际答题时踩过最大的坑是前面选择题纠结太久导致最后的编程题时间不够。复盘下来时间分配应该遵循“先易后难先拿分再说”的原则。选择题里确实有几道题是有争议的、选项模棱两可的遇到这种题最多停留 3 分钟选一个最合理的答案后立刻跳过不要恋战。编程题反而值得留足时间——因为代码题是按点给分的写出基本思路和关键代码就能拿一半以上的分性价比远高于选择题。我当时大概花了 45 分钟做选择题剩下 45 分钟写编程题实际体验是选择题应该压缩到 30 分钟编程题尽量留到 60 分钟。手写题还有个技巧如果实在写不完整先写函数签名和注释把思路框架搭出来再往里面填实现。阅卷人看的是代码能力和思路空白的卷面是零分写了框架和核心逻辑至少能拿到过程分。4.2 代码书写习惯决定了印象分笔试阅卷很多时候不是机器判卷而是后端或者前端团队的人在看。代码的整洁程度会直接影响印象分。我见过一些同学代码逻辑是对的但命名全是a、b、c缩进乱七八糟函数也没有注释——这种答案即使对了也容易扣分。好的笔试代码应该做到变量命名用语义化的英文比如debounceTimer、resultList、isFirstRender函数名和注释说明函数的作用边界条件写在代码前面关键逻辑加一行注释解释“为什么这么写”。比如深拷贝里的map.has(obj)如果不加注释阅卷人可能会疑惑但如果你写一行“避免循环引用导致栈溢出”印象分会完全不同。还有一个小细节代码缩进统一用两个空格还是四个空格不重要但必须保持一致。千万不要混用 tab 和空格这在显示上会错乱极影响观感。如果你是手写代码现场笔试可能要写在纸上宁可写慢一点也要保证每个字符清晰可辨认。4.3 高频陷阱速查表我把笔试里最容易踩的坑整理成一个速查表考前扫一遍能避开大部分失分点。考点典型陷阱正确思路typeof null返回 object这是 JS 的历史遗留 bug选择题必记 和 0 为 true严格相等不转换类型var 循环闭包输出全是最后一个值let/IIFE/setTimeout 第三参this 指向方法解构后调用 this 丢失箭头函数或 bind 绑定Promise 顺序Promise.then 早于 setTimeout微任务先于宏任务箭头函数没有 arguments、不能 new用 rest 参数替代 argumentsArray.isArrayinstanceof 跨 iframe 失效用 Array.isArray 最稳妥box-sizingpadding 撑大盒子border-box 保布局稳定v-if vs v-show切换频繁用 v-if 卡顿高频切换用 v-show深拷贝循环引用递归栈溢出WeakMap 缓存已克隆对象这十四个坑涵盖了选择题和编程题的大部分失分点。你不需要背下来但做模拟题的时候如果发现自己在这几个点上反复出错就说明基础还需要补。5. 复盘与面试衔接笔试里的每一道题都是面试素材5.1 笔试结束后怎么复盘效率最高很多人笔试结束后就扔了这是最可惜的。笔试是一份非常精准的能力画像哪块薄弱一清二楚。我当时的做法是考完趁记忆还新鲜把每道题按“确定对的”“蒙对的”“完全不会的”三类归档。“蒙对”的题目尤其值得复盘——它意味着你其实不会只是运气好。归档之后针对“完全不会”的部分回到书里和文档里补缺口。比如我当时在事件循环那类题上错得最多所以花了整个周末把所有 Promise、async/await、setTimeout 组合输出题都刷了一遍直到每一种排列组合都能秒答。面试的时候面试官问异步相关的问题我回答得特别轻松因为笔试已经把盲区标出来了。这个复盘习惯还有一个好处它让你知道自己语言描述的表达逻辑在哪里断掉了。很多题你脑子里知道答案但写不出来说明你对知识的掌握还停留在“认识”阶段没有达到“熟练应用”阶段。笔试是检验你“会不会”复盘是帮你搞清楚“为什么不会”。5.2 把笔试题转化为面试表达素材笔试的代码题几乎都是面试时的好素材。比如你笔试里写了防抖函数面试官问你“你在项目里用过防抖吗”你就可以把笔试题里实现拿出来结合项目场景说一遍。这个衔接非常顺畅——因为笔试题本来就是经过筛选的经典场景面试官也熟悉你提到它不会显得突兀。我建议准备一个“笔试错题集”每个错题后面写两行一行是正确答案一行是你当时的错误原因。面试前翻一遍比临时刷题有用得多。我自己在二面的时候被问到“你能讲一下事件循环吗”我直接拿出笔试中做错的那道 Promise 输出题作为引子从错误推导出正确理解面试官印象很深。另外一个很实用的小技巧笔试结束后把每道编程题的代码重新在自己的编辑器里跑一遍确保能正常运行。这个动作的意义不只是验证答案更是让你的手感和思路保持在线。面试写代码的时候很多时候你的肌肉记忆比大脑思考更快平时写得越流畅面试表现越稳定。
延伸阅读

更多相关文章

2026/10/27 9:35:32

Godot 3D 模型材质切换指南:3 步实现完整换装与状态替换

Godot 3D 模型材质切换指南:3 步实现完整换装与状态替换 【免费下载链接】godot Godot Engine – Multi-platform 2D and 3D game engine 项目地址: https://gitcode.com/GitHub_Trending/go/godot 角色一踏进雨里,身上的衣服要立刻变成湿身材质&…

2026/10/24 15:51:19

mermaid 完整解析:一段文本变成 SVG 图的 5 站旅程

mermaid 完整解析:一段文本变成 SVG 图的 5 站旅程 【免费下载链接】mermaid Generation of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid 在一个 …

2026/10/28 18:59:02

大龄前端逆袭指南:收藏这份转行AI大模型应用开发全攻略!

文章为面临失业风险的大龄前端提供了转行AI大模型应用开发的详细步骤,包括基础能力自测、职业诉求确认、行业市场调研、薪资成本测算以及作品集落地要求。作者强调通过系统学习和项目实践,弥补年龄劣势,实现职业转型,并给出了学习…

2026/10/28 18:59:02

跟着一条指令走:启元 Q1 技术架构解读

把 Q1 从折叠收储的状态叫起来,让它走到你面前。 对用户来说,这是一句话。对机器人来说,这句话要穿过五层:技能层决定“做什么”,智能层理解“在哪、是谁”,运动控制层决定“怎么动”,通信层把…

2026/10/28 18:59:02

springboot易购数码商城系统11471-计算机课程设计、毕业设计

前言 ✨ 博主介绍:一线全栈工程师,毕设实战引路人。技术栈覆盖Java、Python、C#、PHP、Node.js及UniApp跨端开发,擅长多语言项目落地与架构设计。持续分享毕设源码、开题报告、技术选型心得与职场踩坑经验。用工程化思维写代码,帮…

2026/10/28 18:59:02

有效进行自动化测试,这几个软件测试工具一定要收藏好!!!

大家普遍都清楚, 在进行软件测试的那些工作里头, 自动化这东西是可以实实在在地把测试工作的效率往上提一提的。可是到了实实在在动手干的时候就老碰到这么个事儿: 许多做测试的人都感觉, 那个自动化, 根本没能把它的最大潜力给完全开发出来, 或者说没把它用到最极致。那为啥会…

2026/10/28 18:54:00

高校教材订购管理系统:毕业设计选题与Spring Boot实现

简介:这份高校教材订购管理系统毕业设计资源包,面向计算机相关专业学生与需要完成课程设计、毕业设计的开发者,围绕教材采购、订单处理、库存监控与报表统计等业务场景,提供一套可运行的B/S架构信息化管理方案。包内共398个文件&a…

2026/10/28 14:42:12

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/28 15:28:56

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/28 0:02:13

Python股票自动交易系统源码解析:从行情获取到风控的完整链路

简介:这份资源是面向高校计算机、金融相关专业毕业设计场景的完整项目源码包,主题为基于Python的股票自动交易系统,适合需要完成毕设选题、课程设计或自学金融量化交易开发的学生与开发者参考。压缩包共收录687个文件,整体约14.93…

2026/10/28 0:02:13

视酷酷信IM源码部署指南:Java 17+MySQL 8.0.33实战配置

简介:这是一套2024年亲测可部署的视酷酷信IM即时通讯系统源码,面向具备Java、OC、C#及Vue开发能力的技术人员,解决私有化即时通讯平台快速搭建与二次定制需求,尤其适用于需集成商城、保障数据主权的中小型企业或独立开发者。资源共…

2026/10/28 0:02:13

Python爬取百度迁徙数据:接口解析、批量采集与避坑指南

简介:这份资源是一个用Python爬取百度迁徙数据的脚本压缩包,面向具备Python基础、希望入门网络爬虫与数据解析的开发者,解决按日期获取全国热门城市人口迁徙数据的问题。包内共1个文件,为单个py脚本,压缩包约1KB&#…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑