reverse()会直接修改原数组,是原地操作;需用[...arr].reverse()或arr.slice().reverse()创建新数组副本,避免副作用。

JavaScript数组的reverse()方法会直接修改原数组,而不是创建新数组。这是它和filter、map等纯函数方法的关键区别,也是容易引发bug的地方。
reverse()是原地操作,不返回新数组
调用arr.reverse()后,原数组元素顺序被彻底翻转,内存地址不变。返回值虽然是该数组本身(方便链式调用),但并非副本:
- 如果需要保留原数组,必须先用slice()或展开运算符复制一份
- 错误写法:
const newArr = arr.reverse()—— 此时arr和newArr指向同一数组,两者都已被反转 - 正确写法:
const newArr = [...arr].reverse()或const newArr = arr.slice().reverse()
对引用类型元素无深层影响
reverse()只改变数组项的排列顺序,不修改每个元素内部结构。若数组包含对象或嵌套数组,这些引用本身被移动位置,但其内容不受影响:
- 例如:
const arr = [{a:1}, {b:2}]; arr.reverse();→ 数组变成[{b:2}, {a:1}],但两个对象各自的属性未变化 - 不会触发对象深拷贝,也不会递归反转嵌套数组
与其他数组方法组合时需注意执行顺序
由于reverse()有副作用,在链式调用中它的位置决定最终结果:
-
[1,2,3].map(x => x * 2).reverse()→ 先映射成[2,4,6],再反转为[6,4,2] -
[1,2,3].reverse().map(x => x * 2)→ 先反转成[3,2,1],再映射为[6,4,2](巧合结果相同,逻辑不同) - 涉及filter等可能改变长度的操作时,顺序差异更明显,务必确认意图
在函数式编程场景中应避免直接使用
现代前端开发强调不可变性(immutability),尤其在React、Redux等场景下,直接修改原数组可能导致状态更新异常或渲染问题:
- 推荐用扩展运算符、slice()、from()等创建新数组后再反转
- 可封装安全版本:
const safeReverse = arr => [...arr].reverse() - TypeScript中reverse()的返回类型仍是T[],但实际行为是mutable,需靠编码规范或工具约束
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











