前端工程JavaScript事件循环原型链手写题浏览器网络
前端核心总纲
前端面试通用总纲:HTML/CSS、JS 核心(闭包/原型/事件循环)、框架、工程化、网络、手写题的高频考点详答。
前端核心总纲
通用前端面试总纲,按「HTML/CSS → JavaScript → 框架 → 工程化 → 网络 → 计算机基础」逐项给答案。覆盖面最广,适合第一轮系统复习。
一、HTML & CSS
- 语义化:用
<header>/<nav>/<article>/<section>/<footer>而非通篇<div>;好处是开发者友好、SEO 友好、无障碍友好。 - 盒模型:标准盒模型
width= content;IE 盒模型width= content+padding+border。开发常用box-sizing: border-box。 - BFC:独立渲染区域,内部不影响外部。触发:根元素/浮动/绝对定位/
overflow非 visible/flex/grid 等。解决:清除浮动、防外边距重叠、阻止被浮动覆盖。 - 重绘 vs 回流:回流(Reflow)重新计算几何信息(宽高/位置/DOM 增删);重绘(Repaint)只改外观(颜色)。避免:批量改 class、
display:none后操作、documentFragment、动画用 transform/opacity。
二、JavaScript 核心
闭包
有权访问另一个函数作用域中变量的函数。原理:词法作用域,内部函数引用外部变量,外部函数执行完变量对象不被销毁。应用:私有变量、柯里化、循环保存状态。缺点:使用不当内存泄漏(退出前置 null)。
原型与原型链
实例.__proto__ === 构造函数.prototype,构造函数.prototype.constructor === 构造函数。访问属性沿 __proto__ 链向上查找。继承:ES5 寄生组合(Parent.call(this) + Object.create(Parent.prototype)),ES6 class extends 是语法糖。
事件循环(Event Loop)
- 宏任务:
script、setTimeout、setInterval、setImmediate、I/O、MessageChannel - 微任务:
Promise.then/catch/finally、MutationObserver、queueMicrotask、process.nextTick
执行流程:执行一个宏任务 → 清空整个微任务队列 → 可能 UI 渲染 → 下一个宏任务。
⚠️ 「UI 渲染」不是宏任务——渲染是「微任务清空后、下一个宏任务前」择机执行的独立步骤。
requestAnimationFrame也不属于宏/微任务,它挂在渲染步骤之前。这是最常见的错答点。
三、框架(React)
- Virtual DOM:JS 对象对真实 DOM 的轻量抽象,Diff 找最小变更后批量更新。
- Diff 算法:同级比较 O(n);类型不同直接重建;列表靠
key复用(不要用数组索引)。 - Hooks:解决逻辑复用难、复杂组件难拆分、class 的 this 困扰。Hooks 是链表存储,不能在条件/循环/嵌套中调用。
useEffectvsuseLayoutEffect:前者绘制后异步执行;后者 DOM 变更后、绘制前同步执行(用于测量 DOM,尽量少用)。- 性能优化:
React.memo(props 浅比较)、useMemo/useCallback、React.lazy+Suspense代码分割。
四、工程化
Webpack
- Loader:转换器,处理非 JS 文件(css/vue/图片)。
- Plugin:扩展器,监听生命周期钩子做打包优化/资源管理。
- HMR 原理:文件监听重新编译 → WebSocket 通知新 hash → 浏览器 fetch/XHR 拉取
hot-update.json+hot-update.js→ 执行module.hot.accept回调。⚠️ 现代webpack-dev-server已用 fetch/XHR,不是 JSONP。
TypeScript
interfacevstype:interface 可声明合并、可 extends;type 可联合类型/元组/别名。官方推荐优先 interface。- 工具类型:
Partial<T>、Pick<T,K>、Readonly<T>、Record<K,T>。
五、网络
- 从 URL 到页面:URL 解析 → DNS → TCP 三次握手 → 发请求(HTTPS 有 TLS)→ 服务器响应 → 解析渲染(DOM/CSSOM/Render/Layout/Paint/Composite)→ 四次挥手。
- 缓存:强缓存(
Cache-Control: max-age优先级高于Expires);协商缓存(ETag/If-None-Match优于Last-Modified/If-Modified-Since,返回 304)。 - XSS:注入恶意脚本。防御:输出转义、CSP、Cookie
HttpOnly。 - CSRF:诱导用户以登录态发恶意请求。防御:Token、验证 Referer、二次验证。
六、手写题(核心)
// 防抖
function debounce(func, wait, immediate) {
let timeout;
return function (...args) {
const context = this;
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(() => {
timeout = null;
if (!immediate) func.apply(context, args);
}, wait);
if (callNow) func.apply(context, args);
};
}
// 深拷贝(解决循环引用)
function deepClone(obj, hash = 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 (hash.has(obj)) return hash.get(obj);
const cloneObj = new obj.constructor();
hash.set(obj, cloneObj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) cloneObj[key] = deepClone(obj[key], hash);
}
return cloneObj;
}
// new 操作符
function myNew(constructor, ...args) {
const obj = Object.create(constructor.prototype);
const result = constructor.apply(obj, args);
return result instanceof Object ? result : obj;
}
// Promise.all
function promiseAll(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) return reject(new TypeError('Arguments must be an array'));
const results = [];
let count = 0;
if (promises.length === 0) return resolve(results);
promises.forEach((promise, index) => {
Promise.resolve(promise).then(value => {
results[index] = value;
if (++count === promises.length) resolve(results);
}).catch(reject);
});
});
}
七、Web 核心指标
- LCP(最大内容绘制):加载性能,≤2.5s
- INP(交互到下一次绘制):交互响应,≤200ms(2024-03 起取代 FID)
- CLS(累积布局偏移):视觉稳定性,≤0.1