toSpliced是ES2023新增的不可变数组方法,与splice接口一致但不修改原数组、返回新数组;根本区别在于splice是原地变异操作,而toSpliced是纯函数式、无副作用的复制操作。
toSpliced 是 ES2023 新增的数组方法,核心价值就是「不修改原数组」。它和 splice 接口几乎一致(同样接受 start、deleteCount 和插入元素),但返回的是一个新数组,原数组完全不受影响。
常见错误是误以为 toSpliced 是 splice 的“安全版别名”——其实它不兼容旧环境(Node.js ≥19.5,Chrome ≥114),且没有副作用这个特性是硬编码进语言规范的,不是靠浅拷贝模拟出来的。
使用场景包括:React/Vue 中响应式更新需要不可变数据、函数式编程链式调用、避免意外污染共享数组引用。
toSpliced 的参数顺序和语义与 splice 完全一致,但不会改变 this 数组。
[1, 2, 3, 4].toSpliced(1, 2) → [1, 4](从索引 1 开始删 2 个)[1, 2, 3].toSpliced(1, 0, 'a', 'b') → [1, 'a', 'b', 2, 3](在索引 1 处插入)['a', 'b', 'c'].toSpliced(1, 1, 'x') → ['a', 'x', 'c']
注意:负数索引支持(如 -1 表示倒数第一个),行为与 splice 一致;deleteCount 超出剩余长度时,只删到末尾,不会报错。
三个高频翻车点:
@babel/plugin-transform-array-prototype-to-spliced 或手动降级为 slice+concat 组合[].toSpliced(0, 0, 1))是合法的,返回 [1];但若传入无效 start(如 NaN、undefined),会被强制转为 0,而非抛错[1, , 3])中,toSpliced 会保留空位(hole),这点和 splice 一致;但若用扩展运算符或 Array.from 手动实现,可能意外填充 undefined
如果项目需支持 IE 或老版本 Node.js,或需要更细粒度控制(比如自定义深拷贝逻辑),就别强依赖 toSpliced。
arr.slice(0, start).concat(arr.slice(start + deleteCount)).concat(inserts)
[...arr.slice(0, start), ...inserts, ...arr.slice(start)]
slice 对稀疏数组的处理和 toSpliced 并不完全等价(slice 会把 hole 变成 undefined)真正需要不可变更新又必须兼容旧环境时,建议封装一层工具函数,内部根据运行时特征自动选择原生方法或 polyfill 实现。