1、了解浅拷贝和深拷贝
javascript的数据类型,这里我就不讲了,我们直接进入主题。
深拷贝和浅拷贝都只是针对Object、Arary这类复杂的对象。
解释1:浅拷贝只复制了对象的一层属性,不会复制对象里面为引用类型的数据,所以当改变了引用类型的数据时,会改变源对象。而深拷贝是开辟了一个新内存,递归复制了对象的引用,直到子对象都为基本类型,两个对象对应两个不同的地址,因此改变新对象时不会改变源对象。
解释2:浅拷贝只复制了对象的指针,而不复制内存,复制后新旧对象共享同一个内存,当修改了新对象后,源对象也会发生变化。而深拷贝是创建了一个一模一样的对象,两个对象不共享同一个内存,所以当新对象不会影响到源对象。
解释3:基本数据类型的键值都储存在栈内存里,引用类型的键存在栈内存里,值存在堆内存里,但是栈内存中会存一个引用地址指向堆内存里的值。浅拷贝就是只复制了栈内存里的键以及引用地址,而并非堆里面的值,所以当我们改变新对象时,旧对象也会发生改变。而深拷贝会在堆内存中开辟一个内存专们存放新对象的值就可以达到深拷贝的效果了。
解释4:图示
2、浅拷贝实现
- fon in 循环遍历第一层
let obj1 = {
a: 1,
b: 2,
c: 3
}
function copy(obj){
let obj2 = Array.isArray(obj) ? [] : {};
for(let i in obj) {
obj2[i] = obj[i];
}
return obj2;
}
let copy_obj = copy(obj1);
console.log(copy_obj);
console.log(obj1);
- es6中的Object.assign() Object.assign()方法是用于合并对象,将源对象所有的可枚举属性赋值到目标对象。第一个参数是目标对象,后面的参数都为源对象。
let obj = {
a: 1,
b: 2,
c: 3
}
let copy_obj = Object.assign({},obj);
console.log(copy_obj);
- 直接用=赋值
let a = {a:1,b:2,c:3};
let b = a;
3、深拷贝实现
- 循环递归遍历对象的每一个层级的所有属性(代码较多,不多赘述)
- JSON对象的parse和sgrtingify方法。
let obj = {a:1,b:2,c:3};
let b = JSON.parse(JSON.stringify(obj));
- jQuery的$.extend()
let arr = [1,2,3,4]
let newArr = $.extend(true, [], arr); // true为深拷贝,false为浅拷贝
还有其他的方法也可以实现深拷贝,这里不多做赘述。
记录只为更好地学习。谢谢大家。