tospliced是es2023新增的纯函数式数组方法,返回新数组且不修改原数组;而splice直接修改原数组并返回被删元素。

toSpliced 是什么,和 splice 有什么关键区别
toSpliced 是 ES2023 新增的数组方法,作用是返回一个新数组,在指定位置增删元素,原数组完全不变。这和 splice 的核心差异在于:后者直接修改原数组并返回被删除的元素(不是新数组),而 toSpliced 始终纯函数式,适合不可变数据流场景。
常见错误现象是误以为它能像 slice + concat 那样手动拼接——其实它内部已封装了插入、删除、偏移逻辑,直接用更安全。
-
toSpliced(start, deleteCount, ...items)参数含义和splice完全一致 - 第一个参数
start支持负数(从末尾计数),但不支持undefined或null,否则会转为0 -
deleteCount为0时只插入,为Infinity或大于剩余长度时删到末尾 - 返回值永远是新数组,哪怕没做任何改动(例如
arr.toSpliced(0, 0))
删除元素:只删不插的典型写法
想删掉索引 2 开始的 1 个元素,得到新数组:
const arr = [1, 2, 3, 4, 5]; const newArr = arr.toSpliced(2, 1); // → [1, 2, 4, 5]
注意点:
-
arr本身仍是[1, 2, 3, 4, 5],未被修改 - 如果
start超出范围(如10),不报错,直接返回原数组副本(即不删不插) -
deleteCount传负数会被转成0,等效于只插入
插入元素:在指定位置添加,不删除
想在索引 1 后插入两个新值:
const arr = ['a', 'b', 'c']; const newArr = arr.toSpliced(2, 0, 'x', 'y'); // → ['a', 'b', 'x', 'y', 'c']
使用场景包括:表单列表新增项、UI 动态插入节点、状态更新时避免 mutate。
- 插入位置由
start决定:toSpliced(0, 0, ...)是前插,toSpliced(arr.length, 0, ...)是后插 -
deleteCount必须显式写0,不能省略(否则第二个参数会被当作deleteCount) - 插入多个元素时,直接展开为后续参数,不用包成数组
同时删和插:真实业务中最常遇到的情况
比如编辑购物车:删掉第 1 个商品,同时在开头加一个促销商品:
const cart = [{id: 1}, {id: 2}, {id: 3}];
const newCart = cart.toSpliced(0, 1, {id: 'promo-2024'});
// → [{id: 'promo-2024'}, {id: 2}, {id: 3}]
容易踩的坑:
- 删除数量超过可删范围时,多余部分静默忽略(例如
toSpliced(1, 100, 'x')在长度为 3 的数组上只会删掉索引 1 和 2) - 插入内容如果是对象或数组,只是浅拷贝引用,原对象仍可被外部修改
- 浏览器兼容性需留意:
toSpliced在 Safari 16.4+、Chrome 114+、Firefox 115+ 才支持;Node.js 20.2+ 起可用,旧环境需 polyfill 或降级为toSorted+ 手动 slice/concat 组合
真正要小心的是混合操作时的索引偏移感——删完再插,插入位置是基于原数组计算的,不是删完后的中间状态。这点和 splice 行为一致,但初学者容易脑补成“先删后插再定位”,实际是一次性按原始索引完成的。










