splice能同时删、插、替,因其接收start、deleteCount及插入项三类参数,在原数组上就地完成任意位置的增删改;而push/pop仅限末尾操作且功能单一。

splice 为什么能同时删、插、替,而 push/pop 不能
splice 是唯一原生支持「在指定索引处精准干预数组结构」的方法。它不依赖数组末尾,也不需要手动拼接新数组,所有操作都在原数组上就地完成。关键在于它接收三个核心参数:start(起始索引)、deleteCount(删除个数)、以及可选的 item1, item2, ...(插入项)。其他方法如 push、unshift 或 filter 只能覆盖单一场景,且多数会返回新数组或仅限端点操作。
删除元素:deleteCount > 0,不传新增项
最常用也最容易出错的是越界删除——当 start 超出数组长度时,splice 不报错,但什么也不删;当 start 为负数,会从末尾倒数(-1 表示最后一个元素)。注意:deleteCount 为 0 时等价于只插入,不是“删零个”意义上的空操作,而是触发插入逻辑。
- 删第 2 个元素(索引 1):
arr.splice(1, 1) - 删最后两个:
arr.splice(-2, 2) - 删索引 5 开始的所有剩余项:
arr.splice(5)(deleteCount省略即删到底) - 错误写法:
arr.splice(10, 1)在长度为 3 的数组上静默失败,建议先校验start
插入元素:deleteCount = 0,后面跟新项
插入本质是「不删、只加」。此时 start 指定的是新元素将要插入的位置(即插入后它们会占据该索引及后续位置),原索引 ≥ start 的所有元素自动后移。插入不改变原数组长度以外的结构,但要注意:如果 start 大于当前长度,新元素会追加到末尾(不会补 undefined)。
- 在开头插入两个元素:
arr.splice(0, 0, 'a', 'b') - 在末尾插入(等效于
push):arr.splice(arr.length, 0, 'x') - 在索引 2 后插入(即新元素成为第 3、4 位):
arr.splice(2, 0, 'y', 'z') - 常见误用:
arr.splice(1, 0, ['a', 'b'])会插入一个数组作为单个元素,应展开:arr.splice(1, 0, ...['a', 'b'])
替换元素:deleteCount > 0,且带新增项
替换 = 删除 + 插入 的原子组合。这是 splice 最不可替代的用途——比如把中间某几个元素换成另一组,位置和数量都可控。返回值是被删掉的元素组成的数组,可用于回滚或日志记录。性能上,它比先 slice 再拼接更优,尤其对大数组,因避免了多次内存分配。
- 用 ['X', 'Y'] 替换索引 1 开始的 2 个元素:
arr.splice(1, 2, 'X', 'Y') - 删 1 个、插 3 个(净增 2):
arr.splice(3, 1, 'p', 'q', 'r') - 删 3 个、插 1 个(净减 2):
arr.splice(0, 3, 'single') - 注意边界:若
start + deleteCount > arr.length,实际只删到末尾,但新增项仍会正常插入(例如[1,2].splice(1,10,'x')→[1,'x'])
真正难的是动态计算 start 和 deleteCount 时的边界处理,尤其是结合循环或条件判断使用时,数组长度实时变化会让索引偏移。建议:要么先收集所有待操作位置再批量调用 splice,要么改用函数式方法(如 map + filter)避免副作用。原地修改看着省事,一不小心就索引错乱。










