js 中,哪些数组原型方法会修改数组本身,哪些会返回新数组
在 JavaScript(TypeScript 同理)中,Array 的原型方法按照 是否修改原数组 可以分为两类:
✅ 会修改原数组(Mutator 方法)
Copy
| 方法 | 说明 |
|---|---|
push(...items) | 末尾添加元素 |
pop() | 删除最后一个元素 |
shift() | 删除第一个元素 |
unshift(...items) | 开头添加元素 |
splice(start, deleteCount, ...items) | 删除、替换或插入元素 |
reverse() | 反转数组 |
sort(compareFn?) | 排序数组 |
copyWithin(target, start?, end?) | 将数组内部元素复制到指定位置 |
fill(value, start?, end?) | 用指定值填充数组 |
✅ 不会修改原数组,返回新数组(Accessor / Iteration 方法)
Copy
| 方法 | 说明 |
|---|---|
concat(...arrays) | 合并数组 |
slice(start?, end?) | 提取子数组 |
map(callback) | 对每个元素执行函数并返回新数组 |
filter(callback) | 过滤符合条件的元素 |
reduce(...) / reduceRight(...) | 归约数组(返回任意值,不一定是数组) |
flat(depth?) | 扁平化嵌套数组 |
flatMap(callback) | 先映射再扁平化一层 |
toReversed() (ES2023) | 返回反转后的新数组(不修改原数组) |
toSorted(compareFn?) (ES2023) | 返回排序后的新数组 |
toSpliced(start, deleteCount?, ...items) (ES2023) | 返回删除/插入后的新数组 |
with(index, value) (ES2023) | 返回指定索引替换元素后的新数组 |
⚠️ 注意
- 即使是非修改方法,如果回调函数内部修改了原数组(如
arr[i] = 123),仍然可能导致副作用。 - ES2023 引入的
toReversed()/toSorted()/toSpliced()/with()是专门为 不修改原数组 设计的替代方案。
记忆口诀(非官方但好用)
- 带
to前缀的 + 不带to的「纯函数」 → 返回新数组 - 其余「动词」 → 大概率会修改原数组
示例对比
JavaScript
Copy
const arr = [1, 2, 3];
const newArr = arr.reverse(); // ❌ 修改原数组
console.log(arr); // [3, 2, 1](原数组被改了)
console.log(newArr === arr); // true(返回的是原数组引用)
const newArr2 = arr.toReversed(); // ✅ 返回新数组
console.log(arr); // [3, 2, 1](原数组不变)
console.log(newArr2); // [1, 2, 3]