前端八股文-高频面试题 - 教程
HTML & CSS 篇
1. 盒模型
问:说说CSS盒模型,以及box-sizing的作用?
- 标准盒模型:
width和height只包含内容。 - IE盒模型:
width和height包含内容、内边距和边框。 box-sizing:content-box:标准模型(默认)。border-box:IE模型。更直观,开发常用。
2. 居中对齐
问:如何实现一个元素的水平垂直居中?(至少说出3种)
- Flexbox(首选):
.parent { display: flex; justify-content: center; align-items: center; } - Grid:
.parent { display: grid; place-items: center; } - 定位 + Transform:
.child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
3. BFC
问:什么是BFC?如何触发?有什么作用?
- 定义:块级格式化上下文,一个独立的渲染区域。
- 触发条件:
float不为none、overflow不为visible、display: inline-block/flex/table-cell、position: absolute/fixed等。 - 作用:
- 清除浮动(防止高度塌陷)。
- 防止外边距重叠。
- 隔离元素,阻止元素被浮动元素覆盖。
4. 选择器与优先级
问:CSS选择器的优先级如何计算?
- !important > 行内样式 > ID选择器 > 类/伪类/属性选择器 > 元素/伪元素选择器 > 通配符。
- 计算规则:
(a, b, c, d)- a: 行内样式
- b: ID选择器个数
- c: 类、伪类、属性选择器个数
- d: 元素、伪元素选择器个数
- 从左到右逐级比较。
JavaScript 篇(核心中的核心)
1. 事件循环
问:说出下面代码的输出顺序
console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
console.log(4);
// 输出:1, 4, 3, 2
- 原理:
- 同步代码(宏任务)先执行:
1, 4。 - 清空微任务队列:
Promise.then->3。 - 执行下一个宏任务:
setTimeout->2。
- 同步代码(宏任务)先执行:
2. 闭包
问:什么是闭包?有什么作用和缺点?
- 定义:函数能够记住并访问其词法作用域,即使该函数在其作用域之外执行。
- 作用:
- 创建私有变量和方法(模块模式)。
- 实现柯里化和函数式编程。
- 缺点: improper use can lead to 内存泄漏。
3. this 指向
问:如何确定函数中this的指向?
- 默认绑定:严格模式
undefined,非严格模式window。 - 隐式绑定:
obj.foo()->this指向obj。 - 显式绑定:
call/apply/bind-> 指向第一个参数。 new绑定:指向新创建的对象。- 箭头函数:继承定义时外层作用域的
this,无法被改变。
4. 原型与原型链
问:说说原型链的理解?
- 每个对象都有一个
__proto__属性,指向它的构造函数的prototype。 - 当访问一个对象的属性时,如果自身没有,就通过
__proto__向上查找,这条链就是原型链,终点是Object.prototype.__proto__(null)。
5. 手写代码(必考!)
- 手写
Promise.allPromise.myAll = function(promises) { return new Promise((resolve, reject) => { const results = []; let count = 0; promises.forEach((promise, i) => { Promise.resolve(promise).then(res => { results[i] = res; if (++count === promises.length) resolve(results); }).catch(reject); }); }); }; - 手写
bindFunction.prototype.myBind = function(context, ...args) { const fn = this; return function(...innerArgs) { return fn.apply(context, [...args, ...innerArgs]); }; }; - 手写防抖与节流
- 手写深拷贝
Vue 篇
1. Vue2 vs Vue3 响应式原理
- Vue2:
Object.defineProperty- 缺点:无法监听对象属性的增删、数组索引/长度变化。
- 解决:
Vue.set/Vue.delete,重写数组方法。
- Vue3:
Proxy- 优点:可监听所有操作,性能更好。
2. v-if vs v-show
v-if:真正的条件渲染,元素会销毁/创建。切换开销大。v-show:通过CSSdisplay控制。初始渲染开销大。- 使用场景:频繁切换用
v-show,运行时条件很少改变用v-if。
3. key 的作用
- 核心:
key是VNode的唯一标识,用于Diff算法高效地复用节点。 - 为什么不用
index:列表顺序变化时,index也会变,导致性能浪费和状态错乱。
4. Vue 组件间通信方式
- Props /
$emit:父子。 v-model:语法糖。$parent/$children/refs:直接访问(不推荐)。- Event Bus:任意组件(Vue3用mitt)。
- Provide / Inject:祖孙。
- Vuex / Pinia:状态管理。
5. nextTick 原理
- Vue将DOM更新任务推入一个异步队列。
- 在下一个事件循环“tick”中清空队列。
- 内部尝试使用
Promise.then->MutationObserver->setImmediate->setTimeout来创建微/宏任务。
React 篇
1. React 事件机制
- 合成事件:React将所有事件委托到
document(v17+是root)上。 - 优点:跨浏览器兼容、性能更好(事件池)。
- 与原生事件区别:异步访问事件对象需调用
e.persist()。
2. useState vs useEffect
useState:用于在函数组件中添加状态。更新是异步的。useEffect:用于执行副作用。[]:只在挂载后执行一次。[dep]:在挂载后和dep变化后执行。- 返回函数:用于清理(如取消订阅、清除定时器)。
3. useCallback & useMemo
useCallback:缓存函数本身,防止因函数引用变化导致子组件不必要的重渲染。useMemo:缓存计算结果,避免每次渲染都进行高开销计算。
4. 受控组件 vs 非受控组件
- 受控组件:表单数据由React state管理(
value+onChange)。推荐。 - 非受控组件:表单数据由DOM自身管理(
ref获取)。用于文件上传等场景。
5. 虚拟DOM & Diff算法
- 虚拟DOM:轻量的JS对象,描述真实DOM。
- Diffing策略:
- 同级比较,不跨级。
- 不同类型的元素会拆卸重建。
- 同类型的元素会复用,只更新变化的属性。
- 列表使用**
key**进行高效对比。
性能优化 & 网络 篇
1. 性能优化指标
- LCP:最大内容绘制 < 2.5s。
- FID/INP:交互响应延迟 < 100ms/200ms。
- CLS:累积布局偏移 < 0.1。
2. 优化手段
- 加载:代码分割、懒加载、图片优化、CDN、HTTP/2、
preload/preconnect。 - 渲染:避免布局抖动、使用
transform/opacity做动画、分解长任务。 - 缓存:强缓存(
Cache-Control: max-age)、协商缓存(Etag)。
3. 从输入URL到页面显示发生了什么?
- DNS解析:将域名解析为IP地址。
- TCP连接:三次握手。
- 发送HTTP请求。
- 服务器处理并返回响应。
- 浏览器解析渲染:
- 解析HTML构建DOM树。
- 解析CSS构建CSSOM树。
- 合并成渲染树。
- 布局。
- 绘制。
- TCP断开连接:四次挥手。
4. HTTP 缓存
- 强缓存:
Cache-Control(max-age)、Expires。状态码200。 - 协商缓存:
Last-Modified/If-Modified-Since、Etag/If-None-Match。状态码304。
这份清单覆盖了前端面试90%以上的高频考点。建议你不仅要记住答案,更要理解其背后的原理,并能用简洁的语言清晰地表达出来。祝你面试顺利!
浙公网安备 33010602011771号