如何在 JavaScript 中交换两个变量

IT技术 javascript variables swap
2021-01-17 04:31:05

我有这两个变量:

var a = 1,
    b = 2;

我的问题是如何交换它们?只有这个变量,没有任何对象。

6个回答

这是一个用于交换两个变量值的单行程序。
给定变量ab

b = [a, a = b][0];

演示如下:

var a=1,
    b=2,
    output=document.getElementById('output');

output.innerHTML="<p>Original: "+a+", "+b+"</p>";

b = [a, a = b][0];

output.innerHTML+="<p>Swapped: "+a+", "+b+"</p>";
<div id="output"></div>

@FrançoisWahl 好点。我认为这里的大多数答案都会起作用并且相当等效。我想这是临时变量使用、代码量和速度之间的权衡。
2021-03-29 04:31:05
+1。但最短的版本将在 ECMAScript 6: 中[a, b] = [b, a];
2021-03-31 04:31:05
@showdev 阅读 Ted Hopp 回答中的 Dijkstra 引述。
2021-04-02 04:31:05
@FrançoisWahl 好吧,我没想到这个解决方案会慢得多。另见:jsperf.com/swap-array-vs-variable/3
2021-04-08 04:31:05
@Kay:使用数组而不是第三个变量似乎也慢得多:http : //jsperf.com/swap-array-vs-variable我只在 Chrome 中测试过这个。我还无法测试 ECMAScript 6 版本,因为它目前出现Invalid left-hand side in assignment 错误。
2021-04-10 04:31:05

ES6(Firefox 和 Chrome 已经支持(解构赋值数组匹配)):

let a = 5, b = 6;
[a, b] = [b, a];
console.log(`${a} ${b}`);

有人知道 es6 中这种交换的名称吗?
2021-03-18 04:31:05
@derek - 我认为它被称为数组匹配,一种解构赋值的形式
2021-03-22 04:31:05
从 V8 版本 6.8 开始,使用数组解构交换变量应该与使用临时变量 ( v8project.blogspot.com/2018/06/v8-release-68.html )一样快
2021-03-29 04:31:05
2021-04-02 04:31:05
这似乎比 nodejs 7.4.0/win7 64 上的第三个变量方法慢 35 倍。但它确实很整洁。
2021-04-10 04:31:05

你可以这样做:

var a = 1,
    b = 2,
    tmp;
tmp = a;
a = b;
b = tmp;

对于可读性和可维护性,这是无可匹敌的(至少在 JavaScript 中)。任何维护代码的人(包括六个月后的您)都会确切地知道发生了什么。

由于这些是整数,您还可以使用任意数量的巧妙技巧1进行交换,而无需使用第三个变量。例如,您可以使用按位异或运算符:

let a = 1, b = 2;
a = a ^ b;
b = a ^ b;
a = a ^ b;
    
console.log('a is now:', a);
console.log('b is now:', b);

这称为 XOR 交换算法。它的操作理论在这篇维基百科文章中有所描述

1 “称职的程序员完全意识到自己头骨的有限大小。因此,他以完全谦逊的态度对待自己的任务,并避免像瘟疫一样聪明的把戏。” — Edsger W. Dijkstra

@TedHopp 足够公平。我的意思是“有效”,因为你可以向它抛出任何数据类型,而不是像它那样作为一个好的交换解决方案。我同意它一般来说不是很有用。
2021-03-15 04:31:05
这个技巧适用于任何数据类型,只要你不介意整数结果;这些值会自动转换为 int32s。这意味着它可以处理数字字符串、布尔值 (0/1)、空值 (0) 和空数组/对象 (0)。尽管原始类型没有保留,因此受影响的布尔值不能与typeof a == 'boolean'or 一起使用a === false,例如。实数有效,除了它们向零倾斜而不是四舍五入到最接近的整数。
2021-03-18 04:31:05
@RobertGrant - JavaScript 中的 xor 运算符将其操作数转换为 32 位整数(使用ToInt32内部方法 - 请参阅ECMAScript 标准的第 11.10 节)。对于非整数数值,它不会产生正确的结果。它还可以将非数字值转换为 32 位整数。如果你开始a = "hi"b = "there"你结束了a == 0b == 0
2021-03-21 04:31:05
@Beejor - 换句话说,它适用于任何数据类型,除非它不适用(除非它们是整数值)。在我的书中,“交换”的意思是“以每个变量具有另一个具有的值结束”,而不是“转换为 int32 然后交换”。
2021-03-27 04:31:05
Xor 适用于任何数据类型。这是只适用于数字的减法技巧。
2021-04-10 04:31:05

不要使用下面的代码。不是交换两个变量值的推荐方法(只需为此使用临时变量)。它只是展示了一个 JavaScript 技巧。

这个解决方案不使用临时变量,不使用数组,只添加一个,而且速度很快事实上,它有时比多个平台上的临时变量更快
它适用于所有数字,从不溢出,并处理诸如 Infinity 和 NaN 之类的边缘情况。

a = b + (b=a, 0)

它分两步工作:

  • (b=a, 0)设置b为旧值a并产生0
  • a = b + 0设置a为旧值b
我认为这仅适用于数值是否正确?您不能将它与例如 var a ="hello" b="world" as a="world0" 一起使用。
2021-03-19 04:31:05
@ChrisGWGreen: a = b + (b=a, "")
2021-03-29 04:31:05
括号中的操作符是逗号操作符,,它已被包装以设置正确的优先级。逗号运算符计算它的两个参数(在本例中为b=a0)并返回最后一个(在本例中为0)。所以在这里,它具有将新b设置为旧值的效果a,同时产生0
2021-04-02 04:31:05
temp var 版本稍微快一点,也更通用和更易读。jsperf.com/swap-two-numbers-without-tmp-var/9
2021-04-06 04:31:05
这个 () 语法是什么意思?它如何产生0?
2021-04-12 04:31:05

从 ES6 开始,您还可以更优雅地交换变量:

var a = 1,
    b = 2;

[a, b] = [b, a];

console.log('a:', a, 'b:', b); // a: 2 b: 1