JavaScript 数组 concat 方法详解:结合 apply 实现扁平化

作者:青柠时间:2026-10-30 13:39:15浏览:628

本文深入解析 JavaScript 中 concat 方法的合并机制,指出其将新数组成员添加至原数组尾部且原数组不变的特性。重点探讨 concat 与 apply 结合使用时,利用 apply 将数组参数展开为单个参数的特性,从而实现多维数组扁平化的技巧,并对比两种方法的行为差异。

JavaScript 数组 concat 方法详解:结合 apply 实现扁平化

在展开具体介绍之前,先提出一个常见的问题:如何将多个独立的数组合并为一个完整的数组?

接下来的内容将按以下小节进行分享:

1. concat 方法的基础介绍

2. 通过实例深入理解 concat 方法

concat 方法的基础介绍

1. concat 方法的基础介绍

concat 方法的主要功能是将多个数组合并。它会将新数组的成员追加到原数组的尾部,并返回一个新数组,而原数组保持不变。


console.log([].concat([1],[2],[3])); // [1, 2, 3]
console.log([].concat([[1],[2],[3]])); // [[1], [2], [3]]
console.log([].concat(4,[[5,6],[7]])); // [4, [5, 6], [7]]

上述代码中,第一个返回值展示了将一个空数组与三个数组 [1]、[2]、[3] 合并的过程,最终结果为 [1, 2, 3]。第二个示例是将一个空数组与一个包含 [1]、[2]、[3] 的二维数组合并,由于二维数组的成员本身是数组,因此返回结果仍为二维数组 [[1], [2], [3]]。第三个例子同理。这里需要重点理解的概念是:新数组的成员会被添加到原数组的尾部,而非递归展开。

除了接受数组作为参数外,concat 方法还可以接受其他类型的值作为参数。这些非数组类型的值会作为独立的元素,被添加到数组的尾部。


console.log([].concat(1,2,3)); //[1,2,3];
//等同于
console.log([].concat(1,[2,3])); //[1,2,3];
console.log([].concat([1],[2,3])); //[1,2,3]; 

虽然这部分内容看似简单,但真正深入理解其内部机制并非易事。

从实例中感受 concat 方法

2. 从实例中感受 concat 方法

介绍完基础知识后,分享一个近期遇到的实际题目。原题如下。

JavaScript 数组 concat 方法详解:结合 apply 实现扁平化

通过观察示例即可明白其含义。

该题目的一个解决方案如下:


var flatten = function (arr){
return [].concat.apply([],arr);
};

这段简单的函数实现了将数组元素合并的功能。但在理解其返回值时,我发现了一个值得探讨的问题。

问题:为什么使用 apply 方法与不使用 apply 方法会产生不同的结果?


console.log([].concat.apply([],[[1],[2],[3]])); //[1, 2, 3]
console.log([].concat([[1],[2],[3]])); //[[1], [2], [3]]

在上述代码中,虽然都是在空数组的尾部添加新数组,但第一个返回的是 [1, 2, 3],而第二个却返回了一个二维数组。

经过一段时间的调试与分析,终于理解了造成这种差异的原因。

首先,当我们在空数组上调用实例方法 concat 时,传入的参数会被 push 到数组末尾。这意味着,concat 会将空数组与传入数组的最外层结构进行合并,然后返回一个新数组。


console.log([].concat(1,2,3)); //[1, 2, 3]
console.log([].concat([1],[2],[3])); //[1, 2, 3]
console.log([].concat([[1],[2],[3]])); //[[1], [2], [3]]
console.log([].concat([[[1],[2],[3]]])); // [[[1], [2], [3]]]

上述代码展示了从多个数组到一维数组、二维数组、三维数组逐渐变化的过程。

在《Javascript 中 call、apply、bind 方法的详解与总结》一文中提到,apply 方法的作用与 call 类似,也是改变 this 指向(即函数执行时所在的作用域),并在指定的作用域中调用该函数,同时立即执行。两者的唯一区别在于,apply 接收一个数组作为函数执行时的参数列表。

apply 方法的第一个参数指定了 this 指向的对象,如果设为 null、undefined 或 this,则等同于指定全局对象。第二个参数是一个数组,该数组的所有成员会依次作为参数传入原函数。而在 call 方法中,参数必须逐个添加;但在 apply 方法中,参数必须以数组形式传入。


console.log([].concat.apply([],[[1],[2],[3]])); //[1, 2, 3]
console.log([].concat([[1],[2],[3]])); //[[1], [2], [3]]

从代码可以看出,第一段代码先在空数组上调用 concat 方法,其作用是将新数组的成员添加到原数组尾部。随后调用 apply 方法,第一个参数指定对象执行时的作用域,第二个参数的作用是将数组中的所有成员作为参数,在调用时传入数组中。

因此,当 concat 与 apply 方法同时使用时,两者的作用会叠加,从而出现与单独使用 concat 不同的现象。请看以下示例。


console.log([].concat([1,2,3])); //[1, 2, 3]
console.log([].concat.apply([],[[1],[2],[3]]));//[1, 2, 3]
console.log([].concat([[1],[2],[3]]));//[[1], [2], [3]]
console.log([].concat.apply([],[[[1],[2],[3]]]));//[[1], [2], [3]]
console.log([].concat([[[1],[2],[3]]]));//[[[1], [2], [3]]]
console.log([].concat.apply([],[[[[1],[2],[3]]]]));//[[[1], [2], [3]]]

上述代码中,concat 方法先将最外层的数组合并,然后在合并的基础上,对下一层数组进行合并。


console.log([].concat.apply([],[[1],[2],[3]]));//[1, 2, 3]
//相当于
console.log([].concat(1,2,3)); //[1,2,3] 

总结

总结:

1. 单独使用 concat 方法时,会将新数组的成员添加到原数组的尾部。

2. 使用 apply 方法来指定 concat 方法的 this 指向时,会让两个方法的作用叠加。

3. 数组元素合并的方法:


var flatten = function (arr){
return [].concat.apply([],arr);
}; 
var flatten = function (array){
return array.reduce(function(a,b){
return a.concat(b);
},[])
}

以上所述是小编给大家介绍的 javascript 使用 concat 方法对数组进行合并的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对本站网站的支持!

作者最新文章