[a, b] = [b, a] 是基于 ES6 解构赋值的原始类型安全交换方式,先求值右侧数组缓存当前值,再按序解构赋值,无需临时变量,语义清晰、类型无差别兼容且性能优异。
直接用
[a, b] = [b, a]
就行。这是目前最安全、可读性最高、也最符合现代 JavaScript 语义的原始类型变量交换方式。
为什么它适合原始类型
原始类型(如 number、string、boolean、null、undefined)都可被安全放入数组,右侧
会在赋值前完整计算并缓存当前值,左侧按序解构,不依赖中间变量,也不改变原始值的求值顺序。
数字:
→
变为
,
变为
字符串:
→ 值互换无转换损耗
布尔值:
→ 直接交换,不转为数字
null/undefined:
→ 合法,但需确保右侧非
或
(否则报
)
必须满足的前提条件
解构交换不是“万能写即跑”,以下两点缺一不可:
变量必须已声明
:不能是未初始化状态,例如
会触发
,因为右侧
还未定义
右侧表达式必须可迭代
:即
的结果不能是
或
;若存在空值风险,可用空值合并操作符兜底:
const 声明的变量也能用吗
可以。即使写成
也是合法的——这不是对
变量“重新赋值”,而是通过解构绑定新值,ES 规范明确允许这种语法。
和其他方法比,它强在哪
相比加减法或异或法,解构对原始类型真正做到了“无差别兼容”:
加减法在
、
、大整数上会失效或精度丢失
异或法只适用于整数,遇到字符串或布尔就静默出错
解构不关心类型,只要能放进数组,就能交换;且语义清晰,调试友好,V8 等引擎也做了深度优化,性能与临时变量法基本一致
[b, a]let a = 10, b = -5; [a, b] = [b, a];a-5b10let x = "hello", y = "world"; [x, y] = [y, x];let p = true, q = false; [p, q] = [q, p];let m = null, n; [m, n] = [n, m];nullundefinedTypeError: undefined is not iterablelet a, b; [a, b] = [b, a];ReferenceErrorb[b, a]nullundefined[a, b] = [b ?? 0, a ?? 0]const a = "x", b = "y"; [a, b] = [b, a];constInfinityNaN