在 JavaScript 中复制数组的 14 个技巧

1,111 阅读4分钟

因为缺乏对 JavaScript 如何处理数组及其数组元素的理解,数组复制过程经常被误解。JavaScript中的数组是可变的,这意味着在一个数组被创建后,它的内容可以被修改。

这意味着要复制数组,我们不能简单地将旧数组分配给一个新的数组变量。如果我们这样做,它们将共享同一个引用,在改变一个变量后,另一个变量也会受到影响。这就是为什么我们需要克隆数组的原因。

下面是一些关于我们如何克隆数组的有趣方法和技巧。

请注意,这些方法执行的是浅拷贝……尽管在我们的示例中我们没有更深层次的对象来查看它的实际效果。

选项 1 - 使用 Array.slice 方法

const numbers = [1, 2, 3, 4, 5];

const copy = numbers.slice();
copy.push(6); // 增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 2 - 使用 Array.map 方法

const numbers = [1, 2, 3, 4, 5];

const copy = numbers.map(num => num);
copy.push(6); //  增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 3 - 使用 Array.from 方法

const numbers = [1, 2, 3, 4, 5];

const copy = Array.from(new Set(numbers));
copy.push(6); //  增加一个新项,以证明我们不会修改原来的数组。
console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 4 - 使用扩展运算符

const numbers = [1, 2, 3, 4, 5];

const copy = [...numbers];
copy.push(6); //  增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 5 - 将 Array.of 方法与扩展运算符一起使用

const numbers = [1, 2, 3, 4, 5];

const copy = Array.of(...numbers);
copy.push(6); //  增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 6 - 使用带有扩展运算符的数组构造函数

const numbers = [1, 2, 3, 4, 5];

const copy = new Array(...numbers);
copy.push(6); //  增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 7 - 使用解构

const numbers = [1, 2, 3, 4, 5];

const [...copy] = numbers;
copy.push(6); //  增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 8 - 使用 Array.concat 方法

const numbers = [1, 2, 3, 4, 5];

const copy = numbers.concat();
copy.push(6); // 增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 9 - 将 Array.push 方法与扩展运算符一起使用

const numbers = [1, 2, 3, 4, 5];

let copy = [];
copy.push(...numbers);
copy.push(6); // 增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 10 - 将 Array.unshift 方法与扩展运算符一起使用

const numbers = [1, 2, 3, 4, 5];

let copy = [];
copy.unshift(...numbers);
copy.push(6); //  增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 11 - 使用 Array.forEach 方法

const numbers = [1, 2, 3, 4, 5];

let copy = [];
numbers.forEach((value) => copy.push(value));
copy.push(6); //  增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 12 - 使用 for 循环

const numbers = [1, 2, 3, 4, 5];

let copy = [];
for (let i = 0; i < numbers.length; i++) {
    copy.push(numbers[i]);
}
copy.push(6); //  增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 13 - 使用 Array.reduce

这是有可能的,但这是一种矫枉过正的做法,你应该选择上述方法之一。

const numbers = [1, 2, 3, 4, 5];

const copy = numbers.reduce((acc, x) => { acc.push(x); return acc; }, []);
copy.push(6); // 增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

选项 14 - 一种怀旧的方式 - 使用 apply 方法

const numbers = [1, 2, 3, 4, 5];

let copy = [];
Array.prototype.push.apply(copy, numbers);
copy.push(6); // 增加一个新项,以证明我们不会修改原来的数组。

console.log(copy);
console.log(numbers);

// 输出
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

感谢您的阅读,我们下一篇文章再见。