You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript如何以不可变方式在数组指定索引位置插入元素

JavaScript 实现不可变版 splice 功能

核心实现思路

原生splice会直接修改原数组,要实现不可变效果,只需基于原数组切片拼接生成新数组,全程不操作原数组本身。


方案1:独立工具函数(推荐,无原型污染风险)

function immutableSplice(arr, start, deleteCount, ...insertItems) {
  return [
    ...arr.slice(0, start),
    ...insertItems,
    ...arr.slice(start + deleteCount)
  ]
}

测试效果:

const arr = [1,2,3,4,5,6]
const arr2 = immutableSplice(arr, 2, 0, 'a')

console.log(arr) // [1,2,3,4,5,6] 原数组无变化
console.log(arr2) // [1,2,'a',3,4,5,6] 符合预期

方案2:挂载到Array原型(匹配示例中的调用方式)

注意:直接修改内置对象原型存在命名冲突风险,非必要不推荐使用

// 先判断是否已存在该方法,避免覆盖
if (!Array.prototype.specialSplice) {
  Array.prototype.specialSplice = function(start, deleteCount, ...insertItems) {
    return [
      ...this.slice(0, start),
      ...insertItems,
      ...this.slice(start + deleteCount)
    ]
  }
}

测试效果:

const arr = [1,2,3,4,5,6]
const arr2 = arr.specialSplice(2, 0, 'a')

console.log(arr) // [1,2,3,4,5,6] 原数组无变化
console.log(arr2) // [1,2,'a',3,4,5,6] 符合预期

兼容原生splice参数规则的完整版

如果需要完全对齐原生splice的参数处理逻辑(比如负索引、deleteCount省略/负数等边界情况),可以使用以下实现:

function immutableSplice(arr, start, deleteCount, ...insertItems) {
  // 处理负索引:负数表示从数组末尾倒数
  const actualStart = start < 0 
    ? Math.max(arr.length + start, 0) 
    : Math.min(start, arr.length)

  // 处理deleteCount边界:未传则删除start之后所有元素,负数视为0
  const actualDeleteCount = deleteCount === undefined
    ? arr.length - actualStart
    : Math.max(Math.min(deleteCount, arr.length - actualStart), 0)

  return [
    ...arr.slice(0, actualStart),
    ...insertItems,
    ...arr.slice(actualStart + actualDeleteCount)
  ]
}

内容的提问来源于stack exchange,提问作者Soumya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 21:12:00