toSorted 是 ES2023 新增的不可变排序方法,返回新数组而不修改原数组,比会改变原数组的 sort 更安全,尤其在 React/Vue 等响应式框架中可避免意外 re-render 或状态错乱。

toSorted 是什么,为什么它比 sort 更安全
toSorted 是 ES2023 新增的数组方法,它的核心作用就是「返回排序后的新数组,不修改原数组」。而 sort 默认就地排序——哪怕你只是想看个结果,原数组也已经面目全非了。这在 React、Vue 的响应式场景里特别危险,一不小心就触发意料外的 re-render 或状态错乱。
它和 slice().sort() 行为一致,但更语义清晰、写法更短,且底层实现可能有优化(比如 V8 对小数组做了 fast-path)。
基本用法和常见错误写法
直接调用 toSorted() 会按字符串 Unicode 码点升序排,这对数字数组是灾难性的:[10, 2, 30].toSorted() 得到 [10, 2, 30](因为 "10" 为 true)。这不是 bug,是设计如此。
- 要按数值升序:用
toSorted((a, b) => a - b) - 要降序:用
toSorted((a, b) => b - a) - 对象数组按字段排:用
toSorted((a, b) => a.name.localeCompare(b.name)) - 千万别写成
arr.toSorted().sort(...)—— 多此一举还可能破坏不可变性
兼容性与降级方案
目前 Chrome 117+、Firefox 120+、Safari 17.4+ 原生支持 toSorted;Node.js 20.2+ 起可用。旧环境会报 TypeError: arr.toSorted is not a function。
如果必须兼容老浏览器或 Node.js 18 及以下:
- 最简降级:用
[...arr].sort(comparator)(注意解构比slice()更常用,也更直观) - 想封装统一 API:可以给
Array.prototype添加 polyfill,但需先检测是否已存在toSorted - 用 Lodash?没必要——
_.sortBy(arr, 'field')返回新数组,但引入整个库只为一个功能太重
和 toReversed、toSpliced 等新方法的共性注意点
toSorted 和 toReversed、toSpliced 都属于“不可变数组方法”家族,它们都满足:不改原数组、返回新数组、接受可选 comparator/参数、对稀疏数组保持稀疏性(即 [1, , 3].toSorted() 仍为长度 3 的稀疏数组)。
容易被忽略的是:它们都不处理 undefined 或 NaN 的特殊排序逻辑——比如 [NaN, 1, undefined].toSorted() 在不同引擎中行为可能不一致,建议提前过滤或映射。

















