深拷贝和浅拷贝
Posted hellocindy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深拷贝和浅拷贝相关的知识,希望对你有一定的参考价值。
1、浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用(栈中的地址)
2、深拷贝拷贝多层,每一级别的数据都会拷贝
3、Object.assign(target,...source)(ES6新增的方法可以浅拷贝)
一、浅拷贝
1 var obj = {
2 name: ‘Cindy‘,
3 age: 16,
4 msg: {
5 sex: ‘female‘
6 }
7 }
8 // 浅拷贝方法一
9 var o = {};
10 for (var k in obj) {
11 o[k] = obj[k];
12 }
13 // Object.assign()浅拷贝方法二
14 // Object.assign(o, obj);
15 console.log(obj);
16 console.log(o);
17 obj.age = 29;
18 console.log(obj);
19 console.log(o);
20 obj.msg.sex = ‘male‘;
21 console.log(obj);
22 console.log(o);
浅拷贝只是把msg的地址拷贝给了o,这个地址指向的还是原来obj里存的数据,也就是说o里面的msg和obj里面的msg指向的是同一个地址,所以此时修改了obj里面的msg,也会影响到o里面的msg,这里o和obj里面的msg都是sex为male,因为它们指向的是同一个地址,所以浅拷贝如果遇到了这种对象级别更深层次的数据的话只是拷贝了地址。
而且可以看出,修改了obj的age,但是o里面的age仍为16,并没有改变,只有一层的话是不会出现这种多层拷贝地址的问题的。
二、深拷贝
1 var obj = {
2 name: ‘Cindy‘,
3 age: 16,
4 msg: {
5 sex: ‘female‘
6 },
7 hobby: [‘swim‘, ‘basketball‘]
8 }
9 var o = {};
10
11 function deepCopy(newobj, oldobj) {
12 for (var k in oldobj) {
13 var item = oldobj[k];
14 if (oldobj[k] instanceof Array) {
15 newobj[k] = [];
16 deepCopy(newobj[k], item);
17 } else if (oldobj instanceof Object) {
18 newobj[k] = {};
19 deepCopy(newobj[k], item);
20 } else {
21 newobj[k] = oldobj[k];
22 }
23 }
24 }
25 deepCopy(o, obj);
26 console.log(obj);
27 console.log(o);
28
29 o.msg.sex = ‘male‘;
30 console.log(obj);
31 console.log(o);
这里改变o.msg.sex为male,o里面的数据也不会跟着变,所以实现了深拷贝。另外要注意的是,这个实现深拷贝的函数把数组放在做上面判断是因为数组也属于object,如果把Object放在最上面,那么它就会把数组当做对象,不会再执行判断数组的情况了。
1 var obj = {
2 name: ‘Cindy‘,
3 age: 16,
4 msg: {
5 sex: ‘female‘
6 },
7 hobby: [‘swim‘, ‘basketball‘]
8 }
9 var o = {};
10
11 o = JSON.parse(JSON.stringify(obj));
12 console.log(obj);
13 console.log(o);
14
15 o.msg.sex = ‘male‘;
16 console.log(obj);
17 console.log(o);
另外通过JSON.parse(JSON.stringify(object))也可以实现深拷贝,原理是JSON对象中的stringify可以把js对象序列化为一个JSON字符串,parse可以把JSON字符串反序列化为一个js对象。但这个方法不能拷贝函数,不能解决循环引用的对象,会忽略undefined和symbol。
以上是关于深拷贝和浅拷贝的主要内容,如果未能解决你的问题,请参考以下文章