JS中[].concat(...arr)与[...arr]的差异:数组扁平化递归解析
解释两种写法的行为差异
核心区别在于:扩展运算符...和concat处理数组参数的逻辑完全不同
先明确arr.map(steamrollArray)的返回值
递归调用时,steamrollArray对每个元素的处理结果是:
- 如果元素是单个值(比如
1),直接返回该值 - 如果元素是数组(比如
[2]),返回扁平化后的数组(比如[2])
以原数组[1, [2], [3, [[4]]]]为例,第一次map的结果是:
[1, [2], [3, 4]]
为什么[...arr.map(steamrollArray)]无法扁平化?
扩展运算符...仅负责把数组的第一层元素逐个拆出放进新数组,不会递归拆解内部的子数组。
上面的map结果里,[2]和[3,4]本身是数组,用...展开后,它们会作为完整的数组元素留在新数组里,最终得到的就是[1, [2], [3,4]],和map的输出完全一致,自然没完成扁平化。
为什么[].concat(...arr.map(steamrollArray))能正常工作?
Array.prototype.concat的特性是:只要传入的参数是数组,就会把数组内的所有元素逐个合并到结果中;如果是单个值,则直接添加。
当用...把map的结果展开成参数传给concat时,相当于执行:
[].concat(1, [2], [3, 4])
concat会自动把[2]里的2、[3,4]里的3和4拆出来,最终合并成[1,2,3,4],正好完成深度扁平化。
补充:和Python思路的差异
作为Python背景开发者,你可能习惯用列表推导式[x for sub in arr for x in sub]或sum(arr, [])实现扁平化,但JS的扩展运算符更像Python的*解包(仅解一层),而concat才是真正能将数组参数“打散”合并的方法——这就是两种写法结果完全相反的核心原因。
内容的提问来源于stack exchange,提问作者gorky
相关产品推荐
相关产品推荐

