reverse() 直接修改原数组,需先拷贝再翻转;安全写法包括[...arr].reverse()、arr.slice().reverse()或深克隆后reverse()。

reverse() 会直接修改原数组,不是“展示顺序”操作
Array.prototype.reverse() 是就地(in-place)方法,调用后原始数组元素顺序立刻翻转,返回的也是该数组本身。它不生成新数组,也不管你是不是只想改 UI 展示——只要调了,源数据就变了。
常见错误现象:reverse() 调用后,后续其他逻辑读到的数组顺序已变,比如分页状态错乱、缓存命中失败、或 React 中因引用未变导致视图没更新(或相反,引用变了但你不希望它变)。
- 想“只改展示”,必须显式创建副本再翻转
- 不能依赖
reverse()的返回值来“假装没改原数组”——它返回的就是原数组 - 如果数组含对象,浅拷贝(如
[...arr].reverse())只复制引用,对象内部属性仍共享
安全翻转的三种写法及适用场景
核心原则:先拷贝,再 reverse()。但拷贝方式影响性能和语义:
-
简单值数组(number/string/boolean):用扩展运算符最直观 ——
[...arr].reverse() -
需要兼容旧环境(IE):用
arr.slice().reverse(),slice()不传参即浅拷贝 -
含嵌套对象且需深翻转(极少见):先
JSON.parse(JSON.stringify(arr))或用结构化克隆(structuredClone(arr),Chrome 98+),再reverse();但注意函数、undefined、Date 等会丢失
示例对比:
const original = [1, 2, 3]; const displayed = [...original].reverse(); // [3, 2, 1] console.log(original); // 仍是 [1, 2, 3] ✅
React/Vue 中容易忽略的引用陷阱
即使用了 [...arr].reverse(),如果在组件内反复调用(比如每次渲染都执行),可能触发不必要的重渲染或 memo 失效。更关键的是:如果原始数组是 props 或全局状态的一部分,而你在某处不小心对它调了 .reverse(),整个应用状态就污染了。
- 永远不要在
useEffect或计算属性里直接对传入的数组调reverse() - 推荐封装成纯函数:
const reversed = (arr) => [...arr].reverse(),明确输入输出 - Redux / Zustand 等状态管理中,禁止在 reducer 或 action 内修改传入的 state 数组
reverse() 和 sort() 混用时的典型误操作
有人想“倒序排序”,会写 arr.sort().reverse(),这看似合理,实则多了一次无意义的就地翻转。更糟的是,如果 sort() 已经改变了原数组,reverse() 又接着改——两次污染。
- 正确做法:用
sort()一次到位,例如数字倒序:[...arr].sort((a, b) => b - a) - 字符串倒序(按字典逆序):
[...arr].sort((a, b) => b.localeCompare(a)) - 如果真要先升序再翻转,也必须确保
sort()作用在副本上,如[...arr].sort().reverse()
真正需要 reverse() 的场景其实很窄:仅当你要保持原有排序逻辑(比如后端返回的“最新在前”需改成“最新在后”),又不想重写比较函数时才用。










