数组和对象的深拷贝

Posted ljwsyt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组和对象的深拷贝相关的知识,希望对你有一定的参考价值。

在实际开发中,如果遇到稍微复杂一点的逻辑,经常会遇到要复制对象或数组的场景。而在复制之后,我们会发现改了副本,原对象或数组的数据也相应改变了。这就是深拷贝的问题。

其原理涉及到内存,简单来说,我们的浅拷贝就是新建一个变量,指向目标变量,而不占用新的内存,所有一旦改变,就是直接改变的内存中的值,所以原来的值也改变了。

深拷贝就是,启用新的内存,所以修改新的值,将不影响旧的值。

 

会产生新内存的一些常用公共方法:

concat,slice

比如,var new_arr = arr.concat();var new_arr = arr.slice()

 

原本以为这样就可以一劳永逸,直到遇到一个无限嵌套循环的数组的场景。

技术分享图片

结构如上。我们使用上边两个方法进行深拷贝之后,发现,改动一级不会影响原数据,但是改动了内部二级数据之后,原数据就变了。

 

解决办法:

1.对象-字符-对象转化,适用于对象和数组,不适用于方法

var new_arr = JSON.parse(JSON.stringify(arr))

 

2.递归深拷贝

代码 :

 1 var deepCopy = function(obj) {
 2   // 只拷贝对象
 3   if (typeof obj !== ‘object‘) return;
 4   // 根据obj的类型判断是新建一个数组还是一个对象
 5   var newObj = obj instanceof Array ? [] : {};
 6   for (var key in obj) {
 7     // 遍历obj,并且判断是obj的属性才拷贝
 8     if (obj.hasOwnProperty(key)) {
 9       // 判断属性值的类型,如果是对象递归调用深拷贝
10       newObj[key] = typeof obj[key] === ‘object‘ ? deepCopy(obj[key]) : obj[key];
11     }
12   }
13   return newObj;
14 }

附封装的浅拷贝方法:

 1 var shallowCopy = function (obj) {
 2   // 只拷贝对象
 3   if (typeof obj !== ‘object‘) return;
 4   // 根据obj的类型判断是新建一个数组还是一个对象
 5   var newObj = obj instanceof Array ? [] : {};
 6   // 遍历obj,并且判断是obj的属性才拷贝
 7   for (var key in obj) {
 8     if (obj.hasOwnProperty(key)) {
 9       newObj[key] = obj[key];
10     }
11   }
12   return newObj;
13 }

 

以上是关于数组和对象的深拷贝的主要内容,如果未能解决你的问题,请参考以下文章

6javascript中对象和数组的深拷贝

拷贝数组和对象,深拷贝,浅拷贝

对象数组实例的深拷贝,Java

数组和对象的深拷贝

对象数组的深拷贝

javascript 数组以及对象的深拷贝(复制数组或复制对象)的方法