【数组】js合并数组的三种方式concat、apply、扩展运算符

2,976 阅读3分钟

回顾数组合并的三种常用实现方式:concat、apply、扩展运算符。(不扩展遍历~)

每个调用实现的方式大同小异,那么你平常最习惯用哪一种方式来做数组合并操作呢?

image.png

1、Array.prototype.concat()

使用 concat() 方法来合并两个或多个的数组。用 concat 来合并现有数组不会去更改现有数组的结构,而是返回一个浅拷贝后的新数组,现有数组的元素将复制到新数组中,对于新数组的任何操作(除对象引用外)都不会对原始数组产生影响。

调用格式:

var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])

valueN 就是数组和/或值,将被合并到一个新的数组中。如果省略了所有 valueN 参数,则 concat 会返回调用此方法的现存数组的一个浅拷贝。

案例

// 1、数组与数组间的合并
const arr1 = ['张三', '李四', '王五'];
const arr2 = ['赵六', '秦七', '郑八', '唐九'];
const arr3 = ['如十'];
const arr4 = arr1.concat(arr2, arr3);

console.log(arr1) // ['张三', '李四', '王五']
console.log(arr2) // ['赵六', '秦七', '郑八', '唐九']
console.log(arr4) // ['张三', '李四', '王五', '赵六', '秦七', '郑八', '唐九','如十']


// 2、数组与其他
const arr5 = ['吕一', '施二', '金三'];
const arr6 = arr5.concat(4, 5, 6)

console.log(arr5) // ['吕一', '施二', '金三']
console.log(arr6) // ['吕一', '施二', '金三', 4, 5, 6]


// 3、数组与对象
const obj1 = {a: 1};
const arr7 = arr5.concat(obj1)
console.log(arr7) // ['吕一', '施二', '金三', {a: 1}]

obj1.a = 2; // 如果去修改对象的值,那么新数组中的值也将对应发生改变,这是因为原数组和新数组都引用的是相同的对象。
console.log(arr7) // ['吕一', '施二', '金三', {a: 2}]


// 4、数组与嵌套数组
const arr8 = [[7], [8, 9]];
const arr9 = arr5.concat(arr8);
console.log(arr9) // ['吕一', '施二', '金三', [7], [8, 9]]

arr8[0][0] = 10; // 万物皆对象~~
console.log(arr9) // ['吕一', '施二', '金三', [10], [8, 9]]


2、Array.prototype.push.apply

如果合并数组的方式是想要将元素添加到现有数组,而不是去创建新数组,再去用push 将值追加到数组中,就显得不太合适,因为如果push的参数是数组,它会将该数组作为单个元素去进行添加,而不是将这个数组内的每个元素添加进去,因此我们最终会得到一个数组内的数组,但这只能解决单一情况下的数组合并,对于嵌套数组等复杂类型进行合并就稍微欠缺。

那么通过利用 apply() 方法特性就刚刚好可以将元素追加到现有数组里。

apply()的调用方式:

func.apply(thisArg , [ argsArray])

调用格式

Array.prototype.push.apply(array1, array2);

案例


// 1、数组与数组
const arr1 = ['张三', '李四', '王五'];
const arr2 = ['赵六', '秦七', '郑八', '唐九'];
const arr3 = ['如十'];
Array.prototype.push.apply(arr1, arr2);
Array.prototype.push.apply(arr1, arr3);
console.log(arr1) // ['张三', '李四', '王五', '赵六', '秦七', '郑八', '唐九','如十']


// 2、数组与其他
const arr5 = ['吕一', '施二', '金三'];
const number1 = 1;
Array.prototype.push.apply(arr5, [1]); // 注意 apply 的第二个参数接受的是数组
console.log(arr5) // ['吕一', '施二', '金三', 1]


// 3、数组与对象
const arr5 = ['吕一', '施二', '金三'];
const obj1 = {a: 1};
Array.prototype.push.apply(arr5, [obj1]);
console.log(arr5) // ['吕一', '施二', '金三', {a: 1}]

obj1.a = 2; // 同样的,这时候如果去修改对象的值,那么新数组中的值也将一样发生改变,这是因为它们引用的都还是相同的对象。
console.log(arr5) // ['吕一', '施二', '金三', {a: 2}]

3、扩展运算符

扩展运算符的调用方式就是简单的三个点(...),跟 rest 参数的逆运算相似,它用于把一个数组转化为用逗号分隔的参数序列,它常用在不定参数个数时的函数调用,数组合并等情形。在合并数据到原数组的时候,即可以直接调用,也可以通过call()来调用。

call()的调用方式:

function.call(thisArg, arg1, arg2, ...)

调用格式

arr1.push(...arr2)

案例


// 1、数组与数组
const arr1 = ['张三', '李四', '王五'];
const arr2 = ['赵六', '秦七', '郑八', '唐九'];
const arr3 = ['如十'];
Array.prototype.push.call(arr1, ...arr2); // ~
console.log(arr1) // ['张三', '李四', '王五', '赵六', '秦七', '郑八', '唐九']

arr3.push(...arr2);
console.log(arr3) // ['如十', '赵六', '秦七', '郑八', '唐九']


4、参考

MDN关于Apply的相关介绍

MDN关于Push的相关介绍

MDN关于Concat的相关介绍

MDN关于Call的相关介绍