<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JavaScript 交換值的奇思妙想

          共 5513字,需瀏覽 12分鐘

           ·

          2020-09-24 05:40

          (給前端大學(xué)加星標(biāo),提升前端技能.

          作者:前端小智

          https://juejin.im/post/687361199923894682

          早期之前,在 JS 中交換值,我們主要還是使用臨時(shí)變量。ES6 之后,我們可以使用展開運(yùn)算符號(hào)來交換變量,除了這兩種方式,你還能想到哪些呢?
          今天,這篇文章將介紹交換變量的10 種方法,請(qǐng)各位過目。

          1、使用臨時(shí)變量

          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、使用算術(shù)運(yùn)算符+-

          function swapWithPlusMinus(num1, num2){ console.log(num1, num2)
          num1 = num1 + num2 num2 = num1 - num2 num1 = num1 - num2
          console.log(num1, num2)}
          swapWithPlusMinus(66, 8)
          主要的過程是這樣的,先求出兩個(gè)數(shù)的和,那么第二個(gè)數(shù)要換友第一個(gè)數(shù)的的值就是總的和減去第二個(gè),也就是代碼中的 num2 = num1-num2,同理,第一個(gè)數(shù)要換成第二個(gè)數(shù)的值,就是總的和減去第一個(gè)數(shù)的值,現(xiàn)在第一個(gè)數(shù)已經(jīng)是賦值給第二個(gè)數(shù),所以直接減去第二數(shù)的值即可,也就是 num1 = num1-num2?。
          但我試了一下小數(shù),好像有點(diǎn)問題,有點(diǎn)尷尬 ,但這種思想我們還是要掌握的 。
          上面還可以這樣來簡寫 :
          function swapWithPlusMinusShort(num1, num2){ console.log(num1, num2)
          num2 = num1 + (num1 = num2) - num2
          console.log(num1, num2)}
          這里的技巧在于 (num1 = num2) ,這步,我們讓 num1 等于 num2 了,并且返回是 num2 的值,此時(shí) num1 值已交換。接著就用 num1 加上 ? (num1 = num2) 返回的值,也就是 num1 + num2 求和,然后思路就和上面分析的一樣了 。
          但是,使用浮點(diǎn)數(shù)時(shí),也會(huì)得到一些意外的結(jié)果?
          你可以在控制臺(tái)跑跑下面這段代碼:
          function swapWithPlusMinusShort(num1, num2){ console.log(num1, num2)
          num2 = num1 + (num1 = num2) - num2
          console.log(num1, num2)}
          swapWithPlusMinusShort(2,3.1)

          3、僅使用+或-運(yùn)算符

          只要使用+運(yùn)算符,就可以得到與同時(shí)使用+和-一樣的結(jié)果。
          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、?使用算術(shù)運(yùn)算符*和/

          *和/的原理與先前的方法相同,只是有一些微小的區(qū)別 。
          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)
          與上一個(gè)相同。我們得到兩個(gè)數(shù)字的乘積并將它們存儲(chǔ)在其中一個(gè)變量中,對(duì)應(yīng)就是 num1 = num1*num2。然后,用總數(shù)除了對(duì)應(yīng)的變量,得到交換后變量的值。
          但這個(gè)有些問題是什么呢?就是,如果有交換值有 0 就會(huì)得到意想不到的問題 :
          swapWithMulDiv(2.34,0)// 2.34 0// NaN NaN
          我們的值沒有交換,而是得到一個(gè)奇怪的NaN。那是怎么回事?如果你還記得你的數(shù)學(xué)課,我們總是被告知不要除以0因?yàn)樗俏炊x。
          原因在于極限是如何起作用的,還有一些其他的原因,我們不會(huì)涉及?,F(xiàn)在,讓我們看看這個(gè)方法的其他問題:
          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,因?yàn)槲覀儾荒苡肐nfinity除以任務(wù)內(nèi)容,因此未定義 。
          如果是負(fù)無窮大呢,結(jié)果又會(huì)是怎么樣 :
          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的結(jié)果與前面的示例相同,原因也是一樣的。
          下面是上面的一個(gè)簡寫方式,當(dāng)然存在問題也是一樣的:
          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、僅使用*或/運(yùn)算符

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

          6、使用按位異或

          異或是按二進(jìn)制位來工作,當(dāng)我們有兩個(gè)值不一樣時(shí),它的結(jié)果為1,否則為
          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)
          4位二進(jìn)制數(shù)10-> 1010
          4位二進(jìn)制數(shù)1-> 0001
          上面的分解過程 :
          num1 = num1 ^ num2 = 1010 ^ 0001 = 1011num2 = num1 ^ num2 = 1011 ^ 0001 => 1010 => 10num1 = num1 ^ num2 = 1011 ^ 1010 => 0001 => 1
          我們來看另一個(gè)例子。
          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
          嗯?交換的值在哪里?我們只得到這個(gè)數(shù)的整數(shù)部分。這就是問題所在。異或假設(shè)輸入是整數(shù),因此執(zhí)行相應(yīng)的計(jì)算。
          但是浮點(diǎn)數(shù)不是整數(shù),并且由IEEE 754標(biāo)準(zhǔn)來表示,該標(biāo)準(zhǔn)將數(shù)字分為三部分:一個(gè)符號(hào)位、一組表示指數(shù)的位以及另一組表示1(包括)到2(不包括)之間的數(shù)字尾數(shù),因此我們得到了不正確的值。
          另一個(gè)例子:
          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
          再一次,我們沒有看到預(yù)期的結(jié)果。這是因?yàn)镮nfinity和–Infinity都是浮點(diǎn)數(shù)。正如我們上面討論的,對(duì)于XOR,浮點(diǎn)數(shù)是一個(gè)問題。
          7、使用同或門 XNOR
          同或門也稱為異或非門,它也可以操作二進(jìn)制位,與XOR相反。當(dāng)我們有兩個(gè)值不一樣時(shí),XNOR 結(jié)果是0,否則為1。JavaScript 沒有一個(gè)操作符來執(zhí)行XNOR,所以我們使用非與XOR操作符來達(dá)到類似的效果。

          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位二進(jìn)制數(shù)10-> 1010
          4位二進(jìn)制數(shù)1-> 0001
          上面的分解過程:
          num1 = ~(num1 ^ num2) => ~(1010 ^ 1011)=> ~(1011) => ~11 => -12
          由于我們有一個(gè)負(fù)數(shù),我們需要將其轉(zhuǎn)換回二進(jìn)制并執(zhí)行2的補(bǔ)碼以獲取十進(jìn)制值,例如:
          -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
          花費(fèi)了一些時(shí)間,但我們交換了價(jià)值。但不幸的是,它遇到了與XOR相同的問題,它不能處理浮點(diǎn)數(shù)和無窮大。
          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、在數(shù)組中賦值

          這是一個(gè)簡單的技巧,只需要一行來執(zhí)行交換,更重要的是不需要數(shù)學(xué)知識(shí),只需要一個(gè)基本的數(shù)組知識(shí)即可。
          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
          在數(shù)組的索引0中,我們存儲(chǔ)num1,在索引1中,我們既將num2分配給num1,又存儲(chǔ)了num2。另外,訪問[0],將數(shù)組中的num1值存儲(chǔ)在num2中。
          這種方式可以交換我們想要的任何東西,包括整數(shù),浮點(diǎn)數(shù)(包括無窮大)以及字符串,它很整潔,但清晰度不夠。

          9、使用解構(gòu)表達(dá)式

          這是ES6的一個(gè)特性,也是最簡單的,我們可以像這樣交換值:
          let num1 = 23.45let num2 = 45.67
          console.log(num1,num2)
          [num1,num2] = [num2,num1]
          console.log(num1,num2)

          10、使用立即調(diào)用的函數(shù)表達(dá)式(IIFE)

          IIFE指的是在定義后立即執(zhí)行的函數(shù)。
          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)
          在上面的示例中,我們立即調(diào)用第4行上的一個(gè)函數(shù)。最后的括號(hào)是函數(shù)的參數(shù)。第二個(gè)參數(shù)將num1分配給num2,第一個(gè)參數(shù)num1被返回。因此,交換了這些值,請(qǐng)記住,這種交換方法效率不高。

          ??愛心三連擊

          點(diǎn)分享
          點(diǎn)點(diǎn)贊
          點(diǎn)在看
          瀏覽 50
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人做爰A片一区二区 | 欧日韩男女乱伦肏屄视频 | 国产porn | 成人无码做爰www欧美粉嫩 | 亚洲AV无码精品色午夜红一片 |