溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

你不知道的JavaScript運(yùn)算符

發(fā)布時(shí)間:2020-06-27 19:49:17 來(lái)源:網(wǎng)絡(luò) 閱讀:919 作者:陳學(xué)輝 欄目:web開(kāi)發(fā)

運(yùn)算符對(duì)于大家來(lái)說(shuō)并不陌生,只要平時(shí)寫(xiě)代碼就會(huì)頻繁用的到??赡芷綍r(shí)大家只關(guān)注它們的使用層還停留在只知其用法的表面,但是運(yùn)算符有一些鮮為人知技能,明白以后會(huì)讓你掌握運(yùn)算符的原理和運(yùn)算符的奇技淫巧以及解決一些面試題

先來(lái)看一些面試題,請(qǐng)小伙伴本著不去試的原則寫(xiě)出下而四道題的運(yùn)行結(jié)果

//1
console.log('kaivon' && (2+1));
console.log(![] || '你好,siri');

//2
{
    let a=10,b=20;
    const fn=()=>(a++,b++,10);
    console.log(a,b,fn());

    let c=fn(); 
    console.log(a,b,c);
}

//3
for(var i=0,j=0,k;i<6,j<10;i++,j++){
    k=i+j;
}
console.log(k);

//4
{
    let a=1;
    let b=a++;
    console.log(a,b);

    let c=1;
    let d=++c;
    console.log(c,d);
}

對(duì)于面試題,我一開(kāi)始是拒絕的,內(nèi)心是崩潰的??偸菚?huì)想這些題沒(méi)有意義啊,真正在開(kāi)發(fā)的時(shí)候誰(shuí)會(huì)去做題呀,更不會(huì)遇到這么無(wú)聊的東西,為什么會(huì)用這種東西來(lái)面試?難道說(shuō)面試官是過(guò)來(lái)裝逼的么?看到我們回答不上來(lái),一臉不屑地鄙視我們么?反過(guò)來(lái)想想,面試官跟我們無(wú)冤無(wú)仇,前端何苦為難前端?然而這些東西其實(shí)是有意義的,從你對(duì)這些題的回答可以看出你的基礎(chǔ)知識(shí)全面性,并且能判斷出你的技術(shù)能力。

以上面試題包含三種運(yùn)算符,邏輯運(yùn)算符、逗號(hào)運(yùn)算符、遞增遞減運(yùn)算符,我就分別來(lái)介紹這三種運(yùn)算符

邏輯運(yùn)算符

且運(yùn)算符:&&

  • 并且的意思,至少需要兩個(gè)數(shù)據(jù)(也可以為表達(dá)式)符號(hào)左右各一個(gè)。并且會(huì)把兩邊的結(jié)果轉(zhuǎn)成布爾值
  • 如果左側(cè)的值為真,返回右側(cè)的值。如果左側(cè)的值為假,返回左側(cè)的值(不會(huì)計(jì)算右邊的結(jié)果)
  • 只有當(dāng)左右兩邊的結(jié)果都為真的時(shí)候,整個(gè)結(jié)果才為真(用于判斷)
  • 且運(yùn)算符可以出現(xiàn)多個(gè),會(huì)依次按從左到右的順序,遇到假的結(jié)果便返回。如果都為真則返回最后一個(gè)結(jié)果
console.log('kaivon' && (2+1)); //3

遇到&&運(yùn)算符,先去計(jì)算左邊的結(jié)果并轉(zhuǎn)成布爾值,左邊為字符串kaivon,它轉(zhuǎn)為布爾值的結(jié)果為true,所以會(huì)返回&&運(yùn)算符右側(cè)的結(jié)果。右側(cè)為一個(gè)表達(dá)式,計(jì)算后的結(jié)果為3,所以整個(gè)結(jié)果為3

console.log(![] && '你好,siri');  //false

左側(cè)的表達(dá)式是把一個(gè)空數(shù)組轉(zhuǎn)成布爾值(對(duì)象轉(zhuǎn)基本數(shù)據(jù)類(lèi)型的算法私信我要視頻)并取反的結(jié)果。空數(shù)組轉(zhuǎn)成布爾值結(jié)果為true,取反后結(jié)果為false。當(dāng)左側(cè)的結(jié)果為false時(shí)會(huì)直接返回,并不會(huì)去理會(huì)右側(cè)的內(nèi)容,所以直接返回左側(cè)的結(jié)果false

let n=1;
n-1 && (n+=5);
console.log(n);     //1 左側(cè)為假,所以不會(huì)執(zhí)行右側(cè)的結(jié)果,n不會(huì)加5

const fn=()=>console.log('函數(shù)被調(diào)用了');
n==1 && fn();

第一個(gè)console.log的結(jié)果為1,說(shuō)明n+=5這個(gè)表達(dá)式并沒(méi)有執(zhí)行。因?yàn)?code>&&運(yùn)算符左邊的表達(dá)式運(yùn)算結(jié)果為0轉(zhuǎn)成布爾值為false,所以直接返回左邊的結(jié)果,不會(huì)去管右邊的表達(dá)式,所以n的值并不會(huì)變。
第二個(gè)console.log會(huì)打印出內(nèi)容,說(shuō)明&&運(yùn)算符的右側(cè)表達(dá)式被執(zhí)行了,因?yàn)閚的值并沒(méi)有改變還是1,所以左邊的表達(dá)式運(yùn)行結(jié)果為true,根據(jù)規(guī)則會(huì)返回右側(cè)的結(jié)果,所以執(zhí)行調(diào)用函數(shù)fn

console.log(true && 'kaivon' && (2-2) && 4 && '陳學(xué)輝' && true);   //0 返回2-2的結(jié)果
console.log(true && 'kaivon' && [] && 4 && '陳學(xué)輝');   //陳學(xué)輝

根據(jù)上面最后一條規(guī)則可以很輕易得出上面的運(yùn)算結(jié)果。運(yùn)算會(huì)按從左到右的順序執(zhí)行,一旦遇到表達(dá)式的結(jié)果為false的話就會(huì)停止執(zhí)行,并且整個(gè)表達(dá)式會(huì)返回這個(gè)運(yùn)算結(jié)果。如果所有表達(dá)式的結(jié)果都為true,那整個(gè)結(jié)果為最后那個(gè)表達(dá)式的結(jié)果

或運(yùn)算符:||

  • 或者的意思,至少需要兩個(gè)數(shù)據(jù)(也可以為表達(dá)式)符號(hào)左右各一個(gè)。并且會(huì)把兩邊的結(jié)果轉(zhuǎn)成布爾值
  • 如果左側(cè)的值為真,返回左側(cè)的值(不會(huì)計(jì)算右邊的結(jié)果)。如果左側(cè)的值為假,返回右側(cè)的值
  • 如果有一邊的結(jié)果為真的話,整個(gè)結(jié)果就為真(用于判斷)
  • 或運(yùn)算符可以出現(xiàn)多個(gè),會(huì)依次按從左到右的順序,遇到真的結(jié)果便返回。如果都為假則返回最后一個(gè)結(jié)果
let n=1;
n-1 || (n+=5);
console.log(n);     //6

||運(yùn)算符左邊表達(dá)運(yùn)算結(jié)果為0轉(zhuǎn)布爾值為false,根據(jù)上面列出的規(guī)則會(huì)返回右側(cè)表達(dá)式執(zhí)行的結(jié)果,所以會(huì)執(zhí)行n+=5,最終n的結(jié)果為6

console.log(false || '' || (2-2) || 4 || '陳學(xué)輝' || true);    //4
console.log(false || '' || ![] || 0 || undefined);      //undefined

根據(jù)上面的規(guī)則也很容易知道運(yùn)行結(jié)果,||運(yùn)算符的左側(cè) 運(yùn)行結(jié)果為false的話就會(huì)執(zhí)行右側(cè)的表達(dá)式,直到遇到計(jì)算結(jié)果為true的表達(dá)式才會(huì)停下來(lái),并返回這個(gè)值。如果所有表達(dá)式都沒(méi)有返回true,則取最后表達(dá)式的結(jié)果

或運(yùn)算符的用途:

function fn(text){
    text=text || 'kaivon';  //用戶給了參數(shù),取用戶給的值;用戶沒(méi)有給參數(shù),取默認(rèn)值
    console.log(text);
}
fn();           //kaivon    用戶沒(méi)有傳參數(shù),就會(huì)用默認(rèn)的'kaivon'
fn('陳學(xué)輝');  //陳學(xué)輝   用戶有傳參數(shù),就會(huì)用傳的參數(shù)

上面代碼的這種形式是ES5寫(xiě)面向?qū)ο蟮闹饕问剑糜趯?duì)參數(shù)進(jìn)行處理。如果用戶傳了參數(shù),那會(huì)取用戶所傳的參數(shù);如果用戶沒(méi)有傳參,那取默認(rèn)的參數(shù)。保證函數(shù)始終有參數(shù),不會(huì)報(bào)錯(cuò)

逗號(hào)運(yùn)算符

  • 將多個(gè)表達(dá)式放在一條語(yǔ)句里,按從左到右的順序執(zhí)行每個(gè)表達(dá)式,返回最后那個(gè)表達(dá)式的結(jié)果(在一條語(yǔ)句里執(zhí)行多個(gè)運(yùn)算)
  • 優(yōu)先級(jí)最低,最后才會(huì)運(yùn)算逗號(hào)
  • 逗號(hào)運(yùn)算符的兩邊不能是語(yǔ)句(賦值語(yǔ)句)
console.log(1,2,3);     //1 2 3 
console.log((1,2,3));   //3     

console.log是個(gè)函數(shù),它里面的逗號(hào)表示參數(shù)分隔的意思,并不是逗號(hào)操作符。要變成操作符的話,就加個(gè)括號(hào),加個(gè)括號(hào)后就變成了表達(dá)式,而表達(dá)式必需要求出一個(gè)值,所以里面的逗號(hào)就變成了操作符

let a=10,b=(a++,20,30);
console.log(a,b);   //11 30

第一行代碼中的第一個(gè)逗號(hào)的作用是:可以在一行中聲明多個(gè)變量,減少let關(guān)鍵字。從第二個(gè)開(kāi)始被放到了括號(hào)里,而加了括號(hào)后就是個(gè)表達(dá)式。還是那句話,表達(dá)式一定會(huì)產(chǎn)生一個(gè)值,這個(gè)時(shí)候逗號(hào)就是個(gè)運(yùn)算符了,會(huì)把最后一個(gè)賦給變量,也就是30。

下面來(lái)詳細(xì)分析一道面試題,再深度的理解一下逗號(hào)運(yùn)算符

for(var i=0,j=0,k;i<6,j<10;i++,j++){
    k=i+j;
}
console.log(k); //18

很多小伙伴會(huì)說(shuō)這個(gè)k的值不應(yīng)該是14么?i的值走到5不就停了,j的值走到9不也停了,那加起來(lái)應(yīng)該是14??!為什么是18,這不科學(xué)?。。。?/p>

要明白這個(gè)原因需要結(jié)合for循環(huán)的三條語(yǔ)句以及逗號(hào)運(yùn)算符的作用去才能理解
說(shuō)明:

  1. for循環(huán)的第一個(gè)語(yǔ)句var i=0,j=0,k是初始化一些變量,這里的逗號(hào)與上個(gè)代碼塊第一條語(yǔ)句的逗號(hào)一樣,作用為在一行里聲明多個(gè)變量
  2. for循環(huán)的第二個(gè)語(yǔ)句i&lt;6,j&lt;10作用為取一個(gè)循環(huán)范圍,這里要注意循環(huán)范圍只能有一個(gè)條件,不能說(shuō)既小于5又小于8,所以這里的逗號(hào)就是真正的逗號(hào)運(yùn)算符,它只能取一個(gè)值,取的就是最后那個(gè)j&lt;10
  3. for循環(huán)的第三個(gè)語(yǔ)句i++,j++,這條語(yǔ)句的逗號(hào)還是個(gè)運(yùn)算符,表示在一行里執(zhí)行多條語(yǔ)句,但是這個(gè)語(yǔ)句不需要有返回值,只用把語(yǔ)句執(zhí)行了就行
  4. 綜上所述,這個(gè)for循環(huán)表示:聲明三個(gè)變量,條件范圍為j&lt;10,同時(shí)i與j每走一次都要加一次。當(dāng)j的值為9的時(shí)候就不再加了,此時(shí)i的值也一樣會(huì)加到9它已經(jīng)沒(méi)有范圍限制了會(huì)無(wú)限的加,但是j有范圍并不會(huì)無(wú)限加。所以i的值是跟著j在走,得出結(jié)果i+j=18

逗號(hào)運(yùn)算符的另一個(gè)作用:交換兩個(gè)變量的值
聲明兩個(gè)變量,要求通過(guò)某種方式讓兩個(gè)變量的值進(jìn)行交換,你會(huì)用什么方法?

let a=10;
let b=20;
//問(wèn):如何讓a與b的值進(jìn)行交換

有一種笨方法是利用一個(gè)中間變量可以完成,代碼如下:

let a=10;
let b=20;
let c;

c=a;
a=b;
b=c;

console.log(a,b);   //20 10

利用逗號(hào)運(yùn)算符,代碼如下:

let a=10;
let b=20;

a=[b][b=a,0];
console.log(a,b);   //20 10

可以看到利用逗號(hào)運(yùn)算符倒是很容易實(shí)現(xiàn)需求,但是代碼閱讀起來(lái)好像很費(fèi)勁,分析如下:

a=[b][b=a,0];   //這條代碼的兩個(gè)中括號(hào)表示,前面為數(shù)組,后面為下標(biāo)。在數(shù)組中取某一個(gè)數(shù)據(jù)并賦值給a

a=[20][b=10,0]  //分別把a(bǔ)與b的值套進(jìn)去,注意第二個(gè)中括號(hào)里的b=a,這么寫(xiě)是把a(bǔ)的值賦給b,所以只能套a的值

/*
 * 重點(diǎn)看第二個(gè)中括號(hào)里的代碼,此時(shí)這個(gè)中括號(hào)的作用為下標(biāo),所以里面必需產(chǎn)生一個(gè)值,那里面的逗號(hào)就是運(yùn)算符了
 * 根據(jù)逗號(hào)運(yùn)算符的作用,先執(zhí)行兩個(gè)表達(dá)式,把b的值改成10,再返回最后表達(dá)式的值0
 * 所以這個(gè)中括號(hào)牛比的地方有兩個(gè),第一個(gè)是把b的值改成了10,第二個(gè)是整體返回0。也就變成了下面
*/

a=[20][0]   //這不表示把第0個(gè)數(shù)據(jù)的值(20)賦給a

所以,逗號(hào)運(yùn)算符用巧了就是巧他媽給巧開(kāi)門(mén),巧到家了~

遞增遞減運(yùn)算符

  • 它倆可以放在操作數(shù)的前面,也可以放在操作數(shù)的后面
  • 不管它倆放在哪個(gè)位置,都是一個(gè)表達(dá)式,表達(dá)式的話肯定返回一個(gè)值
  • 它倆具有隱式類(lèi)型轉(zhuǎn)數(shù)字的作用

首先驗(yàn)證表達(dá)有值,不管放前面還是放后面都會(huì)有值

let a=3;
console.log(a++);   //3
console.log(++a);   //5

后自增、后自減

  • 表達(dá)式結(jié)果為數(shù)據(jù)直接轉(zhuǎn)數(shù)字后的值
  • 數(shù)據(jù)結(jié)果為加1或者減1的值
let a=['20'];
console.log(a++);   //20    表達(dá)式結(jié)果為a轉(zhuǎn)數(shù)字后的值
console.log(a);     //21    數(shù)據(jù)本身變成了+1后的值

let b='20';
console.log(b--);   //20    表達(dá)式結(jié)果為b轉(zhuǎn)數(shù)字后的值
console.log(b);     //19    數(shù)據(jù)本身變成了-1后的值

前自增、前自減

  • 表達(dá)式與數(shù)據(jù)的結(jié)果一樣,都為數(shù)據(jù)加1或者減1的值
let a=['20'];
console.log(++a);   //21    表達(dá)式結(jié)果為a轉(zhuǎn)數(shù)字后并加1的值
console.log(a);     //21    數(shù)據(jù)本身也為a轉(zhuǎn)數(shù)字后并加1的值

let b='20';
console.log(--b);   //19    表達(dá)式結(jié)果為a轉(zhuǎn)數(shù)字后并減1的值
console.log(b);     //19    數(shù)據(jù)本身也為a轉(zhuǎn)數(shù)字后并減1的值

兩種寫(xiě)法對(duì)比

  • 兩種寫(xiě)法的區(qū)別在于表達(dá)式的結(jié)果不同。數(shù)據(jù)的結(jié)果寫(xiě)前面與寫(xiě)后面都一樣
  • 如果要用表達(dá)式的結(jié)果,看誰(shuí)在前面
    1. 數(shù)據(jù)在前面,結(jié)果為數(shù)據(jù)的值
    2. 符號(hào)在前面,結(jié)果為數(shù)據(jù)+1或者數(shù)據(jù)-1的值
{
    let a=1;
    let b=a++;
    console.log(a,b);   //2 1
}

{
    let a=1;
    let b=++a;
    console.log(a,b);   //2 2
}

通過(guò)對(duì)比,a的值不管是在前面++還是在后面++,結(jié)果都為2(a+1的值)。但b的值(表達(dá)式的值)可以看誰(shuí)在前面,a在前面那就取a的值,++在前面那就取a+1的值

善于總結(jié)!善于總結(jié)!善于總結(jié)!重要的提醒打三遍!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI