如何通过ES2023的Array.prototype.with()方法在不破坏数组不可变性的前提下替换特定索引的元素?
- 内容介绍
- 相关推荐
本文共计1139个文字,预计阅读时间需要5分钟。
`with + () 是 ES2023 新增的不变性数组方法,它不会改变原数组,而是返回一个新数组,其中仅将指定索引位置的值替换为给定的值。这与手写的方式(如 `[...arr.slice(0, i), newValue, ...arr.slice(i + 1)]`)相比,更简洁、语义更清晰。
常见错误是误以为它支持负数索引或范围检查——它不校验索引合法性:传入 -1 或 arr.length + 1 不会报错,但行为等价于在该位置插入(即可能扩展数组)。
- 只接受两个参数:
index(数字)和value(任意值) - 若
index超出[0, arr.length)范围,结果数组长度会相应变化(如arr.with(5, x)在长度为 3 的数组上调用,返回长度为 6 的数组,末尾补undefined) - 不触发 getter/setter,也不调用
toString()等隐式转换,纯值替换
与 map() 和展开运算符对比:什么场景该选 with()
当只需要改一个已知索引的元素时,with() 比 map() 更轻量:它不遍历整个数组,内部实现可直接构造新数组并复制引用;而 map() 必须走完整迭代流程,即使你用 if (i === target) return newVal; else return item; 也逃不开开销。
本文共计1139个文字,预计阅读时间需要5分钟。
`with + () 是 ES2023 新增的不变性数组方法,它不会改变原数组,而是返回一个新数组,其中仅将指定索引位置的值替换为给定的值。这与手写的方式(如 `[...arr.slice(0, i), newValue, ...arr.slice(i + 1)]`)相比,更简洁、语义更清晰。
常见错误是误以为它支持负数索引或范围检查——它不校验索引合法性:传入 -1 或 arr.length + 1 不会报错,但行为等价于在该位置插入(即可能扩展数组)。
- 只接受两个参数:
index(数字)和value(任意值) - 若
index超出[0, arr.length)范围,结果数组长度会相应变化(如arr.with(5, x)在长度为 3 的数组上调用,返回长度为 6 的数组,末尾补undefined) - 不触发 getter/setter,也不调用
toString()等隐式转换,纯值替换
与 map() 和展开运算符对比:什么场景该选 with()
当只需要改一个已知索引的元素时,with() 比 map() 更轻量:它不遍历整个数组,内部实现可直接构造新数组并复制引用;而 map() 必须走完整迭代流程,即使你用 if (i === target) return newVal; else return item; 也逃不开开销。

