扩展运算符...(浅拷贝)
这是在ES6中出现的新的运算符,自从出现以来,它已经成为最受欢迎的方法之一,它的语法实在是太简洁
numbers = [1, 2, 3]; numbersCopy = [...numbers];
注意:它不能安全的复制多维数组,数组/对象是通过引用复制而不是通过值复制
正例:
numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4]
反例:
nestedNumbers = [[1], [2]]; numbersCopy = [...nestedNumbers]; numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1, 300], [2]] // [[1, 300], [2]]
for循环(浅拷贝)
由于函数式编程的流行,现在应该用的比较少了
numbers = [1, 2, 3]; numbersCopy = []; for (i = 0; i < numbers.length; i++) { numbersCopy[i] = numbers[i]; }
注意:它也不能安全地复制多维数组。因为使用=运算符,因此它将通过引用而不是值来分配对象/数组。
正例:
numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4]
反例:
nestedNumbers = [[1], [2]]; numbersCopy = []; for (i = 0; i < nestedNumbers.length; i++) { numbersCopy[i] = nestedNumbers[i]; } numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy);
while循环(浅拷贝)
和for循环类似
numbers = [1, 2, 3]; numbersCopy = []; i = -1; while (++i < numbers.length) { numbersCopy[i] = numbers[i]; }
注意:它也通过引用而不是按值分配对象/数组。
正例:
numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4]
反例:
nestedNumbers = [[1], [2]]; numbersCopy = []; i = -1; while (++i < nestedNumbers.length) { numbersCopy[i] = nestedNumbers[i]; } numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1, 300], [2]] // [[1, 300], [2]]
Array.map(浅拷贝)
map会将数组转换成为另一个数组又同时保留结构的方法
numbers = [1, 2, 3]; double = (x) => x * 2; numbers.map(double);
复制数组就更简单了
numbers = [1, 2, 3]; numbersCopy = numbers.map((x) => x);
注意:它同样也通过引用而不是按值分配对象/数组。
Array.filter(浅拷贝)
和map一样,接受一个函数组作为参数,但是它会通过传递的函数过滤和筛选,这样不能保证得到数组长度不变,比如筛选出数组中的偶数
[1, 2, 3].filter((x) => x % 2 === 0) // [2]
复制数组
numbers = [1, 2, 3]; numbersCopy = numbers.filter(() => true);
注意:它同样也通过引用而不是按值分配对象/数组。
Array.reduce(浅拷贝)
reduce 在循环列表时转换初始值
numbers = [1, 2, 3]; numbersCopy = numbers.reduce((newArray, element) => { newArray.push(element); return newArray; }, []);
注意:它同样也通过引用而不是按值分配对象/数组。
Array.slice(浅拷贝)
slice需要你传递开始索引和结束索引
[1, 2, 3, 4, 5].slice(0, 3); // [1, 2, 3] // 0到3索引,得到1,2,3,不包括4
如果只想复制,不需要传递任何参数即可
numbers = [1, 2, 3, 4, 5]; numbersCopy = numbers.slice(); // [1, 2, 3, 4, 5]
注意:它同样也通过引用而不是按值分配对象/数组。
JSON.parse和JSON.stringify(深层拷贝)
- JSON.stringify 将对象转换为字符串。
- JSON.parse 将字符串转换为对象。
组合它们可以将对象转换为字符串,然后反转该过程可以创建全新的数据结构。
nestedNumbers = [[1], [2]]; numbersCopy = JSON.parse( JSON.stringify(nestedNumbers) ); numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1], [2]] // [[1, 300], [2]] // 两个数组是分开的
注意:它是安全的复制方法
Array.concat(浅拷贝)
concat是数组之间相连接,例如
[1, 2, 3].concat(4); // [1, 2, 3, 4] [1, 2, 3].concat([4, 5]); // [1, 2, 3, 4, 5]
如果只是单纯的复制,那你可以不传递任何参数或者传递一个空数组即可
[1, 2, 3].concat(); // [1, 2, 3] [1, 2, 3].concat([]); // [1, 2, 3]
注意:它同样也通过引用而不是按值分配对象/数组。
Array.from(浅拷贝)
可以将任何可迭代对象转换为数组,如下
numbers = [1, 2, 3]; numbersCopy = Array.from(numbers) // [1, 2, 3]
注意:它同样也通过引用而不是按值分配对象/数组。
总结
本文着重探讨的是数组的复制,这些方法都可以用来做数组的拷贝,各有好坏,其实还有其他的一些方法来完成数组的复制,本文就介绍到这,如果对你有帮助,请点个关注吧!