javascript 数组以及对象的深拷贝(复制)的方法
=
号来进行复制,那只是浅拷贝。
如上,arr
的修改,会影响arr2
的值,这显然在绝大多数情况下,并不是我们所需要的结果。
数组以及对象的深拷贝是javascript
的一个基本功。
数组的深拷贝
条条大道通罗马,实现数组的深拷贝,是有好几种方法的。举例如下:
for 循环实现数组的深拷贝
for循环是非常好用的。如果不知道高级方法,通过for循环能够完成我们大多数的需求。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
如上,通过对数组的for循环,即可实现对数组的深拷贝了。
slice 方法实现数组的深拷贝
这个代码实现非常简单。原理也比较好理解,他是将原数组中抽离部分出来形成一个新数组。我们只要设置为抽离全部,即可完成数组的深拷贝。代码如下:
- 1
- 2
- 3
- 4
- 5
运行结果如下:
更多 slice
内容请访问 w3school JavaScript slice 方法
concat 方法实现数组的深拷贝
这个代码也非常简单,原理更加粗暴。它是用于连接多个数组组成一个新的数组的方法。那么,我们只要连接它自己,即可完成数组的深拷贝。代码如下:
- 1
- 2
- 3
- 4
- 5
运行结果如下:
更多 concat
内容请访问 w3school JavaScript concat 方法
ES6扩展运算符实现数组的深拷贝
OK,以上之前讲的方法全部过时了,用下面的方法实现数组的深拷贝是最简单的。
- 1
- 2
- 3
- 4
- 5
运行结果如下:
=====多维数组的深拷贝=====
因为javascript分原始类型与引用类型(与java、c#类似)。Array是引用类型,所以直接用=号赋值的话,只是把源数组的地址(或叫指针)赋值给目的数组,并没有实现数组的数据的拷贝。另外对一维数组和多维数据的深拷贝实现方式是不一样的
多维数组深拷贝的JS函数实现方式:
function deepcopy(obj) { var out = [],i = 0,len = obj.length; for (; i < len; i++) { if (obj[i] instanceof Array){ out[i] = deepcopy(obj[i]); } else out[i] = obj[i]; } return out; } //下面是测试代码 var weekArray = new Array(7);//数组第一维 var timeTableArray = new Array(); //数组第二维 var lineArray = new Array(4); //数组第三维 lineArray[0] = "1_a"; lineArray[1] = "1_b"; lineArray[2] = "1_c"; timeTableArray.push(lineArray); weekArray[0] = deepcopy(timeTableArray); //清空,并添加其他星期的数据 lineArray.splice(0,lineArray.length); timeTableArray.splice(0,timeTableArray.length); lineArray[0] = "7_a"; lineArray[1] = "7_b"; lineArray[3] = "7_d"; timeTableArray.push(lineArray); weekArray[7] = deepcopy(timeTableArray); alert("weekArray=" + weekArray[0]);//返回 "1_a,1_b,1_c," alert("weekArray=" + weekArray[7]);//返回 "7_a,7_b,,7_d"
多维数组的jquery实现方式:
把上述的deepcopy函数用下面的函数替代即可
weekArray[0] = $.extend(true, {}, timeTableArray);
对象的深拷贝
对象的深拷贝相比数组也没有困难许多,列举两个方法。
万能的for循环实现对象的深拷贝
在很多时候,for循环能够解决大问题。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
转换成json再转换成对象实现对象的深拷贝
上面的代码实在是比较长,所以,用一个更暴力的方法吧!代码如下:
- 1
- 2
- 3
- 4
- 5
- 6
这个原理没什么好解释的,实在是够简单粗暴的啦!
扩展运算符实现对象的深拷贝
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
运行结果如下:
小结
数组和对象的深拷贝是js中最常见的应用。理解各种方法是必须的。希望对大家有所帮助。
本文中并没有对异常进行处理,主要在讲原理。更多的数组以及对象的操作方法,可以参考lodash
的源码,查看它的源码可以让你的js基础变得非常牢固。我也在学习中。