2026-04-22 06:23:44
在JavaScript中,实现对象的深拷贝可通过以下方法完成,每种方法各有适用场景和局限性:
1. 基本递归方法适用于简单对象(无循环引用、无特殊类型),通过递归遍历对象属性实现拷贝。
function deepCopy(obj) { if (typeof obj !== 'object' || obj === null) { return obj; } let copy = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { copy[key] = deepCopy(obj[key]); } } return copy;}性能问题:递归深度过大可能导致栈溢出。
循环引用:对象属性相互引用时会无限递归。
特殊类型:无法处理Date、RegExp、Map、Set等对象。
利用JSON.parse(JSON.stringify(obj))快速实现深拷贝,但存在严格限制。
let obj = { a: 1, b: { c: 2 } };let copy = JSON.parse(JSON.stringify(obj));数据丢失:忽略函数、undefined、Symbol属性。
循环引用:直接报错(TypeError: Converting circular structure to JSON)。
特殊类型:Date转为字符串,RegExp变为空对象。
通过WeakMap跟踪已拷贝对象,解决循环引用问题,并支持特殊类型处理。
function advancedDeepCopy(obj, weakMap = new WeakMap()) { if (obj === null || typeof obj !== 'object') { return obj; } if (weakMap.has(obj)) { return weakMap.get(obj); } let copy; if (Array.isArray(obj)) { copy = []; } else if (obj instanceof Date) { copy = new Date(obj.getTime()); } else if (obj instanceof RegExp) { copy = new RegExp(obj); } else { copy = Object.create(Object.getPrototypeOf(obj)); } weakMap.set(obj, copy); for (let key in obj) { if (obj.hasOwnProperty(key)) { copy[key] = advancedDeepCopy(obj[key], weakMap); } } return copy;}循环引用:通过WeakMap避免无限递归。
特殊类型:支持Date、RegExp及自定义类实例。
性能开销:大型对象拷贝可能较慢。
自定义类型:需额外处理Map、Set等复杂类型。
推荐使用成熟库(如Lodash的_.cloneDeep)简化实现,兼顾性能与可靠性。
const _ = require('lodash');let obj = { a: 1, b: { c: new Date() } };let copy = _.cloneDeep(obj);全面支持:处理循环引用、特殊类型及自定义类。
性能优化:内部实现经过优化,适合生产环境。
通过合理选择方法,可平衡开发效率与运行性能,满足不同场景需求。