专业编程基础技术教程

网站首页 > 基础教程 正文

JavaScript中数组的克隆(javascript 数组拷贝)

ccvgpt 2024-07-23 01:18:01 基础教程 15 ℃

扩展运算符...(浅拷贝

这是在ES6中出现的新的运算符,自从出现以来,它已经成为最受欢迎的方法之一,它的语法实在是太简洁

numbers = [1, 2, 3];
numbersCopy = [...numbers];

注意:它不能安全的复制多维数组,数组/对象是通过引用复制而不是通过值复制

JavaScript中数组的克隆(javascript 数组拷贝)

正例:

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]

注意:它同样也通过引用而不是按值分配对象/数组。

总结

本文着重探讨的是数组的复制,这些方法都可以用来做数组的拷贝,各有好坏,其实还有其他的一些方法来完成数组的复制,本文就介绍到这,如果对你有帮助,请点个关注吧!

Tags:

最近发表
标签列表