2019-01-18 JavaScript 浅拷贝和深拷贝

2019-01-18  本文已影响0人  KingAmo

基础知识

javascript中对象基本类型的传值方式是不同的:
基本类型值传递对象引用传递

举个例子:

对象:
const obj1 = {a:1};
const obj2 = obj1;
obj2.a = 2;
console.log(obj1.a); // 2
obj1 === obj2 // true (浅比较)

由于对象的传值方式是引用传递,obj1和obj2实际上是指向同一个对象的引用(内存上的同一个地址),造成了修改obj1的a属性的值, obj2的a属性的值也被改了。

基本类型:
var a = 1;
var b = a;
b = 2;
console.log(a); //1
console.log(b); //2

由于基本类型的传值方式是值传递,b = a的这步操作,并没有把a和b指向同一块地址,从而修改b的值,a的值没有修改。

浅拷贝和深拷贝

由于对象的引用传递的传值方式,导致拷贝出来的对象和原对象是同一个引用,这就是所谓的浅拷贝

浅拷贝只复制指向这个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。

深拷贝会另外创造一个对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

解构赋值

const obj1 = {x:{a:1}, y:{b:2}}
const obj2 = {...obj1}
obj1 === obj2 // false
obj1.x === obj2.x //true
obj1.y === obj2.y //true
obj1.x = 1; 
obj1 // {x:1,y:{b:2}}
obj2 //{x:{a:1},y:{b:2}}
// obj2.x并没有改变,因为一层时是深拷贝,相当于,生成一个新对象,包含的子对象是旧的对象的引用
obj1.y.b=3
obj1 // {x:1, y:{b:3}}
obj2 // {x: {a:1}, y:{b:3}}

解构赋值也是浅拷贝,Object.assign()也是是浅拷贝,但是他们都可以处理一层的深拷贝
如果对象只有一层,那么这两种方法就可以实现浅拷贝,但是如果对象深度超过一层就不行了。

深拷贝

实现深拷贝需要递归拷贝,一层一层的把对象拷贝出来,JavaScript没有提供深拷贝的api。
深拷贝实现的库:
loadsh:_.cloneDeep()
jQuery: $.extend()

上一篇 下一篇

猜你喜欢

热点阅读