JavaScript快速拷贝数组的几种方法
本文总结快速拷贝数组的几种方法(个人认为总结都很无聊),文章旨(chun)在(shu)总(wu)结(liao),对于日常编码,只需挑选一种写法即可,通过本文,你将对 JavaScript 数组方法及 ES6 有更多的了解。
为了不重复写代码,所有例子都是以下面这个环境为基础。
1 | const exampleArr = [1, 2, 3]; |
循环
还是写一些基础的for
循环吧
1 | let length = exampleArr.length; |
使用forEach()
1 | const newArr = []; |
如果面试官问你如何拷贝一个数组,你只会for
循环,那估计你是凉凉了。
Array.prototype.map()
map()
方法建一个新数组,其结果是该数组中的每个元素都调用一次提供的函数后的返回值。
这种方法和forEach()
相差无几,都是通过回调函数来为新数组赋值。
1 | const newArr = exampleArr.map((value) => value); |
Array.prototype.filter()
filter()
方法返回一个回调函数过滤后的新数组,他有一个回调函数和指向当前数组的this
(可选参数)作为参数,回调函数的参数和forEach()
及map()
方法相同,当回调函数返回true
时则将当前处理元素放进新数组。
1 | const newArr = exampleArr.filter((i) => true); |
Array.prototype.concat()
concat()
方法用于合并两个或多个数组,并返回一个新数组,参数可以是 0 个或多个数组。
当有 0 个参数的时候显然会返回一个拷贝数组:
1 | const newArr = exampleArr.concat(); |
Array.prototype.slice()
slice()
方法实现了数组的浅拷贝,就是说当拷贝数组里的对象时只会保留引用。
它有两个可选索引参数,由于确定从何处开始拷贝,何处停止拷贝,如果省略参数即拷贝整个数组。
1 | const newArr = exampleArr.slice(); |
还有一个和slice()
方法类似的copyWithin()
方法,他们都是浅拷贝,但copyWithin()
浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。说的不是很明白?举个例子:
1 | const array1 = ["a", "b", "c", "d", "e"]; |
它的第一个参数是开始替换的索引位置,后面两个可选参数分别表示从何处开始复制,在何处结束复制,如果省略即复制整个数组。上面这个例子表示复制索引[3,4)的值(左闭右开),然后将每个值从第 0 个索引开始覆写。最终值将是[“d”,”b”,”c”,”d”,”e”]。
所以下面这种写法并不是拷贝数组,因为它的拷贝值都赋值给自身了,newArr
仅仅是保留了引用。
1 | const newArr = exampleArr.copyWithin(0); |
数组解构+剩余参数
1 | const [...newArr] = exampleArr; |
数组解构是 ES6 中的语法,通过数组解构可以将数组的值保存到解构对应的变量中,当不想一一赋值的时候可以使用剩余参数,将所有剩余的值保存在一个数组中,上面这段代码就是这种做法,将所有的值保存在newArr
中。
注意是剩余参数,而不是扩展运算,二者很像,他们的区别请看这篇文章ES6解构与剩余参数的最后一部分。