这是我为准备前端开发工程师面试整理的第五天每日三题练习,涵盖深拷贝、Vue 响应式原理、WebSocket IM 聊天系统设计等核心知识点,适合巩固基础与提升实战能力。
✅ 题目 1:面试高频:如何实现深拷贝?有哪些常见误区?
📘 解析:
深拷贝是创建一个对象的完全副本,使得修改副本不会影响原对象。常见实现方式及注意事项如下:
✅ 方法一:JSON 方式(适合简单数据结构)
const deepCopy = obj => JSON.parse(JSON.stringify(obj));
优点: 简单快速。
缺点: 无法处理函数、undefined、Symbol、循环引用等。
✅ 方法二:递归 + WeakMap 防循环引用
function deepClone(obj, hash = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj;
if (hash.has(obj)) return hash.get(obj);
const clone = Array.isArray(obj) ? [] : {};
hash.set(obj, clone);
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], hash);
}
}
return clone;
}
优点: 支持嵌套对象、数组、循环引用。
缺点: 不支持函数、Symbol 拷贝。
✅ 方法三:Lodash cloneDeep(企业项目中常用)
import cloneDeep from 'lodash/cloneDeep';
const copy = cloneDeep(original);
优点: 稳定、兼容性强。
⚠️ 常见误区:
- 认为 JSON 方法是万能的深拷贝方式;
- 忽略循环引用可能导致栈溢出;
- 复制后副本中仍有原对象引用。
🧠 记忆脑图建议:
- JSON.stringify / parse:简单但功能有限
- 递归 + WeakMap:通用实现,解决循环引用
- Lodash:生产环境推荐
- 注意函数、Symbol、Date、RegExp 等拷贝边界问题
✅ 题目 2:Vue 的响应式原理详解(Vue 2 vs Vue 3)
📘 解析:
Vue 的核心之一是响应式系统,帮助我们自动追踪依赖并在数据变化时更新视图。
Vue 2 原理(基于 Object.defineProperty):
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log('读取:', key);
return val;
},
set(newVal) {
console.log('更新:', key);
val = newVal;
// 触发更新逻辑...
}
});
}
const data = { name: 'Vue2' };
defineReactive(data, 'name', data.name);
data.name = 'New Name';
优点:实现简单;
缺点:无法监听新增/删除属性,无法监听数组索引变化。
Vue 3 原理(基于 Proxy):
const reactive = (target) => {
return new Proxy(target, {
get(obj, key) {
console.log('读取', key);
return obj[key];
},
set(obj, key, value) {
console.log('设置', key);
obj[key] = value;
return true;
}
});
};
const state = reactive({ count: 0 });
state.count++;
优点:天然支持数组、新增/删除属性;更灵活、性能更优。
🧠 记忆脑图建议:
- Vue 2 使用 defineProperty
- Vue 3 使用 Proxy
- 优劣对比:性能、监听能力、扩展性
✅ 题目 3:系统设计题:使用 WebSocket 实现高性能 IM 聊天系统
📘 解析:
WebSocket 提供了浏览器与服务器之间的全双工通信,适合构建高实时性的聊天系统。
关键模块:
- 用户连接管理
- 消息实时推送
- 心跳检测 / 重连机制
- 消息存储与离线补发
✅ 前端代码示例:
// 建立连接
const socket = new WebSocket('ws://localhost:3000');
// 接收消息
socket.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('收到消息:', data);
};
// 发送消息
function sendMessage(msg) {
socket.send(JSON.stringify({ type: 'chat', content: msg }));
}
// 心跳机制
setInterval(() => {
socket.send(JSON.stringify({ type: 'ping' }));
}, 30000);
后端可使用 Node.js + ws 模块 或使用 Socket.IO 实现。
🧠 记忆脑图建议:
- WebSocket 生命周期:open → message → close/error
- IM 模块设计:连接池、心跳包、断线重连
- 结合前端发送/接收机制
📅 明日预告 - Day 6
这是我为准备前端开发工程师面试整理的第六天每日三题练习,涵盖深拷贝边界处理、Vue Proxy 陷阱、高性能聊天系统服务端设计等内容,帮助你在实战中脱颖而出:
- 浏览器缓存机制详解与实际应用
- React 性能优化:useMemo 与 useCallback 的正确使用
- 前端系统设计实战:如何搭建通用的前端异常监控系统?