2026-07-30 14:33:56
深拷贝是指创建一个新对象,并递归复制原对象的所有属性,包括嵌套对象和引用类型的属性,确保新对象与原对象完全独立,修改新对象不会影响原对象。
浅拷贝则只复制对象的第一层属性,若属性值为引用类型(如对象、数组),则复制的是引用地址而非实际值,导致新旧对象共享同一引用,修改会影响原对象。
深拷贝与浅拷贝的核心区别浅拷贝:仅复制第一层属性,嵌套引用类型仍共享。
深拷贝:递归复制所有层级,完全独立。
浅拷贝:修改嵌套引用类型会影响原对象。
深拷贝:任何修改均不影响原对象。
以下是一个完整的深拷贝函数实现,处理了多种数据类型(如Date、RegExp、Symbol等):
function cloneDeep(obj) { // 处理基本类型和null 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 (obj instanceof Map) return new Map(Array.from(obj, ([key, val]) => [key, cloneDeep(val)])); if (obj instanceof Set) return new Set(Array.from(obj, val => cloneDeep(val))); // 处理Symbol属性 if (typeof obj === 'symbol') return Symbol(obj.description); // 创建新对象(保留原型链) const cloneObj = new obj.constructor(); // 处理对象属性(包括Symbol属性) const allKeys = Reflect.ownKeys(obj); // 获取所有属性键(包括Symbol) for (const key of allKeys) { cloneObj[key] = cloneDeep(obj[key]); // 递归拷贝 } return cloneObj;}代码示例与对比测试对象let obj = { a: 100, b: [10, 20, 30], c: { x: 10 }, d: new Date(), f: undefined, g: /s+/g, fn: function() {}, symbol: Symbol('Symbol'), [Symbol('key')]: 'symbolValue'};拷贝结果对比JSON.parse(JSON.stringify(obj)):
缺点:无法处理Date、RegExp、undefined、函数、Symbol等。
结果:
{ a: 100, b: [10, 20, 30], c: { x: 10 }, d: '2023-10-01T00:00:00.000Z', // Date转为字符串 g: {} // RegExp丢失}自定义cloneDeep函数:
优点:完整保留所有数据类型和结构。
结果:
{ a: 100, b: [10, 20, 30], c: { x: 10 }, d: Date对象, // 保留Date实例 f: undefined, g: /s+/g, // 保留RegExp fn: [Function: fn], symbol: Symbol(Symbol), [Symbol(key)]: 'symbolValue' // 包含Symbol属性}Date/RegExp:直接创建新实例。
Map/Set:遍历并递归拷贝值。
Symbol:通过Symbol(description)创建新Symbol。
通过以上实现,可安全处理绝大多数数据类型的深拷贝需求。