toSorted 是 ES2023 新增的数组方法,返回新排序数组而不修改原数组,与会改变原数组的 sort 本质不同;需注意兼容性、默认字符串排序、浅拷贝开销及 React 中浅比较问题。

toSorted 是什么,为什么不能直接替换 sort
toSorted 是 ES2023 新增的数组方法,它不修改原数组,而是返回一个**新排序后的数组**。这和 sort 的行为本质不同:sort 直接原地修改、返回原数组引用,而 toSorted 天然满足“无副作用”要求——你不用再手动 [...arr].sort() 或 arr.slice().sort()。
基本用法与 compareFn 的写法差异
和 sort 一样,toSorted 接收可选的 compareFn 参数,但行为完全一致:返回负数排前面、正数排后面、0 表示相等。唯一区别是它不改原数组。
常见场景示例:
const nums = [3, 1, 4, 1, 5]; const sorted = nums.toSorted((a, b) => a - b); // [1, 1, 3, 4, 5] console.log(nums); // 仍是 [3, 1, 4, 1, 5] —— 没变
注意点:
-
compareFn缺失时,默认按字符串 Unicode 码点排序([10, 2, 30]→[10, 2, 30],不是数值序) - 升序数值排序务必显式写
(a, b) => a - b;降序用(a, b) => b - a - 对象数组排序写法和
sort完全相同,例如arr.toSorted((a, b) => a.name.localeCompare(b.name))
兼容性问题与降级方案必须考虑
toSorted 在 Node.js 20.1+ 和现代浏览器(Chrome 117+、Firefox 119+、Safari 17.4+)才原生支持。旧环境会直接报 TypeError: arr.toSorted is not a function。
安全做法是运行时检测 + 降级:
const safeSorted = (arr, compareFn) => {
return typeof arr.toSorted === 'function'
? arr.toSorted(compareFn)
: [...arr].sort(compareFn);
};如果你用 TypeScript,还需在 lib 配置中加入 es2023,否则类型检查会报错。
性能影响:浅拷贝开销比你想象的小,但别滥用
toSorted 内部必然做一次浅拷贝(类似 slice()),再对副本排序。对于小数组(items.toSorted(...)),就可能成为瓶颈。
此时更合理的做法是:
- 只在数据真正变更后重新排序(配合
useMemo或响应式依赖追踪) - 对超大数组(>10k),优先考虑服务端排序或虚拟滚动,而非前端全量
toSorted - 避免链式调用如
arr.toSorted().filter().map()——中间数组无法复用,GC 压力上升
真正的麻烦往往不在语法是否正确,而在没意识到 toSorted 返回的是新引用——如果你把它赋给 React state 后又用 === 做浅比较判断更新,那每次都会触发重渲染,哪怕内容完全一样。

















