toSpliced 是 ES2023 新增的纯函数式数组方法,不修改原数组而返回新数组;splice 则直接修改原数组。二者参数一致,但 toSpliced 支持负索引、不接受负 deleteCount,需注意兼容性与浅拷贝特性。
toSpliced 是 ES2023 新增的数组方法,核心价值就是「不修改原数组、返回新数组」。而 splice 是就地修改——调用后原数组直接被改写,想保留原始数据就得先 slice() 或展开复制,容易漏写或写错。toSpliced 的参数签名和 splice 完全一致:toSpliced(start, deleteCount, ...items),但行为是纯函数式的:只读取原数组,构造并返回一个新数组。常见错误现象:有人误以为 toSpliced 是 splice 的别名,或者在旧环境(如 Node.js
toSpliced 一个方法覆盖三种场景,无需组合 filter + concat + slice:arr.toSpliced(2, 1) 表示从索引 2 开始删 1 个deleteCount 设为 0,例如 arr.toSpliced(1, 0, 'a', 'b') 在索引 1 前插入两个元素deleteCount > 0 且有新增项,例如 arr.toSpliced(0, 2, 'x', 'y') 删前两个、插两个新元素注意负数索引支持:和 splice 一样,start 可为负值,-1 表示倒数第一个位置。但 deleteCount 不能为负,否则抛 RangeError。
toSpliced 不是所有环境都可用。Node.js 需 ≥19.5,浏览器中 Safari 16.4+ 才支持,旧版微信 WebView、部分 Electron 内核也缺失。不要依赖用户环境自动降级。明确检查并提供 fallback:
const safeToSpliced = (arr, start, deleteCount, ...items) => { if (Array.prototype.toSpliced) { return arr.toSpliced(start, deleteCount, ...items); } // 手动模拟:slice + splice 组合,但确保不改原数组 const result = [...arr]; result.splice(start, deleteCount, ...items); return result;};
关键点:fallback 里用 [...arr] 而非 arr.slice(),避免对稀疏数组或带自定义属性的类数组出错;splice 操作的是副本,原数组绝对安全。
toSpliced 内部仍需遍历并拷贝元素,大数据量时不是零成本操作。但它比手动 slice + concat 更简洁、更少出错。start 超出范围(如大于 arr.length)时,新数组末尾追加 items,不报错deleteCount 大于剩余可删数量时,只删到末尾,不会越界[].toSpliced(0, 0, 1) 正常返回 [1]
Object.freeze(arr)),toSpliced 仍能工作,因为它不修改原数组真正容易被忽略的是:它不处理嵌套引用。如果你删掉的是一个对象,新数组里那个对象仍是同一引用——深拷贝得另外做,toSpliced 不负责这个。