字节前端面试知识点总结
1. 闭包是什么?
定义: 闭包是函数和其词法作用域的组合,即一个函数可以“记住”其定义时所处的作用域,即使在函数在其作用域外执行。
原理: 函数在定义时会“捕获”其外部作用域变量,即便函数在外部执行,这些变量仍然可以访问。
应用场景:
- 数据隐藏(如创建私有变量)
- 函数柯里化
- 缓存(memoization)
- 防抖 / 节流函数
示例:
function createCounter() {let count = 0return function() {count++return count}
}
const counter = createCounter()
counter() // 1
counter() // 2
面试话术: 闭包的本质是函数作用域的记忆,它能保存状态、做私有封装,是 JS 函数式编程的核心能力。
2. 防抖函数
定义: 设定一个固定时间 delay,事件触发后 delay 时间内不再触发才执行函数。
应用:
- 输入框搜索
- resize 监听
- scroll 滚动优化
实现:
function debounce(fn, delay) {let timer = nullreturn function(...args) {clearTimeout(timer)timer = setTimeout(() => {fn.apply(this, args)}, delay)}
}
通俗解释: 比如你敲键盘,每次敲一个字母,后台就发请求——太浪费了。防抖就是“等你停 500ms 再发”。
面试话术: 防抖通过闭包保存定时器,避免频繁调用,是前端事件性能优化中最常见的应用。
3. Flex 布局项目中如何使用
核心轴: 主轴(默认横向)+ 交叉轴(默认纵向)
常用属性:
- 容器属性(display: flex, justify-content, align-items)
- 项目属性(flex, order, align-self)
示例: 横向居中:
.parent {display: flex;justify-content: center;align-items: center;
}
项目中应用: 页面布局、导航栏、左右结构、弹性容器都可用 flex 实现响应式适配。
面试话术: Flex 布局简洁强大,适合一维布局场景,主流页面都离不开它。
4. 跨域是什么?如何解决?
定义: 浏览器同源策略限制,不允许从一个域向另一个域发起 AJAX 请求。
判断跨域标准: 协议、域名、端口三者只要有一个不同就属于跨域。
常见解决方案:
- CORS(后端设置
Access-Control-Allow-Origin
) - JSONP(仅 GET 请求)
- 代理转发(前端开发服务器配置 proxy)
- iframe + postMessage 通信
面试话术: 跨域是浏览器安全机制导致,生产中主要使用 CORS 或 proxy。JSONP 是早期解决方案。
5. JSONP 和 postMessage
JSONP: 利用 <script>
标签无跨域限制,通过 URL 传参数,后端返回 JS 调用函数。
// 前端:
function handleData(data) {console.log(data)
}
const script = document.createElement('script')
script.src = 'http://example.com/data?callback=handleData'
document.body.appendChild(script)
缺点: 仅支持 GET,请求不安全,不推荐用于敏感数据。
postMessage: 跨域 iframe/窗口之间通信的安全机制。
// 子页面:
window.parent.postMessage('hello', '*')// 父页面:
window.addEventListener('message', (e) => {console.log(e.data)
})
面试话术: postMessage 更现代、安全,推荐用在 iframe 跨域、OAuth 登录、前端微服务通信场景。
6. WebSocket 重连接与消息重发
定义: WebSocket 是双向通信协议,可实现浏览器和服务器的实时通信。
断线重连实现思路:
- 使用
onclose
监听断开 - 延迟一段时间尝试 reconnect
- 设置最大重试次数避免无限重连
发送消息重试:
- 发送前检测
socket.readyState
- 若未连接好,将消息暂存,连接建立后 flush 消息队列
示例代码片段:
let socket
let msgQueue = []function initSocket() {socket = new WebSocket('wss://server')socket.onopen = () => {msgQueue.forEach(msg => socket.send(msg))msgQueue = []}socket.onclose = () => {setTimeout(initSocket, 1000)}
}function send(msg) {if (socket.readyState === 1) socket.send(msg)else msgQueue.push(msg)
}
面试话术: WebSocket 是实时通信首选协议,断线重连和消息重发机制对稳定性要求较高的业务尤为重要。
7. npm / yarn / pnpm 区别
工具 | 安装速度 | node_modules 结构 | 支持 monorepo | 特点 |
---|---|---|---|---|
npm | 普通 | 扁平 | 部分支持 | 官方默认,稳定性好 |
yarn | 快 | 扁平 | ✅ | 缓存机制好,lock 文件稳定 |
pnpm | 更快 | 严格嵌套 + 软链 | ✅ | 节省磁盘空间,速度极快,软链接 |
面试话术:在大多数现代项目中,推荐使用 pnpm 或 yarn 替代 npm,尤其是配合 monorepo 管理大型代码仓库时。
8. Monorepo 是什么?
定义:多个项目/包统一放在一个仓库中维护的方式(mono=单,repo=仓库)。
优势:
- 模块之间联动方便
- 依赖统一管理
- 适合组件库或多个产品线统一维护
工具:
pnpm workspaces
Lerna
Turborepo
面试话术:Monorepo 能简化大型项目协同开发、版本管理及构建发布过程,在中大型前端团队中很常见。
9. VueRouter 实现原理(手写版)
核心机制:监听 URL 变化(hash/history)→ 渲染对应组件
基本手写实现(Hash 模式):
const routes = {'/': '首页','/about': '关于页'
}function render() {const path = location.hash.slice(1) || '/'document.getElementById('view').innerText = routes[path] || '404'
}window.addEventListener('hashchange', render)
render()
关键点:
- 使用
location.hash
获取路由 - 页面中预留
<div id="view"></div>
容器渲染内容
面试话术:VueRouter 本质是监听 URL 变化,然后根据路由映射渲染对应视图,可通过自定义组件结合响应式完成 router-view 效果。
10. Tree Shaking 与按需加载
Tree Shaking 原理:ES Module 静态结构分析 + 标记未使用代码 + 删除
工具支持:Webpack、Rollup、Vite 都支持 Tree Shaking
按需加载组件库方式(如按需加载 Element Plus):
import { ElButton } from 'element-plus'
或使用插件:
// babel-plugin-import
{"libraryName": "element-plus","libraryDirectory": "es","style": true
}
面试话术:Tree Shaking 能有效减少产物体积,前提是使用 ESModule 且编译工具支持。按需加载组件库也是一种 Tree Shaking 的实际运用。
11. 打包流程与图片资源处理
整体打包流程(以 Webpack 为例):
- 解析入口文件(entry)
- 构建模块依赖图(import/require)
- 编译代码(Babel、TS、CSS loader)
- Tree shaking / 压缩优化
- 输出 bundle 到 dist 文件夹
图片处理:
- 小图(<8kb):转 base64 内联到 JS 中,减少请求数
- 大图:复制到 dist,生成 hash 文件名,自动替换路径
module.exports = {module: {rules: [{test: /\.png$/,type: 'asset',parser: { dataUrlCondition: { maxSize: 8 * 1024 } },}]}
}
面试话术:打包的核心是将源码模块化、标准化处理为浏览器可识别的 JS/CSS/HTML/图片资源,优化性能、缓存与部署流程。
12. 浏览器缓存机制
两类缓存:
- 强缓存(状态码 200 from cache):Expires、Cache-Control
- 协商缓存(状态码 304 Not Modified):Last-Modified、ETag
强缓存示例:
Cache-Control: max-age=31536000
协商缓存示例:
ETag: "abc123"
If-None-Match: "abc123"
面试话术:合理配置 HTTP 缓存头可显著提升网站性能与加载速度,需兼顾更新与命中率。
13. this 的指向、new 创建过程
this 取决于调用方式:
- 普通函数:window(或 undefined 严格模式)
- 对象调用:this 指向调用者
- bind/call/apply 修改 this
- 箭头函数:this 不变,取决于父作用域
new 做了哪些事?
- 创建空对象
- this 指向该对象
- 执行构造函数
- 返回对象(显式返回对象则替换)
示例:
function Person(name) {this.name = name
}
const p = new Person('Tom')
面试话术:this 是 JS 中最容易出错的机制,理解调用上下文尤为重要。new 是构造函数实例化对象的过程。
14. 原型链与类的区别
原型链定义:
每个对象都有 __proto__
,指向其构造函数的 prototype,最终形成一条链。
类的实现(ES6 class):
语法糖,本质仍是构造函数 + prototype 实现继承
区别总结:
- 类是语法层面结构
- 原型链是对象查找属性的方法机制
面试话术:理解原型链是理解继承、作用域、 instanceof 的关键,类是对原型的封装,便于组织代码结构。
15. Vue3 响应式原理
**Vue2 响应式缺陷:**基于 Object.defineProperty,数组无法监听新增属性
Vue3 使用 Proxy 实现响应式:
- 捕捉 get、set 操作
- 结合依赖收集与触发更新(effect)
示例核心代码:
const reactive = obj => new Proxy(obj, {get(target, key) {track(target, key) // 依赖收集return Reflect.get(target, key)},set(target, key, value) {const res = Reflect.set(target, key, value)trigger(target, key) // 触发更新return res}
})
面试话术:Vue3 相比 Vue2,在响应式系统更具灵活性和性能,Proxy 的优势在于可监听新增、删除、数组索引等所有操作。
16. 虚拟列表与 IntersectionObserver 实现懒加载
虚拟列表定义:只渲染可视区域的数据,提升长列表性能。
实现方式:
- 固定高度列表 + 滚动监听
- 滚动时计算渲染区间索引,动态替换 DOM
IntersectionObserver 实现图片懒加载:
const observer = new IntersectionObserver(entries => {entries.forEach(entry => {if (entry.isIntersecting) {const img = entry.targetimg.src = img.dataset.srcobserver.unobserve(img)}})
})document.querySelectorAll('img[data-src]').forEach(img => {observer.observe(img)
})
面试话术:虚拟列表提高了性能,避免一次性渲染大量 DOM。IntersectionObserver 是现代浏览器优化滚动监听的首选。
17. 发布订阅模式
定义:一种解耦通信机制,发布者发事件,订阅者监听响应。
手写实现:
class EventBus {constructor() {this.events = {}}on(event, fn) {(this.events[event] ||= []).push(fn)}emit(event, ...args) {this.events[event]?.forEach(fn => fn(...args))}
}
应用场景:
- 组件通信(兄弟组件)
- Vue 的 $emit / $on 本质
面试话术:发布订阅用于组件解耦或异步通知,是前端常用架构思想之一。
18. Composition API 与 Options API
特性 | Options API | Composition API |
---|---|---|
组织方式 | 分散(data、methods) | 聚合(setup 函数中) |
复用逻辑 | Mixin | 可组合函数(Composable) |
类型推导支持 | 较弱 | TypeScript 更友好 |
面试话术:Composition API 更适合复杂逻辑组合与 TS 项目,Options API 更适合初学者。Vue3 推荐使用 Composition。
19. computed 与 watch 区别
特性 | computed | watch |
---|---|---|
概念 | 派生状态,自动缓存 | 监听响应式数据,手动触发回调 |
使用场景 | 模板渲染的衍生值 | 监听异步操作、副作用处理 |
返回值 | 返回值 | 无返回值 |
面试话术:computed 是依赖驱动、自动缓存的计算属性,而 watch 更像是监听器,用于观察数据变化并做副作用操作。
20. React18 特性
核心变化:
- 自动批处理(无需手动包裹 setTimeout)
- 并发特性(startTransition)
- useId(防止 SSR 问题)
新 API 示例:
import { startTransition } from 'react'startTransition(() => {setValue('new')
})
面试话术:React18 最大亮点是并发渲染与自动批处理机制,大幅提升响应能力与开发体验。
21. let / const / var 区别
特性 | var | let | const |
---|---|---|---|
作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
提升 | 有(值为 undefined) | 有(不初始化) | 有(不初始化) |
重复声明 | 允许 | 报错 | 报错 |
可修改 | 是 | 是 | 否(基本类型) |
面试话术:let/const 是 ES6 提供的更安全、作用域明确的声明方式,建议默认使用 const。var 已逐步淘汰。
22. Vuex 与 Pinia 区别
特性 | Vuex | Pinia |
---|---|---|
API 风格 | module + mutations/actions | setup 语法,函数式组织 |
类型支持 | 差 | 优秀(TS 支持一流) |
使用成本 | 多 | 少(无需冗余代码) |
Devtools | Vue Devtools | 支持更好 |
面试话术:Pinia 是 Vue3 官方推荐状态库,简洁、支持 Composition API、类型推导强,是 Vuex 的未来替代品。
23. HTTP 与 HTTPS 区别
项目 | HTTP | HTTPS |
---|---|---|
安全性 | 明文传输,易被窃听 | 加密传输(SSL/TLS) |
端口 | 80 | 443 |
证书要求 | 无 | 需 CA 签发的数字证书 |
面试话术:HTTPS 是 HTTP + SSL/TLS 加密,防止中间人攻击与数据泄露,现代站点必备。
24. HTTP 状态码分类
- 1xx:信息(如 101 Switching Protocols)
- 2xx:成功(如 200 OK,204 No Content)
- 3xx:重定向(如 301 永久重定向,302 临时重定向)
- 4xx:客户端错误(如 404 Not Found,403 Forbidden)
- 5xx:服务端错误(如 500 内部错误,502 Bad Gateway)
面试话术:重点掌握 200、301、302、304、403、404、500、503 等状态含义。
25. HTTP/2 特性
- 多路复用(一个连接并发多个请求)
- 头部压缩(减少重复 header 体积)
- Server Push(服务端主动推送资源)
- 二进制协议(比文本更快)
面试话术:HTTP/2 在性能上是 HTTP1 的升级,极大减少了连接数量与传输体积。
26. TCP 三次握手
过程说明:
- 客户端:发送 SYN
- 服务端:收到后返回 SYN + ACK
- 客户端:收到后回复 ACK,连接建立
为什么三次?
- 防止已失效的连接请求重复到达造成错误
面试话术:三次握手确保双方具备收发能力并保持同步,防止半连接攻击。
27. HTTP 缓存控制方式
强缓存:
Expires
(绝对时间)Cache-Control: max-age=3600
协商缓存:
Last-Modified + If-Modified-Since
ETag + If-None-Match
流程图:
- 有强缓存 → 直接使用
- 无强缓存 → 发请求,命中协商缓存返回 304
面试话术:合理缓存配置可极大提升前端性能和用户体验。
28. DNS 使用的协议
DNS 查询过程涉及多个协议:
- 应用层协议:DNS
- 传输层协议:UDP(默认)或 TCP(大于 512 字节)
- 网络层协议:IP
面试话术:DNS 查询是 Web 加载的第一步,通常使用 UDP 提高效率,大包或可靠性要求则转为 TCP。
29. 应用层协议
常见应用层协议包括:
- HTTP / HTTPS
- FTP / SFTP
- SMTP / POP3 / IMAP
- WebSocket
- DNS
面试话术:OSI 七层模型最顶层是应用层,主要面向用户交互与数据格式处理。
30. UDP 协议
特点:
- 面向无连接
- 不保证顺序、不保证可靠
- 发送快、开销小
典型应用:
- 视频直播
- DNS 查询
- 实时游戏
与 TCP 区别:
- TCP 可靠但慢,UDP 快但不可靠
面试话术:UDP 常用于对时效性要求高、能容忍少量丢包的场景。