javascript中会改变原数组的方法有push、pop、shift、unshift、splice、sort、reverse、fill等;es2023新增tosorted、toreversed、tospliced、with等非破坏性方法,返回新数组且不修改原数组。

核心区别在于:原地修改方法直接改变原始数组,而非破坏性方法始终返回新数组,原始数组保持不变。
哪些方法会改原数组
JavaScript 中明确会修改原数组的方法共 6 个:push、pop、shift、unshift、splice、sort;reverse 也属于这一类,但常被忽略。
- push() 在末尾添加元素,返回新长度,原数组变了
-
sort() 默认按字符串 Unicode 排序,
[10, 2, 30].sort()得到[10, 2, 30],不是数值升序 - splice() 参数顺序易错:起始索引、删除个数、插入项;漏掉第二个参数会清空后续所有元素
- reverse() 直接翻转原数组,调用后原数组顺序已不可逆
非破坏性方法怎么用更安全
新标准(ECMAScript 2023)引入的 toSorted、toReversed、toSpliced、with 都不碰原数组,适合状态敏感场景(如 React 的 useState)。
-
toSorted() 替代
slice().sort(),支持传入 compareFn:[3, 1, 2].toSorted((a, b) => a - b)→[1, 2, 3] -
toReversed() 替代
slice().reverse(),反转后原数组仍是原样 - toSpliced(start, deleteCount, ...items) 类似 splice,但返回新数组,原数组不动
-
with(index, value) 安全替换某一项:
[1,2,3].with(1, 99)→[1,99,3],比arr[1] = 99更可控
为什么避免原地修改很重要
在现代前端开发中,随意修改原数组容易引发隐性问题:
- React/Vue 等框架依赖数据变化触发更新,直接改 state 数组可能跳过响应式追踪,导致 UI 不同步
- 调试困难:无法回溯某个数组在某次操作前的状态
- 并发或异步逻辑中,多个函数同时调用
sort()或splice()可能互相干扰 - 函数式编程风格要求“不可变”,便于测试、时间旅行调试、状态快照等
兼容性与落地建议
这些新方法已在 Chrome 117+、Firefox 119+、Safari 17.4+ 和 Node.js 20.6+ 原生支持。旧环境可用轻量 polyfill:
if (!Array.prototype.toSorted) {
Array.prototype.toSorted = function (compareFn) { return this.slice().sort(compareFn); };
}
日常开发中,优先选用 toSorted 替代 sort,toReversed 替代 reverse,既语义清晰,又减少副作用。对老项目做渐进升级时,可先从状态更新逻辑入手——比如 useState 的更新函数里,统一用非破坏性方法构造新数组。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











