对象的深拷贝与浅拷贝
1、对象的引用
1 |
|
上述代码仅仅使用了”=”赋值,这种表达方式为引用对象,不属于浅拷贝,两个对象所用内存地址是相同的,所以判断结果为true。
2、浅拷贝
将对象进行浅拷贝有诸多方式:
1)遍历赋值
1 |
|
上述代码这种方式,遍历了对象A的每个属性,并将其赋值给对象B,看起来像是在内存中开辟了新的空间给对象B,并且判断全等时,两个对象也是不相等的,很容易被误解成就是深拷贝,但我们接着看:
1 |
|
从上面代码可以看出,虽然两个对象的引用地址不同,但是修改了对象A中类型为对象的属性值,对象B的相应的属性值也发生了变化。不止是对象类型,其他复合类型如数组、函数,都只是拷贝了引用地址,而不是这个值的副本。
2)对象展开运算符
1 |
|
上述代码是将对象A的所有属性搜集整理好之后赋值给对象B,本质上与Object.assign相同。两个对象的引用地址不同。
1 |
|
上述代码表示,对象展开运算符的拷贝方式只能拷贝对象自身的属性,不能拷贝其原型对象上的属性。
3)Object.assign
1 |
|
上述代码是将对象A克隆一份,赋值给对象B,两个对象的引用地址不同。
3、深拷贝
1)JSON.stringify和JSON.parse
1 |
|
上述代码是一个深拷贝的过程,可以看到,它的效果是将对象中类型为对象的属性值也重新开辟空间,让两个对象做到了完完全全的不相等,但是,这个做法有一个弊端,就是只支持纯数据JSON的深度拷贝。看下面的例子:
1 |
|
我们会发现,这种拷贝方式,会忽略类型为function、undefined、和null的属性值,并且对时间对象支持的也不友好。
而且,这种方式,只能拷贝对象自身的属性,不能拷贝对象继承的属性:
2)其它靠谱方式
1 |
|
参考文献: 王玉略的个人网站