toReversed() 更适合不可变场景,因其返回新数组且不修改原数组,而 reverse() 会直接修改原数组;它在 React、Redux 等场景中可避免副作用,但仅支持现代环境,需 polyfill 或降级处理。

为什么 toReversed() 比 reverse() 更适合不可变场景
reverse() 会直接修改原数组并返回它,破坏不可变性;而 toReversed() 是 ES2023 新增的纯函数,始终返回一个**新数组**,原数组完全不受影响。这在 React、Redux 或函数式编程中避免意外副作用很关键。
常见错误现象:const arr = [1, 2, 3]; const reversed = arr.reverse(); console.log(arr); // [3, 2, 1] —— 原数组被改了
- 使用场景:需要反转但后续还要用原数组(比如 UI 同时展示正序列表和倒序摘要)
- 兼容性注意:Node.js ≥ 20.1,Chrome ≥ 117,Firefox ≥ 116,Safari ≥ 17.4;旧环境需 polyfill 或降级为
[...arr].reverse() - 性能差异:
toReversed()内部仍需遍历+新建数组,时间复杂度 O(n),和[...arr].reverse()基本一致,但语义更清晰
如何安全地在不支持的环境中 fallback
不能直接调用 toReversed() 然后指望它自动降级——浏览器报 TypeError: arr.toReversed is not a function 就挂了。
实操建议:检测方法是否存在,再选择实现路径:
const safeToReversed = (arr) => {
if (typeof arr.toReversed === 'function') {
return arr.toReversed();
}
return [...arr].reverse();
};
- 不要用
try/catch包裹调用——异常成本高,且无法区分是方法不存在还是其他错误 - 避免在循环中反复检测:可提前缓存判断结果,或用构建工具(如 Babel)自动注入 polyfill
- 注意:Polyfill 实现不能简单覆盖
Array.prototype.toReversed,需确保不污染全局且符合规范(例如处理稀疏数组、symbol 键等边界)
toReversed() 对稀疏数组和类数组对象的行为
它只作用于标准数组(Array.isArray(arr) === true),对类数组对象(如 arguments、NodeList)无效,也不会自动转换。
常见错误现象:[...document.querySelectorAll('div')].toReversed() 可以,但 document.querySelectorAll('div').toReversed() 报错
- 稀疏数组(如
const arr = [1, , 3])会被正确处理:空位保留,结果为[3, , 1] - TypedArray(如
Uint8Array)不支持toReversed(),必须先转成普通数组或用slice().reverse() - 如果传入非数组(
null、undefined、字符串),直接抛TypeError,和reverse()行为一致
和其它不可变反转写法对比:什么时候选哪个
toReversed() 是最直白的选择,但实际项目中可能已有惯用模式。关键看是否要兼顾老环境或特殊类型。
- 仅现代环境 + 纯数组 → 无脑用
arr.toReversed() - 需兼容 IE 或 Node.js [...arr].reverse()(简洁)或
Array.from(arr).reverse()(更明确) - 处理
Uint32Array等类型 → 必须用Array.from(typedArr).reverse()或手动循环构造新数组 - 注意:
arr.slice().reverse()在某些旧引擎中比展开运算符稍快,但差异微乎其微,可忽略
容易被忽略的一点:所有这些方法都只做浅拷贝。如果数组元素是对象,反转后它们的引用不变——不可变的是数组结构,不是内部值。

















