深拷贝与浅拷贝

深拷贝与浅拷贝 浅拷贝Shallow Copy只复制第一层属性。若属性为‌基本类型‌如number、string则复制值若属性为‌引用类型‌如对象、数组则‌仅复制引用地址‌新旧对象共享该嵌套数据如果修改嵌套属性会影响原对象浅拷贝的方法对象1.Object.assign({}, obj)。2.扩展运算符{ ...obj }var a { count: 1, deep: { count: 2 } } var b {...a};//扩展运算符 var c Object.assign({}, a) a.deep.count 5 console.log(b.deep.count) // 5 console.log(c.deep.count) // 5数组arr.slice()截取子数组、浅拷贝支持负索引从末尾算起arr.concat()拼接多个数组/值、浅拷贝可直接传入非数组元素自动展开Array.from(arr)类数组转数组、带映射的转换可传入映射函数支持thisArgconst arr [1, 2, 3, 4, 5]; const arr2 arr.slice(); const arr3 arr.concat(); const arr4 Array.from(arr); arr.push(6); console.log(arr);// [1, 2, 3, 4, 5, 6] console.log(arr2); // [1, 2, 3, 4, 5]原数组不变 console.log(arr3); // [1, 2, 3, 4, 5]原数组不变 console.log(arr4); // [1, 2, 3, 4, 5]原数组不变深拷贝Deep Copy递归复制所有层级‌包括嵌套对象和数组新对象与原对象‌完全独立‌互不影响修改副本不会影响原对象深拷贝的方法1.JSON.parse(JSON.stringify(obj))简单易用但‌无法处理函数、undefined、Symbol、Date、RegExp、循环引用等。使用JSON.stringify和JSON.parse方法时会丢失对象的原型链、函数以及undefined值var a { count: 1, deep: { count: 2 } } var b JSON.parse(JSON.stringify(a)); a.deep.count 5; console.log(b.deep.count) // 22.手写递归这是最常用的方法之一可以处理大部分数据结构但需注意处理循环引用。递归方法需要考虑循环引用的问题通常通过使用WeakMap来记录已拷贝过的对象来解决function deepCloneWithCycle(obj, map new WeakMap()) { // 基本类型或 null直接返回 if (typeof obj ! object || obj null) { return obj; } // 如果已拷贝过直接返回缓存结果 if (map.has(obj)) { return map.get(obj); } let result; if (obj instanceof Date) { result new Date(obj); } else if (obj instanceof RegExp) { result new RegExp(obj.source, obj.flags); //obj.source返回该正则表达式的‌模式字符串‌即正则内容本身不包括斜杠和标志 //obj.flags返回该正则表达式使用的‌标志字符串‌如 g、i、m 等或组合如 gi } else if (Array.isArray(obj)) { result []; for (let i 0; i obj.length; i) { result[i] deepCloneWithCycle(obj[i], map); } } else { result {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { result[key] deepCloneWithCycle(obj[key], map); } } } // 缓存当前对象的拷贝 map.set(obj, result); return result; } const a { date: new Date(), deep: { count: 2 } }; const b deepCloneWithCycle(a); a.deep.count 5; console.log(b.deep.count) // 23.structuredClone()推荐用于现代环境const a { date: new Date(), deep: { count: 2 } }; const b structuredClone(a); a.deep.count 5; console.log(b.deep.count) // 24.利用第三方库如lodash的_.cloneDeep