1.浅拷贝
以赋值的形式拷⻉引⽤对象,仍指向同⼀个地址,修改时原对象也会受到影响
- Object.assign是ES6的新函数。Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。但是 Object.assign() 进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。
- 展开运算符(...) var obj2 = { ...obj1 }
2.深拷贝
深拷贝会开辟新的栈,两个对象对应两个不同的地址,修改对象A的属性,并不会影响到对象B
2.1JSON.parse(JSON.stringfy(obj))
- 性能最快
- 复制具有循环引用的对象时会报错
- 当值为函数、undefined、或symbol时,⽆法拷⻉
2.2手写深拷贝
/**
* 深拷⻉
*@param {Object} obj 要拷⻉的对象
*@param {Map} map ⽤于存储循环引⽤对象的地址
**/
function deepClone(obj={},map=new Map()){
if(typeof obj !== 'object'){
return obj;
}
if(map.get(obj)){
return map.get(obj);
}
let res={}; // 初始化返回结果
// 加 || 的原因是为了防⽌ Array 的 prototype 被重写
if(obj instanceof Array ||
Object.prototype.toString.call(obj) === '[object Array]'){
res=[];
}
map.set(obj,res); // 防⽌循环引⽤
for(let key in obj){
// 保证 key 不是原型属性
if(obj.hasOwnProperty(key)){
// 递归调⽤
res[key]=deepClone(obj,map);
}
}
// 返回结果
return res;
}