1.使用JSON编解码的方式
这种方式是最简单的,不需要额外的依赖,但是也有一定的局限性。如无法处理循环引用的情况、Symbol类型等。
function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
let obj = { a: 1, b: { c: 2 } };
let copyObj = deepCopy(obj);
console.log(copyObj); // { a: 1, b: { c: 2 } }
obj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 3 } }
console.log(copyObj); // { a: 1, b: { c: 2 } } // 深拷贝,原对象改变不影响副本
2.使用第三方库
使用lodash的_.cloneDeep方法,它能处理更多的边缘情况.
2.1安装依赖
npm install lodash --save
2.2使用方式
import _ from 'lodash';
let obj = { a: 1, b: { c: 2 } };
let copyObj = _.cloneDeep(obj);
补充
除了上面两种方式,也可以自己手写的一个具有深拷贝复制对象的函数,但是不推荐,推荐使用已有的轮子。因为自己在手写轮子的时候可能会有考虑不周全的地方,导致生产环境出现bug或性能的问题。
下面是一段能实现深拷贝的手写代码,
function deepClone(obj, hash = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj;
if (hash.has(obj)) return hash.get(obj);
let Constructor = obj.constructor;
let newObj = new Constructor();
hash.set(obj, newObj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key], hash);
}
}
return newObj;
}
let obj = { a: 1, b: { c: 2, d: [3, { e: 4 }] } };
let copyObj = deepClone(obj);
console.log(copyObj); // 完整的深拷贝副本
什么是深拷贝?
深拷贝其实就是真正的复制。
在编程语言中,数据类型通常分为两种,基本数据类型和引用类型。基本数据类型的复制,都是真正的复制。也就是如果一个变量是整型,它的值是2,此时将它赋值给另一个变量时,另一个变量得到的就是值2。但是如果一个变量是引用类型,向另一个变量赋值时,另一个变量得到的是当前变量的地址,而不是地址中具体的数据。
深拷贝就是为了实现对引用类型变量赋值时,把引用类型的具体值传给目标变量,而不是地址。