🔥 前端面试八股文:高频 100 题一口气吃透,背完就能开大!(附答案 & 解析)
0. 先说两句掏心窝的话 (≖_≖ )✧
兄弟们,姐妹们,现在前端面试,真的不是“会写页面”就能过了。 你简历上写得再漂亮,一上来:
display: none和visibility: hidden区别?Promise.all手写一下?- BFC 是啥,能干啥?
- TCP 三次握手四次挥手画一遍?
要是你答不上来,或者答得吞吞吐吐,面试官心里只会有一句话:
“这哥们儿基础不牢,再看看吧。” 然后你的简历就被压在那一堆“回去等通知”里了。 所以,我花了点时间,把市面上各种“前端面试八股文”汇总了一下,结合各大厂高频题,整理了 100 道前端高频八股题,每一道都给你:
- 标准回答(面试怎么答)
- 大白话解析(到底是什么东西)
- 适当延伸(避免被问死) 文章风格跟之前一样:多图、多表情包、多打比方,该煽动情绪的地方绝不客气。
一、HTML / CSS 基础篇(15 题)
1. DOCTYPE 是什么?严格模式 & 混杂模式怎么触发?
回答示例:
DOCTYPE 是用来告诉浏览器用哪种规范解析页面。HTML5 的写法是:
<!DOCTYPE html>
- 严格模式(标准模式):浏览器按 W3C 标准解析渲染。
- 混杂模式(怪异模式):浏览器兼容老版本页面,行为类似老 IE。
如果 HTML 文档最上面写了一个正确的
<!DOCTYPE html>,就进入严格模式;如果没写、写错、或者上面有其他内容(比如注释、XML 声明),就可能触发混杂模式。
2. HTML 语义化是什么?为什么要语义化?
回答示例:
HTML 语义化就是:用合适的标签表达内容含义,而不是全用 div + span。
好处:
- 对开发者:结构清晰,易读易维护。
- 对搜索引擎:SEO 更友好,爬虫能理解页面结构。
- 对无障碍:屏幕阅读器能更好“读”网页。 常见语义标签:
header、footer、nav、article、section、aside等。
3. 盒模型是什么?标准盒模型 & IE 盒模型区别?
回答示例:
盒模型 = content + padding + border + margin。
两种盒模型:
- 标准盒模型(W3C):
width/height只包含 content。- 总宽度 =
width + padding + border + margin
- 总宽度 =
- IE 盒模型(怪异盒模型):
width/height包含 content + padding + border。- 总宽度 =
width + margin通过 CSS 切换:
- 总宽度 =
/* 标准盒模型 */
box-sizing: content-box;
/* IE 盒模型 */
box-sizing: border-box;
4. 行内元素、块级元素有哪些?区别是什么?
回答示例:
- 块级元素:
div、p、h1~h6、ul、ol、li、table等。- 独占一行,可设宽高、内外边距。
- 行内元素:
span、a、img、input、button、label等。- 只占自身宽度,不换行,设置
width/height无效(img 等替换元素除外)。 区别要点:
- 只占自身宽度,不换行,设置
- 是否独占一行。
- 能否设置宽高。
- 垂直方向的 padding/margin 行内元素不占空间。
5. CSS 选择器优先级怎么算?
回答示例:
优先级从高到低:
!important- 行内样式(
style="...") - ID 选择器(
#id) - 类选择器(
.class)、属性选择器([attr])、伪类(:hover) - 标签选择器(
div)、伪元素(::before) - 通配符
*权重计算方式(近似):
- 行内样式:1000
- ID:100
- 类/属性/伪类:10
- 标签/伪元素:1 比较时,按位比较,数值越大优先级越高。
6. display: none 和 visibility: hidden 区别?
回答示例:
display: none:- 元素从文档流中消失,不占空间。
- 会触发重排(回流)。
visibility: hidden:- 元素不可见,但仍然占空间。
- 只触发重绘,不重排。
7. BFC 是什么?怎么触发?能解决什么问题?
回答示例:
BFC(Block Formatting Context,块级格式化上下文)是一个独立的渲染区域,内部元素不影响外部,外部也不影响内部。
触发条件(常见):
- 根元素
html float不为noneposition为absolute或fixeddisplay为inline-block、table-cell、table-caption、flex、inline-flexoverflow不为visibledisplay: flow-root能解决的问题:- 避免 margin 重叠。
- 清除浮动(包含浮动子元素)。
- 实现自适应布局(比如左固定右自适应)。
8. 如何实现水平垂直居中?
回答示例:
- 绝对定位 + transform
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
- Flexbox
.parent {
display: flex;
justify-content: center;
align-items: center;
}
- Grid
.parent {
display: grid;
place-items: center;
}
9. Flex 布局常用属性有哪些?
回答示例:
- 容器属性:
flex-direction:主轴方向(row / column)justify-content:主轴对齐(center / space-between 等)align-items:交叉轴对齐flex-wrap:是否换行align-content:多根轴对齐
- 项目属性:
order:排列顺序flex-grow:放大比例flex-shrink:缩小比例flex-basis:基准大小align-self:单个项目对齐方式
10. 常见 CSS 布局:左固定宽,右自适应有几种实现?
回答示例:
- float + margin
.left {
float: left;
width: 200px;
}
.right {
margin-left: 200px;
}
- float + overflow(触发 BFC)
.left {
float: left;
width: 200px;
}
.right {
overflow: hidden; /* 触发 BFC,不与浮动重叠 */
}
- Flex
.parent {
display: flex;
}
.left {
width: 200px;
}
.right {
flex: 1;
}
11. 移动端 1px 问题怎么解决?
回答示例:
在高分辨率屏幕上,1px 物理像素对应多个 CSS 像素,导致边框看起来“太细”。
常见方案:
transform: scaleY(0.5)+meta viewport缩放。- 使用
border-image或 SVG 边框。 - 使用
viewport+rem方案。 核心思路:用 CSS 或视觉方案“骗”过屏幕。
12. CSS 中 link 和 @import 区别?
回答示例:
link是 HTML 标签,@import是 CSS 语法。link加载的 CSS 会和页面同时加载;@import引入的 CSS 会等页面加载完再加载。link权重高于@import。 实际开发中,推荐使用link。
13. 如何隐藏一个元素?各种方式有什么区别?
回答示例:
display: none:不占空间,重排。visibility: hidden:占空间,只重绘。opacity: 0:占空间,只重绘,仍可交互。position: absolute; left: -9999px:移出视口。height: 0; overflow: hidden:高度塌陷。
14. CSS Sprites(精灵图)是什么?优缺点?
回答示例:
将多个小图标合并成一张大图,通过 background-position 显示不同区域。
优点:
- 减少 HTTP 请求数。
- 提升页面加载速度。 缺点:
- 开发时需要量位置。
- 维护成本高,改一张图要重新定位。
15. 响应式布局有哪些方案?
回答示例:
- 媒体查询(
@media)。 - 弹性布局(Flex + rem/vw)。
- 百分比布局。
- CSS Grid。
- 框架提供的栅格系统(如 Bootstrap)。
二、JavaScript 基础篇(30 题)
16. JS 有哪些数据类型?
回答示例:
- 基本类型:
undefined、null、boolean、number、string、symbol(ES6)、bigint。 - 引用类型:
object(含数组、函数、正则等)。
17. typeof 能判断哪些类型?
回答示例:
typeof能准确判断基本类型(除null):typeof undefined === 'undefined'typeof 'abc' === 'string'typeof 123 === 'number'
- 对于引用类型:
typeof [] === 'object'typeof {} === 'object'typeof function(){} === 'function'
- 注意:
typeof null === 'object',这是一个历史 Bug。
18. instanceof 的原理?手写实现?
回答示例:
instanceof 用于检测构造函数的 prototype 是否在对象的原型链上。
手写实现思路:
function myInstanceof(obj, Constructor) {
// 基本类型直接返回 false
if (typeof obj !== 'object' || obj === null) return false;
let proto = Object.getPrototypeOf(obj);
while (proto) {
if (proto === Constructor.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
return false;
}
19. 什么是原型、原型链?
回答示例:
- 每个函数都有一个
prototype属性,指向原型对象。 - 每个对象都有一个
__proto__,指向其构造函数的原型。 - 原型链:当访问一个对象的属性时,如果本身没有,就沿着
__proto__一直往上找,直到null。
20. 什么是作用域、作用域链?
回答示例:
- 作用域:变量和函数的可访问范围。
- 全局作用域、函数作用域、块级作用域(ES6)。
- 作用域链:在当前作用域找不到变量,就往外层作用域找,形成一条链。
21. 什么是闭包?有什么应用?
回答示例:
闭包是指:有权访问另一个函数作用域中变量的函数。
简单例子:
function outer() {
let a = 1;
return function inner() {
console.log(a);
};
}
应用场景:
- 数据私有化。
- 函数柯里化。
- 防抖/节流。
22. JS 的继承方式有哪些?手写一种?
回答示例:
常见继承:
- 原型链继承。
- 构造函数继承。
- 组合继承。
- 寄生组合继承(最常用)。 手写寄生组合继承示例:
function inherit(Sub, Super) {
Sub.prototype = Object.create(Super.prototype);
Sub.prototype.constructor = Sub;
}
function Super(name) {
this.name = name;
}
Super.prototype.say = function() {
console.log(this.name);
};
function Sub(name, age) {
Super.call(this, name);
this.age = age;
}
inherit(Sub, Super);
23. new 操作符做了什么?手写实现?
回答示例:
- 创建一个空对象。
- 将对象的
__proto__指向构造函数的prototype。 - 执行构造函数,绑定
this。 - 如果构造函数返回对象,则返回该对象;否则返回新建对象。 手写实现:
function myNew(fn, ...args) {
const obj = Object.create(fn.prototype);
const res = fn.apply(obj, args);
return res instanceof Object ? res : obj;
}
24. this 指向规则?
回答示例:
- 默认绑定:独立调用,
this指向全局对象(严格模式下是undefined)。 - 隐式绑定:作为对象方法调用,
this指向该对象。 - 显式绑定:
call/apply/bind。 new绑定:指向新创建的对象。- 箭头函数:没有自己的
this,继承外层作用域的this。
25. call / apply / bind 区别?
回答示例:
call(thisArg, arg1, arg2, ...)apply(thisArg, [arg1, arg2])bind(thisArg, arg1, arg2, ...)- 返回一个新函数,不会立即执行。
26. 什么是变量提升?
回答示例:
使用 var 声明变量和函数声明,会被“提升”到当前作用域顶部。
- 变量提升:只提升声明,不提升赋值。
- 函数提升:整体提升。
console.log(a); // undefined
var a = 1;
等价于:
var a;
console.log(a);
a = 1;
27. ES6 有哪些常用新特性?
回答示例:
let/const- 箭头函数
- 模板字符串
- 解构赋值
- 默认参数
- 扩展运算符
- Promise
- 类(class)
- 模块化(import / export)
28. let / const / var 区别?
回答示例:
var:函数作用域,存在变量提升。let:块级作用域,不存在变量提升,存在暂时性死区。const:块级作用域,声明时必须赋值,之后不能改引用(但对象属性可改)。
29. 什么是暂时性死区?
回答示例:
在 let / const 声明之前,访问该变量会抛出 ReferenceError,这段区域叫“暂时性死区”。
console.log(a); // ReferenceError
let a = 1;
30. == 和 === 区别?
回答示例:
===:类型和值都相等才返回true。==:会进行类型转换再比较。 建议:日常使用===,避免隐式转换带来的坑。
31. 什么是深拷贝、浅拷贝?手写深拷贝?
回答示例:
- 浅拷贝:只复制一层引用,修改会互相影响。
- 深拷贝:递归复制所有层级,互不影响。 手写深拷贝简易版:
function deepClone(obj, cache = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj;
if (cache.has(obj)) return cache.get(obj);
const cloneObj = Array.isArray(obj) ? [] : {};
cache.set(obj, cloneObj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
cloneObj[key] = deepClone(obj[key], cache);
}
}
return cloneObj;
}
32. 什么是防抖和节流?手写实现?
回答示例:
- 防抖:在事件被触发 n 毫秒后再执行回调,如果在这 n 毫秒内又被触发,则重新计时。
- 节流:规定在一个单位时间内,只能触发一次函数。 手写防抖:
function debounce(fn, delay) {
let timer = null;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
手写节流:
function throttle(fn, delay) {
let last = 0;
return function(...args) {
const now = Date.now();
if (now - last >= delay) {
last = now;
fn.apply(this, args);
}
};
}
33. 什么是事件委托(事件代理)?
回答示例:
利用事件冒泡,将子元素的事件处理函数绑定到父元素上,通过 event.target 判断具体子元素。
优点:
- 减少绑定次数,提升性能。
- 对动态新增元素同样有效。
34. 什么是事件冒泡和事件捕获?
回答示例:
- 事件捕获:从
window往目标元素传播。 - 事件冒泡:从目标元素往
window传播。 - DOM 事件流:捕获 -> 目标阶段 -> 冒泡。
可通过
addEventListener的第三个参数指定: true:捕获阶段触发。false(默认):冒泡阶段触发。
35. addEventListener 第三个参数是什么?
回答示例:
第三个参数可以是:
- 布尔值:
true表示在捕获阶段触发,false表示在冒泡阶段触发。 - 对象:支持
capture、once、passive等选项。
36. 什么是跨域?常见解决方案?
回答示例:
浏览器同源策略(协议 + 域名 + 端口)限制,导致不同源之间不能直接请求。
常见方案:
- CORS(后端设置 Access-Control-Allow-Origin 等)。
- JSONP(利用
script标签,只支持 GET)。 - 反向代理(Nginx)。
- postMessage、WebSocket 等。
37. 什么是 JSONP?原理是什么?
回答示例:
JSONP 是利用 script 标签不受同源策略限制的特性,通过动态创建 script,请求一个带回调函数名的接口,服务器返回函数调用,前端预先定义好该函数。
缺点:只支持 GET 请求。
38. 什么是 XSS?如何防范?
回答示例:
XSS(跨站脚本攻击):攻击者注入恶意脚本到页面。
防范:
- 对用户输入进行转义。
- 使用 CSP(Content Security Policy)。
- 设置
HttpOnlycookie,防止 JS 读取。
39. 什么是 CSRF?如何防范?
回答示例:
CSRF(跨站请求伪造):伪造用户请求发给目标站点。
防范:
- 验证码。
- 检查 Referer 头。
- 使用 token 并验证。
40. 什么是 Event Loop(事件循环)?
回答示例:
- JS 是单线程,事件循环负责管理异步任务。
- 执行栈执行同步代码。
- 宏任务:
script、setTimeout、setInterval、I/O、UI 渲染。 - 微任务:
Promise.then、MutationObserver。 - 事件循环流程:
- 执行一个宏任务。
- 执行所有微任务。
- UI 渲染(如果需要)。
- 进入下一轮事件循环。
41. 宏任务和微任务有哪些?
回答示例:
- 宏任务:
script、setTimeout、setInterval、setImmediate(Node)、I/O、UI 渲染。 - 微任务:
Promise.then、catch、finally、process.nextTick(Node)、MutationObserver。
42. Promise 的状态有哪些?手写一个简单的 Promise?
回答示例:
状态:
pendingfulfilledrejected简单实现:
class MyPromise {
constructor(executor) {
this.status = 'pending';
this.value = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = value => {
if (this.status === 'pending') {
this.status = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(cb => cb(this.value));
}
};
const reject = reason => {
if (this.status === 'pending') {
this.status = 'rejected';
this.value = reason;
this.onRejectedCallbacks.forEach(cb => cb(this.value));
}
};
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
then(onFulfilled, onRejected) {
if (this.status === 'fulfilled') {
onFulfilled(this.value);
}
if (this.status === 'rejected') {
onRejected(this.value);
}
if (this.status === 'pending') {
this.onFulfilledCallbacks.push(onFulfilled);
this.onRejectedCallbacks.push(onRejected);
}
}
}
43. Promise.all 和 Promise.race 区别?手写实现?
回答示例:
Promise.all:所有 Promise 都成功,才返回结果数组;一个失败就立即失败。Promise.race:返回最先改变状态的那个 Promise 结果。 手写Promise.all:
Promise.myAll = function(promises) {
return new Promise((resolve, reject) => {
const result = [];
let count = 0;
promises.forEach((p, i) => {
Promise.resolve(p).then(
value => {
result[i] = value;
count++;
if (count === promises.length) {
resolve(result);
}
},
reject
);
});
});
};
44. async/await 原理是什么?
回答示例:
async/await 是 Promise 的语法糖,Generator 的语法糖。
async函数返回一个 Promise。await等待一个 Promise 完成,并返回其结果。
45. 什么是垃圾回收机制?
回答示例:
JS 自动回收不再使用的内存。
常见算法:
- 标记清除:标记所有变量,然后清除环境中无法访问的变量。
- 引用计数:统计引用次数,为 0 时回收(但循环引用会出问题)。
46. 什么是内存泄漏?常见原因?
回答示例:
不再使用的内存没有被释放,导致内存占用越来越多。
常见原因:
- 全局变量。
- 未清理的定时器。
- 闭包。
- DOM 引用未清理。
47. 什么是模块化?CommonJS 和 ES6 模块区别?
回答示例:
- CommonJS:Node.js 标准,
require/module.exports,同步加载,运行时加载。 - ES6 模块:
import/export,编译时加载,静态分析。
48. 什么是防抖和节流的应用场景?
回答示例:
- 防抖:
- 搜索输入框联想。
- 窗口 resize。
- 节流:
- 滚动加载更多。
- 鼠标移动事件。
49. Object.is() 和 === 区别?
回答示例:
Object.is() 在以下两点与 === 不同:
Object.is(NaN, NaN) === trueObject.is(-0, +0) === false
50. null 和 undefined 区别?
回答示例:
undefined:表示“缺少值”,变量已声明但未赋值。null:表示“空值”,显式赋值为null。
51. 什么是包装类型?
回答示例:
基本类型在必要时会被临时包装成对象,称为包装类型。
const s = 'hello';
s.toUpperCase(); // 实际上先 new String(s),调用方法后销毁实例
52. const 对象属性能修改吗?
回答示例:
const 保证变量指向的地址不变,但对象属性可以修改。
const obj = { a: 1 };
obj.a = 2; // 允许
obj = {}; // 报错
53. 什么是 arguments?
回答示例:
arguments 是类数组对象,包含函数传入的所有参数,具有 length 属性,但没有数组方法。
54. 什么是剩余参数(rest parameters)?
回答示例:
使用 ...args 收集多余的参数,形成真正的数组。
function sum(...args) {
return args.reduce((a, b) => a + b, 0);
}
55. 如何判断一个变量是数组?
回答示例:
Array.isArray(arr); // 推荐方式
arr instanceof Array;
Object.prototype.toString.call(arr) === '[object Array]';
56. forEach / for...in / for...of 区别?
回答示例:
forEach:遍历数组,不能break。for...in:遍历对象可枚举属性(含原型链),不适合数组。for...of:遍历可迭代对象(数组、Map、Set 等),支持break。
57. map 和 forEach 区别?
回答示例:
forEach:只遍历,不返回新数组。map:返回一个新数组,是映射后的结果。
58. 什么是函数柯里化?
回答示例:
将多参数函数转为一系列单参数函数。
function add(a) {
return function(b) {
return a + b;
};
}
add(1)(2); // 3
59. 什么是高阶函数?
回答示例:
满足以下之一的函数:
- 接受一个或多个函数作为参数。
- 返回一个函数。
例如:
map、filter、reduce。
60. 什么是尾调用优化?
回答示例:
尾调用是指函数最后一步调用另一个函数。某些引擎会在严格模式下进行优化,复用调用栈,避免栈溢出。
三、浏览器 & 网络篇(20 题)
61. 从输入 URL 到页面展示全过程?
回答示例:
- DNS 解析:域名 -> IP。
- TCP 三次握手。
- 发送 HTTP 请求。
- 服务器处理并返回响应。
- 浏览器解析 HTML -> DOM 树。
- 解析 CSS -> CSSOM 树。
- 合成渲染树,布局、绘制。
- JavaScript 执行。
62. TCP 三次握手过程?为什么是三次?
回答示例:
- 客户端发送 SYN 报文。
- 服务端返回 SYN + ACK。
- 客户端发送 ACK。 三次握手的原因:防止已失效的连接请求报文突然又传送到服务端,导致错误连接。
63. TCP 四次挥手过程?为什么是四次?
回答示例:
- 客户端发送 FIN。
- 服务端返回 ACK。
- 服务端发送 FIN。
- 客户端返回 ACK。 原因:TCP 是全双工,每个方向都需要单独关闭。
64. HTTP 和 HTTPS 区别?
回答示例:
- HTTP:明文传输,不安全。
- HTTPS:HTTP + SSL/TLS,加密传输,更安全。
65. HTTP 常见状态码?
回答示例:
- 1xx:信息响应。
- 2xx:成功。
- 200 OK
- 3xx:重定向。
- 301 永久重定向
- 302 临时重定向
- 304 缓存有效
- 4xx:客户端错误。
- 400 Bad Request
- 401 Unauthorized
- 403 Forbidden
- 404 Not Found
- 5xx:服务器错误。
- 500 Internal Server Error
- 502 Bad Gateway
- 503 Service Unavailable
66. HTTP 1.1 和 HTTP 2.0 区别?
回答示例:
- HTTP 1.1:
- 长连接(Keep-Alive)。
- 管道化,但队头阻塞。
- HTTP 2.0:
- 二进制分帧。
- 多路复用。
- 头部压缩。
- 服务器推送。
67. 什么是浏览器缓存?强缓存和协商缓存?
回答示例:
- 强缓存:不请求服务器,直接从缓存读取。
Cache-Control、Expires。
- 协商缓存:向服务器确认缓存是否有效。
Last-Modified/If-Modified-Since。ETag/If-None-Match。
68. 什么是 Cookie、SessionStorage、LocalStorage?
回答示例:
- Cookie:每次请求都会携带,大小有限。
- LocalStorage:持久化本地存储,除非主动删除。
- SessionStorage:会话级别,关闭标签页就清除。
69. Cookie 有哪些安全属性?
回答示例:
HttpOnly:禁止 JS 访问,防 XSS。Secure:只在 HTTPS 下传输。SameSite:防止 CSRF。
70. 什么是浏览器同源策略?
回答示例:
同源策略是浏览器安全机制,限制不同源之间的资源交互。
同源 = 协议 + 域名 + 端口相同。
71. 常见跨域方式有哪些?
回答示例:
- CORS。
- JSONP。
- 反向代理。
- WebSocket。
- postMessage。
72. 什么是 XSS 和 CSRF?
(见 38、39 题)
73. 什么是 DNS 解析过程?
回答示例:
- 浏览器缓存。
- 系统缓存。
- 路由器缓存。
- ISP DNS 服务器。
- 根域名服务器 -> 顶级域名服务器 -> 权威域名服务器。
74. 什么是 CDN?
回答示例:
CDN(内容分发网络)将资源缓存到全球多个节点,用户就近获取,提升访问速度。
75. 什么是 DNS 预解析?
回答示例:
在 HTML 中使用:
<link rel="dns-prefetch" href="//example.com">
提前解析域名,减少延迟。
76. 什么是重排(回流)和重绘?
回答示例:
- 重排:布局变化,需要重新计算几何属性。
- 重绘:外观变化,不影响布局。 重排必定重绘,重绘不一定重排。
77. 如何减少重排重绘?
回答示例:
- 批量修改 DOM。
- 使用
transform代替top/left。 - 使用
visibility代替display: none(有时)。 - 避免频繁读取布局属性。
78. 什么是虚拟 DOM?
回答示例:
虚拟 DOM 是用 JS 对象描述 DOM 结构,通过 diff 算法最小化更新,减少真实 DOM 操作。
79. 什么是 SPA?优缺点?
回答示例:
SPA(单页应用):只加载一个 HTML,通过路由动态切换内容。
优点:
- 用户体验好,页面流畅。
- 前后端分离。 缺点:
- SEO 不友好。
- 首屏加载可能慢。
80. 前端性能优化常见指标?
回答示例:
- FP(First Paint)
- FCP(First Contentful Paint)
- LCP(Largest Contentful Paint)
- TTI(Time to Interactive)
- CLS(Cumulative Layout Shift)
四、框架 & 工程化篇(20 题)
81. Vue 双向绑定原理?
回答示例:
Vue 2 使用 Object.defineProperty 劫持数据,结合发布订阅模式实现双向绑定。
Vue 3 使用 Proxy 代替 defineProperty,可以监听数组变化和对象新增属性。
82. Vue 生命周期有哪些?
回答示例:
beforeCreatecreatedbeforeMountmountedbeforeUpdateupdatedbeforeDestroydestroyedVue 3 有setup、onMounted等。
83. Vue 组件通信方式有哪些?
回答示例:
props/$emit$parent/$childrenprovide/inject$refs- Vuex
- Event Bus
84. Vuex 核心概念?
回答示例:
state:状态。getters:计算属性。mutations:同步修改状态。actions:异步操作。modules:模块拆分。
85. Vue 中 key 的作用是什么?
回答示例:
key 用于标识节点,在 diff 算法中判断节点是否可复用,提高性能。
86. React 中 key 的作用是什么?
回答示例:
同 Vue,key 帮助 React 识别哪些元素改变、添加或删除,提高 diff 效率。
87. React 生命周期有哪些?
回答示例:
- 挂载:
constructorstatic getDerivedStateFromPropsrendercomponentDidMount
- 更新:
static getDerivedStateFromPropsshouldComponentUpdaterendergetSnapshotBeforeUpdatecomponentDidUpdate
- 卸载:
componentWillUnmount
88. React setState 是同步还是异步?
回答示例:
- 在合成事件和生命周期函数中,
setState是异步更新。 - 在原生事件、定时器中,是同步更新。
89. React Hooks 有哪些常用?
回答示例:
useStateuseEffectuseContextuseReduceruseCallbackuseMemouseRef
90. useEffect 和 useLayoutEffect 区别?
回答示例:
useEffect:在渲染之后异步执行。useLayoutEffect:在 DOM 更新之后同步执行,适合读取布局。
91. 什么是 React Fiber?
回答示例:
Fiber 是 React 16 引入的新协调算法,将渲染任务拆分成小单元,实现可中断渲染,提升响应速度。
92. Webpack 核心概念有哪些?
回答示例:
entry:入口。output:输出。loader:处理非 JS 文件。plugin:扩展功能。mode:开发/生产模式。
93. Loader 和 Plugin 区别?
回答示例:
- Loader:转换文件内容,如
babel-loader、css-loader。 - Plugin:扩展构建流程,如
HtmlWebpackPlugin、DefinePlugin。
94. Webpack 构建流程?
回答示例:
- 初始化参数。
- 创建 Compiler 对象。
- 加载所有插件。
- 根据 entry 找到入口文件。
- 编译模块,递归处理依赖。
- 输出资源到 output 目录。
95. 什么是 Tree Shaking?
回答示例:
Tree Shaking 是在打包时删除未使用的代码,依赖 ES6 模块静态分析。
96. Vite 为什么比 Webpack 快?
回答示例:
- Vite 利用浏览器原生 ES 模块,开发时不打包,编译按需进行。
- Webpack 需要先打包再启动开发服务器。
97. 什么是 Git Flow?
回答示例:
Git Flow 是一种分支模型:
master:生产分支。develop:开发分支。feature:功能分支。release:发布分支。hotfix:紧急修复分支。
98. git rebase 和 git merge 区别?
回答示例:
merge:保留分支历史,创建一个合并提交。rebase:将当前分支移到目标分支顶端,保持线性历史。
99. git pull 和 git fetch 区别?
回答示例:
git fetch:只拉取远程更新,不合并。git pull:fetch + merge,拉取并合并。
100. 什么是微前端?
回答示例:
微前端是将一个大应用拆分成多个小前端应用,可以独立开发、部署,再组合在一起。
常见框架:qiankun、single-spa。
五、最后的话:这 100 题,只是你的“基本功” (ง •_•)ง
看完这 100 题,你以为你“会了”,但真实面试里:
- 你能不能把这些东西串起来,讲清楚一个项目?
- 你能不能在面试官追问时,从原理延伸到场景? 八股文不是死记硬背,而是你脑子里的一张地图。 地图有了,后面你要做的,是:
- 多写项目,多踩坑。
- 多看源码,多思考。
- 多总结,多复盘。
如果你愿意,我可以在下一步:
- 把这 100 题按“HTML/CSS、JS、浏览器、网络、框架、工程化”拆成多篇文章。
- 或者针对某一题,给你写一个“面试官视角”的追问范例,让你练练手。