一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何在不修改原始数据的前提下用 Array.prototype.toSpliced 获取增删元素后的新数组

时间:2026-07-19 18:17:59 编辑:袖梨 来源:一聚教程网

toSpliced 是 ES2023 新增的纯函数式数组方法,不修改原数组而返回新数组;splice 则直接修改原数组。二者参数一致,但 toSpliced 支持负索引、不接受负 deleteCount,需注意兼容性与浅拷贝特性。

toSpliced 是什么,和 splice 有什么根本区别toSpliced 是 ES2023 新增的数组方法,核心价值就是「不修改原数组、返回新数组」。而 splice 是就地修改——调用后原数组直接被改写,想保留原始数据就得先 slice() 或展开复制,容易漏写或写错。toSpliced 的参数签名和 splice 完全一致:toSpliced(start, deleteCount, ...items),但行为是纯函数式的:只读取原数组,构造并返回一个新数组。

常见错误现象:有人误以为 toSplicedsplice 的别名,或者在旧环境(如 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]
  • 如果原数组是 frozen(Object.freeze(arr)),toSpliced 仍能工作,因为它不修改原数组

真正容易被忽略的是:它不处理嵌套引用。如果你删掉的是一个对象,新数组里那个对象仍是同一引用——深拷贝得另外做,toSpliced 不负责这个。

热门栏目