JavaScript中交换值的10种方法总结
本文总结了JavaScript中交换两个变量值的10种不同方法,涵盖使用临时变量、算术运算符、按位异或、数组赋值及ES6解构语法等技巧。文章详细分析了每种方法的原理、优缺点及在浮点数和无穷大值处理上的潜在问题,帮助开发者根据实际需求选择最合适的代码实现方式。
JavaScript交换变量值的10种技巧
前言
在开发过程中,我们经常需要对变量值进行交换。通常大家会采用“临时变量”这一简单方案,但实际上存在更多高效且多样的实现方式。很多时候,我们只是从网络搜索解决方案后直接复制粘贴,却很少深入思考代码背后的工作原理。现在,让我们深入了解如何轻松且高效地交换值。
使用临时变量
1 使用临时变量
这是最基础且直观的方法。
function swapWithTemp(num1,num2){
console.log(num1,num2)
var temp = num1;
num1 = num2;
num2 = temp;
console.log(num1,num2)
}
swapWithTemp(2.34,3.45)
使用算术运算符 + 和 -
2 使用算术运算符 + 和 -
我们可以利用数学运算的技巧来交换数值。
function swapWithPlusMinus(num1,num2){
console.log(num1,num2)
num1 = num1+num2;
num2 = num1-num2;
num1 = num1-num2;
console.log(num1,num2)
}
swapWithPlusMinus(2.34,3.45)
让我们分析其工作原理。第4行计算两个数字的总和。接着,如果从总和中减去其中一个数字,剩下的就是另一个数字的正确值,这正是第5行所执行的操作。从存储在num1变量中的总和中减去num2,即可得到原本存储在num2中的num1值。同理,在第6行中,通过类似操作即可恢复num2的值。
注意:还存在一种结合+和-的单行代码方案,但存在隐患……
具体实现如下:
function swapWithPlusMinusShort(num1,num2){
console.log(num1,num2)
num2 = num1+(num1=num2)-num2;
console.log(num1,num2)
}
swapWithPlusMinusShort(2,3)
上述代码看似能得出预期结果。括号内的表达式先将num2的值赋给num1,随后执行num1 - num2。由于此时num1已变为原num2的值,计算num1 - num2实际上等同于num2 - num2 = 0,因此最终结果看似正确。然而,当处理浮点数时,可能会观察到意想不到的错误结果。
请尝试执行以下代码并观察结果:
function swapWithPlusMinusShort(num1,num2){
console.log(num1,num2)
num2 = num1+(num1=num2)-num2;
console.log(num1,num2)
}
swapWithPlusMinusShort(2,3.1)
仅使用 + 或 - 运算符
3 仅使用 + 或 - 运算符
仅通过+运算符即可实现与同时使用+和-相同的效果。
参考以下代码:
function swapWithPlus(num1,num2){
console.log(num1,num2)
num2 = num1 + (num1=num2, 0)
console.log(num1,num2)
}
//Try with - operator
swapWithPlus(2.3,3.4)
上述代码虽然有效,但牺牲了可读性。在第4行的括号中,我们将num1赋值给num2,而旁边的0作为逗号运算符的返回值。简而言之,第4行的运算逻辑如下所示:
num2 = num1 + 0
=> num2 = num1.
从而得到正确结果。
注意:部分JavaScript引擎可能会对上述代码进行优化,从而忽略+ 0的操作。
使用算术运算符 * 和 /
4 使用算术运算符 * 和 /
让我们进一步利用*和/运算符进行尝试。
其原理与前一种方法类似,但存在一些小问题。
function swapWithMulDiv(num1,num2){
console.log(num1,num2)
num1 = num1*num2;
num2 = num1/num2;
num1 = num1/num2;
console.log(num1,num2)
}
swapWithMulDiv(2.34,3.45)
与上一个方法相同,首先计算两个数字的乘积并存储在num1中。然后在第5行,将num1与这个结果相除,即可得到第一个数字,重复此过程即可获得第二个数字。
现在你俨然是一位“数学家”了。
不过,问题究竟出在哪里呢?
让我们尝试一下:
function swapWithMulDiv(num1,num2){
console.log(num1,num2)
num1 = num1*num2;
num2 = num1/num2;
num1 = num1/num2;
console.log(num1,num2)
}
//试着改变数字的值,看看会发生什么
swapWithMulDiv(2.34,0)
我们的值并未交换,而是得到了一个奇怪的NaN(非数字)。这是怎么回事?如果你记得小学数学课的内容,就会明白不能除以0,因为这在数学上是无意义的。
再来看看这种方法的其他问题,请看下面的代码:
function swapWithMulDiv(num1,num2){
console.log(num1,num2)
num1 = num1*num2;
num2 = num1/num2;
num1 = num1/num2;
console.log(num1,num2)
}
//看看会发生什么
swapWithMulDiv(2.34,Infinity)
没错,结果依然是NaN。因为你无法使用Infinity(无穷大)去除任何值,这会导致未定义的行为。
但我还想再试一次:
function swapWithMulDiv(num1,num2){
console.log(num1,num2)
num1 = num1*num2;
num2 = num1/num2;
num1 = num1/num2;
console.log(num1,num2)
}
//会怎样呢
swapWithMulDiv(2.34,-Infinity)
-Infinity的结果与前一段代码相同,原因也是一样的。
事实证明,即使你是一位出色的“数学家”,也有无能为力的时候。
下面是使用*和/进行值交换的较短版本,同样存在上述问题:
function swapWithMulDivShort(num1,num2){
console.log(num1,num2)
num2 = num1*(num1=num2)/num2;
console.log(num1,num2)
}
swapWithMulDivShort(2.3,3.4)
上述代码类似于使用+和-进行交换时的短代码。将num2赋值给num1,然后第4行的演算逻辑如下:
num2 = num1 * num2 / num2
=> num2 = num1
这样两个值就互换了。
仅使用 * 或 / 运算符
5)仅使用 * 或 / 运算符
function swapWithMul(num1,num2){
console.log(num1,num2)
num2 = num1 * (num1=num2, 1)
console.log(num1,num2)
}
//Try with / and ** operator
swapWithMul(2.3,3.4)
上述程序有效,但牺牲了可读性。在第4行的括号中,我们将num1赋值给num2,旁边的1作为逗号运算符的返回值。简而言之,第4行的逻辑如下所示:
num2 = num1 * 1
=> num2 = num1
这样就得到了结果。
使用按位异或(XOR)
6 使用按位异或(XOR)。
XOR用于进行二进制位运算。当两个输入不同时,结果为1,否则为0。
| X | Y | X^Y |
|---|---|---|
| 1 | 1 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
先了解其工作原理!
function swapWithXOR(num1,num2){
console.log(num1,num2)
num1 = num1^num2;
num2 = num1^num2;
num1 = num1^num2;
console.log(num1,num2)
}
// 试试负值会怎样
swapWithXOR(10,1)
10的4位二进制数 -> 1010
1的4位二进制数 -> 0001
现在:
第四行:
num1 = num1 ^ num2
=> 1010 ^ 0001
=> 1011
=> 7
第五行:
num2 = num1 ^ num2
=> 1011 ^ 0001
=> 1010
=> 10
第六行:
num1 = num1 ^ num2
=> 1011 ^ 1010
=> 0001
=> 1
两个值交换了。
再来看另一个例子:
function swapWithXOR(num1,num2){
console.log(num1,num2)
num1 = num1^num2;
num2 = num1^num2;
num1 = num1^num2;
console.log(num1,num2)
}
swapWithXOR(2.34,3.45)
嗯??交换的值在哪儿?我们只是得到了数字的整数部分,这就是问题所在。XOR假定输入是整数,因此相应地执行计算。但是浮点数不是整数,而是由IEEE 754标准表示的,将数字分为三部分:符号位、代表指数的一组位和代表尾数的一组位。位数是介于1(含)和2(不含)之间的数字。所以得到的值不正确。
另一个例子:
function swapWithXOR(num1,num2){
console.log(num1,num2)
num1 = num1^num2;
num2 = num1^num2;
num1 = num1^num2;
console.log(num1,num2)
}
// 试试 infinities 和整数值.
swapWithXOR(-Infinity,Infinity)
毫无意外,我们没有得到预期的结果。这是因为Infinity和–Infinity都是浮点数。正如我们在前面所讨论的,对于XOR,浮点数是一个问题。
使用按位同或(XNOR)
7 使用按位同或 (XNOR)
它用于进行二进制位运算,但是与XOR正好相反。当有两个不同的输入时,XNOR的结果是0,否则结果为1。JavaScript没有执行XNOR的运算符,所以要用NOT运算符对XOR的结果求反。
| X | Y | XNOR |
|---|---|---|
| 1 | 1 | 1 |
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 0 | 1 |
先了解其工作原理:
function swapWithXNOR(num1,num2){
console.log(num1,num2)
num1 = ~(num1^num2);
num2 = ~(num1^num2);
num1 = ~(num1^num2);
console.log(num1,num2)
}
//可以试试负值
swapWithXNOR(10,1)
10的4位二进制数 -> 1010
1的4位二进制数 -> 0001
第4行:
num1 = ~(num1 ^ num2)
=> ~(1010 ^ 0001)
=>~(1011)
=> ~11
=> -12
由于这是一个负数,所以需要将其转换回二进制并计算2的补码来获取十进制值,例如:
-12 => 1100
=> 0011 + 1
=> 0100
第5行:
num2 = ~(num1 ^ num2)
=> ~(0100 ^ 0001)
=> ~(0101)
=> ~5
=> -6-6
=> 0110
=> 1001 + 1
=> 1010
=> 10
第6行:
num1 = ~(num1 ^ num2)
=> ~(0100^ 1010)
=> ~(1110)
=> ~14
=> -15-15
=> 1111
=> 0000 + 1
=> 0001
=> 1
花了一些时间,但还是交换了值。但不幸的是,它遇到了与XOR相同的问题,不能处理浮点数和无穷大。
试试下面的值:
function swapWithXNOR(num1,num2){
console.log(num1,num2)
num1 = ~(num1^num2);
num2 = ~(num1^num2);
num1 = ~(num1^num2);
console.log(num1,num2)
}
swapWithXNOR(2.3,4.5)
在数组中进行赋值
8 在数组中进行赋值
这是一线技巧。只需要一行代码就可以进行交换,更重要的是,无需数学运算,只需要数组的基本知识。不过它看上去可能很奇怪。
先让看看它的实际效果:
function swapWithArray(num1,num2){
console.log(num1,num2)
num2 = [num1, num1 = num2][0];
console.log(num1,num2)
}
swapWithArray(2.3,Infinity)
在数组的下标0位置中存储num1,在下标1中,既将num2分配给num1,又存储了num2。另外,我们只是访问[0],将数组中的num1值存储在num2中。而且可以在这里交换我们想要的任何东西,比如:整数、浮点数(包括无穷数)以及字符串。看上去很整洁,但是在这里失去了代码的清晰度。
使用解构表达式
9 使用解构表达式
这是ES6的功能。这是所有方法中最简单的。只需要一行代码就可以完成交换:
let num1 = 23.45;
let num2 = 45.67;
console.log(num1,num2);
[num1,num2] = [num2,num1];
console.log(num1,num2);
使用立即调用的函数表达式(IIFE)
10、使用立即调用的函数表达式(IIFE)
这是最奇怪的一个。简单的说IIFE是在定义后立即执行的函数。
可以用它来交换两个值:
function swapWithIIFE(num1,num2){
console.log(num1,num2)
num1 = (function (num2){ return num2; })(num2, num2=num1)
console.log(num1,num2)
}
swapWithIIFE(2.3,3.4)
在上面的例子中,在第4行立即调用一个函数。最后的括号是该函数的参数。第二个参数将num1赋值给num2,仅仅返回第一个参数,不过这种交换方法效率不高。
总结
本文探讨了用于在JavaScript中对值进行交换的众多方法。希望对你有所帮助!
到此这篇关于JavaScript中交换值的10种方法就介绍到这了,更多相关JavaScript交换值方法内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
JavaScript闭包与类(Class)的区别及适用场景对比
2026-11-05 15:48:57
JavaScript入门要学ES6吗?let与箭头函数等新特性解析
2026-11-05 14:49:16
JavaScript 8种数据类型详解:基本类型与引用类型的区别
2026-11-05 14:25:15
怎么在JavaScript中使用async/await优化Ajax异步流程
2026-11-05 13:56:15
JavaScript replace回调函数实现动态正则替换逻辑
2026-11-05 13:52:13
