concat()最稳妥,不修改原数组、兼容性好;展开运算符更现代但需注意环境支持和浅层展开;push()有副作用,仅适用于可控场景;避免join()+split()等不可靠方法。

用 concat() 合并数组最稳妥
concat() 是原生、无副作用、兼容性最好的方法,适合大多数拼接场景。它不修改原数组,而是返回一个新数组。
- 支持任意数量的参数,可以是数组、值,或混合:
const a = [1, 2]; const b = [3, 4]; const c = [5]; const result = a.concat(b, 3.14, c); // [1, 2, 3, 4, 3.14, 5]
- 传入空数组或
undefined不报错,会被忽略;但传入字符串会按字符拆开('abc'.concat([1])→['a','b','c',1]) - IE6+ 全兼容,没有 Symbol 或迭代器相关陷阱
用展开运算符 [...a, ...b] 更现代但有注意点
ES2015+ 推荐写法,语义清晰,性能通常优于 concat(),但要注意它只展开一层,且依赖目标环境支持迭代协议。
- 不能直接展开非可迭代对象(比如普通对象、
null、undefined会报TypeError: undefined is not iterable) - 嵌套数组不会被递归扁平化:
const a = [1, [2, 3]]; const b = [4]; const result = [...a, ...b]; // [1, [2, 3], 4] —— 不是 [1, 2, 3, 4]
- 若需深合并或处理稀疏数组(如
new Array(3)),展开运算符会保留空位,而concat()会转为undefined
用 push(...arr) 原地拼接但要小心副作用
如果明确想复用第一个数组、避免创建新引用,可用 push() 配合展开运算符。但这是**有副作用的操作**,必须确认调用方能接受原数组被修改。
- 仅适用于第一个参数是数组且你拥有其控制权的场景:
const target = [1, 2]; const source = [3, 4, 5]; target.push(...source); // target 变成 [1, 2, 3, 4, 5]
- 传入空数组或
length === 0的类数组没问题;但若source是伪数组(如arguments)且没实现迭代器,可能失败 - 不推荐在函数内部对传入的数组参数直接
push,除非文档明确约定“此函数会修改输入”
避免用 join() + split() 拼接数字/布尔等类型
有人会想到 a.join(',') + ',' + b.join(',') 再 split(','),这在处理纯字符串时看似可行,但对其他类型极不可靠。
立即学习“Java免费学习笔记(深入)”;
-
undefined、null、false、0在join()中都会变成空字符串或"0",导致无法还原原始值 - 含逗号的字符串(如
['a,b', 'c'])会被错误切分 - 性能差:字符串转换 + 分割 + 类型重铸,三重开销,且结果全是字符串
- 真正需要扁平化多维数组时,应选
flat()或递归逻辑,而不是字符串中转
concat() 最省心;追求简洁和现代语法且确定环境可控时,用展开运算符;只有明确要改原数组、且调用链可控时,才用 push(...)。别碰字符串中转那套——看着短,出问题时根本没法 debug。











