关于javascript:在-JavaScript-中交换值的-10-种方法

32次阅读

共计 5828 个字符,预计需要花费 15 分钟才能阅读完成。

作者:Piyush Kochhar

翻译:疯狂的技术宅

原文:https://codeburst.io/10-ways-…

未经容许严禁转载

在开发过程中又是咱们须要对值进行替换。个别咱们都在用一种简略的解决方案:“长期变量”。不过还有更好的方法,而且不只有一个,有很多。有时咱们在网上搜查解决方案,找到后复制粘贴,然而从没想过这小段代码是怎么工作的。当初咱们该学习一下应该怎么轻松高效地替换值了。

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 行的 num1 中失去 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,除了减去 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 行,把 num2 与这个后果相除,失去第一个数字,而后反复此过程以取得第二个数字。

当初你成“数学家”了。

不过那小问题在哪儿呢?

让咱们来尝试一下:

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

这样就失去了后果。

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,浮点数是一个问题。

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);

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 中对值进行替换的泛滥办法。心愿对你有所帮忙!


本文首发微信公众号:前端先锋

欢送扫描二维码关注公众号,每天都给你推送陈腐的前端技术文章

欢送持续浏览本专栏其它高赞文章:

  • 深刻了解 Shadow DOM v1
  • 一步步教你用 WebVR 实现虚拟现实游戏
  • 13 个帮你进步开发效率的古代 CSS 框架
  • 疾速上手 BootstrapVue
  • JavaScript 引擎是如何工作的?从调用栈到 Promise 你须要晓得的所有
  • WebSocket 实战:在 Node 和 React 之间进行实时通信
  • 对于 Git 的 20 个面试题
  • 深刻解析 Node.js 的 console.log
  • Node.js 到底是什么?
  • 30 分钟用 Node.js 构建一个 API 服务器
  • Javascript 的对象拷贝
  • 程序员 30 岁前月薪达不到 30K,该何去何从
  • 14 个最好的 JavaScript 数据可视化库
  • 8 个给前端的顶级 VS Code 扩大插件
  • Node.js 多线程齐全指南
  • 把 HTML 转成 PDF 的 4 个计划及实现

  • 更多文章 …

正文完
 0