concat()方法用于合并数组,返回新数组且不修改原数组,符合不可变更新原则;它执行浅拷贝,嵌套对象仍共享引用,适用于React/Vue等需要引用变化触发更新的场景。

使用 concat 可以安全地向数组添加新元素,同时保持原数组不变,是处理不可变状态的一种简洁方式。它天然返回新数组,不修改原始数组,符合浅拷贝更新的核心要求。
concat 的不可变性原理
concat 方法始终返回一个全新数组,原数组对象引用和内容均不受影响。这种行为天然契合不可变更新原则——不直接修改旧状态,而是生成新状态。
- 即使只传入一个空数组(
arr.concat([])),也会返回新数组引用 - 传入多个参数(如元素、数组、混合值)时,会按顺序拼接并返回新数组
- 对嵌套对象或数组,仅复制其引用,属于浅拷贝 —— 这正是它的适用边界
常见不可变更新场景示例
以下操作都避免了 push、splice 等会改变原数组的方法:
-
追加单个元素:
const newState = oldState.concat(newItem); -
追加多个元素:
const newState = oldState.concat(item1, item2, item3); -
合并另一个数组:
const newState = oldState.concat(otherArray); -
前置插入(模拟 unshift):
const newState = [newItem].concat(oldState);
注意浅拷贝的局限性
concat 只做一层引用复制,若数组内含对象,修改该对象属性仍会影响原状态:
- ✅ 安全:替换整个数组项(如用新对象替换旧对象)
- ⚠️ 不安全:
newState[0].name = 'Alice'会同步改变oldState[0].name - ? 若需深度不可变,应配合结构赋值(
{...obj})或map+ 解构更新对象项
与扩展运算符的对比
concat 和 [...arr, newItem] 效果相似,但有细微差异:
-
concat对null或undefined参数更宽容(直接忽略) - 扩展运算符在参数为非数组时会报错(如
[...null]TypeError) - 函数式风格中,
concat更易链式调用或作为高阶函数参数(如arr.concat.bind(arr))










