浅拷贝
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。
属性值是基本类型:拷贝基本类型的值;
属性是引用类型: 拷贝引用类型的内存地址;
特点: 其中一个对象改变了引用类型的属性,会影响另一个对象。
深拷贝
将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。
赋值
把一个对象赋值给一个新变量的时候,赋的是该对象在栈中的地址,而不是堆中的数据。即两对象指的是同一个堆存储空间,无论谁发生变化,另一个会跟着联动。
浅拷贝实现代码
function shallowCopy(obj){
let res = {};
for(let i in obj) {
if(obj.hasOwnProperty(i)){
res[i] = obj[i]
}
}
return res;
}
深拷贝实现代码
function deepCopy(obj){
let res=[];
if(obj ===null) return obj; //typeof null = 'object'
if(obj instanceof Date) return new Date(obj);
if(obj instanceof RegExp) return new RegExp(obj);
if(typeof obj !== 'object') return obj;
for(let i in obj) {
if(obj.hasOwnProperty(i)){
res[i] = deepCopy(obj[i])
}
}
return target;
}
浅拷贝现有实现方式
- Object.assign()
- lodash: _.clone
- …运算符
- Array.prototype.concat
- Array.prototype.slice
深拷贝现有实现方式
- JSON.parse(JSON.stringify())
- lodash: deepClone
- Jquery:extend()
- 手动递归
tips
JSON.parse(JSON.stringify())拷贝正则、函数不准确。
let obj = {
exp: new RegExp('\\w+'),
function(){}
}
let objC = JSON.parse(JSON.stringify(obj));
//obj:{ exp:/\w+/, function: f() }
//objC: { exp:{} }