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
相关产品推荐
相关产品推荐

