浅拷贝深拷贝和个人一些新理解(非普遍的理解)
预备知识
引用数据类型
- Object(在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象等等)
基本数据类型
Number
、String
、Boolean
、Null
、Undefined
、Symbol
文章参考了牛客网CodeSheep
赋值 vs 浅拷贝 vs 深拷贝
赋值(不能算是拷贝,因为拷贝的仅仅只是引用关系,并没有生成新的实际对象)
很常见的一种
1 | var a = 10; |
浅拷贝
一个误区
很多人说var objOrigin = {name:'李白'}; var objAfter = objOrigin; 是浅拷贝,严格来说是错误的!
1 | // 严格来说是错误的! |
- 这里使用了展开运算符(扩展运算符),官方解释是浅拷贝
如果按照之前有些人的说法,下面这个是浅拷贝
1
var objOrigin = {name:'李白'}; var objAfter = objOrigin;
那么
mdnWebDocs
当中的展开运算符(扩展运算符)可以实现浅拷贝,那么按道理来说这个所谓的浅拷贝,修改了浅拷贝后的对象不会导致原来的对象改变吧?那为什么修改后会发生改变?1
2
3
4
5
6
7
8
9
10
11
12
13//var objOrigin = {name:'李白'}; var objAfter = obj;是浅拷贝
var objOrigin = {name:'李白'};
var objAfter = objOrigin;
//修改拷贝后的对象当中的name(name为基本数据类型)
objAfter.name="李黑";
//输出为 {name: '李黑'}
console.log(objAfter);
//输出为 {name: '李黑'}
console.log(objOrigin);所以我觉得,赋值就是赋值,不是什么浅拷贝和深拷贝!不然你说
var objAfter = objOrigin
就是浅拷贝,那么为什么修改了objAfter
后objOrigin
也会变化?并且修改的还是对象当中的基本数据类型!(因为后面深拷贝还设计到对象当中的数据类型)
真正的浅拷贝
- 比如我们试图通过studen1实例,拷贝得到student2,如果是浅拷贝这种方式,大致模型可以示意成如下所示的样子:
- 很明显,值类型的字段会复制一份,而引用类型的字段拷贝的仅仅是引用地址,而该引用地址指向的实际对象空间其实只有一份。
- 所以浅拷贝是什么,就是赋值引用数据类型当中存储的基本数据类型,而引用数据类型当中的引用数据类型(比如数组当中嵌套对象的情况),仅仅只是将地址赋值给了另外一个对象!
深拷贝
- 深拷贝相较于上面所示的浅拷贝,除了值类型字段会复制一份,引用类型字段所指向的对象,会在内存中也创建一个副本,就像这个样子:
- 所以深拷贝是什么,就是不管对象当中嵌套了多少层引用数据类型还是基本数据类型,都建立一个新的给自己
一些常用的深浅拷贝方法
浅拷贝
展开运算符(扩展运算符)
- 可以看到,除了基本数据类型拷贝了,里面的引用数据类型并未进行拷贝,修改一个拷贝后的引用数据类型会影响原来的
1 | var objOrigin = { |
Object.assign
- 可以看到,除了基本数据类型拷贝了,里面的引用数据类型并未进行拷贝,修改一个拷贝后的引用数据类型会影响原来的
1 | var objOrigin = { |
深拷贝
JSON.stringify和JSON.parseInt实现
- 可以看到,除了基本数据类型拷贝了,里面的引用数据类型也进行了拷贝,修改一个拷贝后的引用数据类型不影响原来的
1 | var objOrigin = { |
lodash当中的cloneDeep
1 | var objects = [{ 'a': 1 }, { 'b': 2 }]; |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 梦洁小站-属于你我的小天地!
评论