JavaScript 交換值的奇思妙想

做者:piyush-kochhar
譯者:前端小智
來源:hackernoon
點贊再看,微信搜索 【大遷世界】 關注這個沒有大廠背景,但有着一股向上積極心態人。本文 GitHub https://github.com/qq44924588... 上已經收錄,文章的已分類,也整理了不少個人文檔,和教程資料。

你們都說簡歷沒項目寫,我就幫你們找了一個項目,還附贈【搭建教程】javascript

早期以前,在 JS 中交換值,咱們主要仍是使用臨時變量。ES6 以後,咱們可使用展開運算符號來交換變量,除了這兩種方式,你還能想到哪些呢? 😱前端

本文主要介紹 交換變量的 10 種方法,請過目 😯java

1. 使用臨時變量

function swapWithTemp(num1, num2) {
  console.log(num1, num2)

  let temp = num1
  num1 = num2
  num2 = temp

  console.log(num1, num2)
}

swapWithTemp(66.66, 8.88)

2. 使用算術運算符+-

function swapWithPlusMinus(num1, num2){
  console.log(num1, num2)

  num1 = num1 + num2
  num2 = num1 - num2
  num1 = num1 - num2

  console.log(num1, num2)
}

swapWithPlusMinus(66, 8)

主要的過程是這樣的,先求出兩個數的和,那麼第二個數要換友第一個數的的值就是總的和減去第二個,也就是代碼中的 num2 = num1-num2,同理,第一個數要換成第二個數的值,就是總的和減去第一個數的值,如今第一個數已是賦值給第二個數,因此直接減去第二數的值便可,也就是 num1 = num1-num2 💪git

但我試了一下小數,好像有點問題,有點尷尬 😓,但這種思想咱們仍是要掌握的 😙github

上面還能夠這樣來簡寫 👏:數組

function swapWithPlusMinusShort(num1, num2){
  console.log(num1, num2)

  num2 = num1 + (num1 = num2) - num2

  console.log(num1, num2)
}

這裏的技巧在於 (num1 = num2) ,這步,咱們讓 num1 等於 num2 了,而且返回是 num2 的值,此時 num1 值已交換。 接着就用 num1 加上 (num1 = num2) 返回的值,也就是 num1 + num2 求和,而後思路就和上面分析的同樣了 🙌。微信

可是,使用浮點數時,也會獲得一些意外的結果 😵函數

你能夠在控制檯跑跑下面這段代碼:工具

function swapWithPlusMinusShort(num1, num2){
  console.log(num1, num2)

  num2 = num1 + (num1 = num2) - num2

  console.log(num1, num2)
}

swapWithPlusMinusShort(2,3.1)

3.僅使用+-運算符

只要使用+運算符,就能夠獲得與同時使用+-同樣的結果 👀。spa

function swapWithPlus(num1, num2){
  console.log(num1, num2)

  num2 = num1 + (num1=num2, 0)

  console.log(num1, num2)
}

swapWithPlus(2.3,3.4)

上面的程序能夠工做,但犧牲了可讀性。在()中,咱們將num1分配給num2,旁邊的0是返回值。簡而言之,第4行看起來是這樣的 ✍:

num2 = num1 + 0 => num2 = num1

4. 使用算術運算符*/

*/的原理與先前的方法相同,只是有一些微小的區別 😎。

function swapWithMulDiv(num1, num2){
  console.log(num1, num2)

  num1 = num1*num2
  num2 = num1/num2
  num1 = num1/num2

  console.log(num1, num2)
}

swapWithMulDiv(2.3,3.4)

與上一個相同。 咱們獲得兩個數字的乘積並將它們存儲在其中一個變量中,對應就是 num1 = num1*num2。而後,用總數除了對應的變量,獲得交換後變量的值 😄。

但這個有些問題是什麼呢?就是,若是有交換值有 0 就會獲得意想不到的問題 😕:

swapWithMulDiv(2.34,0)
// 2.34 0
// NaN NaN

咱們的值沒有交換,而是獲得一個奇怪的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)
// 2.34 Infinity
// NaN NaN

又是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)

  num1 = num1*num2
  num2 = num1*(num1=num2)/num2
  num1 = num1/num2

  console.log(num1, num2)
}

swapWithMulDivShort(2.3,3.4)

5. 僅使用*/運算符

上面的程序能夠工做,但犧牲了可讀性。在()中,咱們將num1分配給num2,旁邊的1`是返回值。num2 = num1 * (num1=num2, 1)`看起來是這樣的:

num2 = num1 * 1 => num2 = num1

6. 使用按位異或

異或是按二進制位來工做,當咱們有兩個值不同時,它的結果爲1,不然爲0:

clipboard.png

function swapWithXOR(num1, num2){
  console.log(num1, num2)

  num1 = num1^num2;
  num2 = num1^num2; 
  num1 = num1^num2;

  console.log(num1, num2)
}

swapWithXOR(10,1)

4位二進制數10-> 1010

4位二進制數1-> 0001

上面的分解過程 👍:

num1 = num1 ^ num2 = 1010 ^ 0001 = 1011
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)
// 2.34 3.45
// 3 2

嗯?交換的值在哪裏?咱們只獲得這個數的整數部分。這就是問題所在。異或假設輸入是整數,所以執行相應的計算。可是浮點數不是整數,而且由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)
}

swapWithXOR(-Infinity,Infinity)
// -Infinity Infinity
// 0 0

再一次,咱們沒有看到預期的結果 😱。 這是由於Infinity–Infinity都是浮點數。 正如咱們上面討論的,對於XOR,浮點數是一個問題。

  1. 使用同或門 XNOR

同或門也稱爲異或非門,它也能夠操做二進制位,與XOR相反。當咱們有兩個值不同時,XNOR 結果是0,不然爲1。JavaScript 沒有一個操做符來執行XNOR,因此咱們使用XOR操做符來達到相似的效果。

clipboard.png

function swapWithXNOR(num1, num2){
  console.log(num1, num2)

  num1 = ~(num1^num2)
  num2 = ~(num1^num2)
  num1 = ~(num1^num2)

  console.log(num1, num2)
}

swapWithXNOR(10,1)

4位二進制數10-> 1010

4位二進制數1-> 0001

上面的分解過程 👍:

num1 = ~(num1 ^ num2) => ~(1010 ^ 1011)=> ~(1011) => ~11 => -12

因爲咱們有一個負數,咱們須要將其轉換回二進制並執行2的補碼以獲取十進制值,例如:

-12 => 1100 => 0011 + 1 => 0100
num2 = ~(num1 ^ num2) => ~(0100 ^ 0001) => ~(0101) => ~5 => -6

-6 => 0110 => 1001 + 1 => 1010 => 10
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)
// 2.3 4.5
// 4 2

8. 在數組中賦值

這是一個簡單的技巧,只須要一行來執行交換,更重要的是不須要數學知識,只須要一個基本的數組知識便可。

function swapWithArray(num1, num2){
  console.log(num1, num2)

  num2 = [num1, num1 = num2][0]

  console.log(num1, num2)
}

swapWithArray(2.3,Infinity)

// 2.3 Infinity
// Infinity 2.3

在數組的索引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,第一個參數num1被返回。所以,交換了這些值,請記住,這種交換方法效率不高。


代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

原文:https://hackernoon.com/how-to...

交流

文章每週持續更新,能夠微信搜索 【大遷世界 】 第一時間閱讀,回覆 【福利】 有多份前端視頻等着你,本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,歡迎Star。

相關文章
相關標籤/搜索