你不知道的JavaScript運算符

運算符對於你們來講並不陌生,只要平時寫代碼就會頻繁用的到。可能平時你們只關注它們的使用層還停留在只知其用法的表面,可是運算符有一些不爲人知技能,明白之後會讓你掌握運算符的原理和運算符的奇技淫巧以及解決一些面試題javascript

先來看一些面試題,請小夥伴本着不去試的原則寫出下而四道題的運行結果前端

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

對於面試題,我一開始是拒絕的,心裏是崩潰的。老是會想這些題沒有意義啊,真正在開發的時候誰會去作題呀,更不會遇到這麼無聊的東西,爲何會用這種東西來面試?難道說面試官是過來裝逼的麼?看到咱們回答不上來,一臉不屑地鄙視咱們麼?反過來想一想,面試官跟咱們無冤無仇,前端何苦爲難前端?然而這些東西實際上是有意義的,從你對這些題的回答能夠看出你的基礎知識全面性,而且能判斷出你的技術能力。java

以上面試題包含三種運算符,邏輯運算符、逗號運算符、遞增遞減運算符,我就分別來介紹這三種運算符面試

邏輯運算符

且運算符:&&

  • 而且的意思,至少須要兩個數據(也能夠爲表達式)符號左右各一個。而且會把兩邊的結果轉成布爾值
  • 若是左側的值爲真,返回右側的值。若是左側的值爲假,返回左側的值(不會計算右邊的結果)
  • 只有當左右兩邊的結果都爲真的時候,整個結果才爲真(用於判斷)
  • 且運算符能夠出現多個,會依次按從左到右的順序,遇到假的結果便返回。若是都爲真則返回最後一個結果
console.log('kaivon' && (2+1)); //3

遇到&&運算符,先去計算左邊的結果並轉成布爾值,左邊爲字符串kaivon,它轉爲布爾值的結果爲true,因此會返回&&運算符右側的結果。右側爲一個表達式,計算後的結果爲3,因此整個結果爲3算法

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

左側的表達式是把一個空數組轉成布爾值(對象轉基本數據類型的算法私信我要視頻)並取反的結果。空數組轉成布爾值結果爲true,取反後結果爲false。當左側的結果爲false時會直接返回,並不會去理會右側的內容,因此直接返回左側的結果false數組

let n=1;
n-1 && (n+=5);
console.log(n);        //1    左側爲假,因此不會執行右側的結果,n不會加5

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

第一個console.log的結果爲1,說明n+=5這個表達式並無執行。由於&&運算符左邊的表達式運算結果爲0轉成布爾值爲false,因此直接返回左邊的結果,不會去管右邊的表達式,因此n的值並不會變。
第二個console.log會打印出內容,說明&&運算符的右側表達式被執行了,由於n的值並無改變仍是1,因此左邊的表達式運行結果爲true,根據規則會返回右側的結果,因此執行調用函數fn函數

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

根據上面最後一條規則能夠很輕易得出上面的運算結果。運算會按從左到右的順序執行,一旦遇到表達式的結果爲false的話就會中止執行,而且整個表達式會返回這個運算結果。若是全部表達式的結果都爲true,那整個結果爲最後那個表達式的結果code

或運算符:||

  • 或者的意思,至少須要兩個數據(也能夠爲表達式)符號左右各一個。而且會把兩邊的結果轉成布爾值
  • 若是左側的值爲真,返回左側的值(不會計算右邊的結果)。若是左側的值爲假,返回右側的值
  • 若是有一邊的結果爲真的話,整個結果就爲真(用於判斷)
  • 或運算符能夠出現多個,會依次按從左到右的順序,遇到真的結果便返回。若是都爲假則返回最後一個結果
let n=1;
n-1 || (n+=5);
console.log(n);     //6

||運算符左邊表達運算結果爲0轉布爾值爲false,根據上面列出的規則會返回右側表達式執行的結果,因此會執行n+=5,最終n的結果爲6視頻

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

根據上面的規則也很容易知道運行結果,||運算符的左側 運行結果爲false的話就會執行右側的表達式,直到遇到計算結果爲true的表達式纔會停下來,並返回這個值。若是全部表達式都沒有返回true,則取最後表達式的結果對象

或運算符的用途:

function fn(text){
    text=text || 'kaivon';  //用戶給了參數,取用戶給的值;用戶沒有給參數,取默認值
    console.log(text);
}
fn();            //kaivon    用戶沒有傳參數,就會用默認的'kaivon'
fn('陳學輝');    //陳學輝    用戶有傳參數,就會用傳的參數

上面代碼的這種形式是ES5寫面向對象的主要形式,用於對參數進行處理。若是用戶傳了參數,那會取用戶所傳的參數;若是用戶沒有傳參,那取默認的參數。保證函數始終有參數,不會報錯

逗號運算符

  • 將多個表達式放在一條語句裏,按從左到右的順序執行每一個表達式,返回最後那個表達式的結果(在一條語句裏執行多個運算)
  • 優先級最低,最後纔會運算逗號
  • 逗號運算符的兩邊不能是語句(賦值語句)
console.log(1,2,3);        //1 2 3    
console.log((1,2,3));    //3

console.log是個函數,它裏面的逗號表示參數分隔的意思,並非逗號操做符。要變成操做符的話,就加個括號,加個括號後就變成了表達式,而表達式必須要求出一個值,因此裏面的逗號就變成了操做符

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

第一行代碼中的第一個逗號的做用是:能夠在一行中聲明多個變量,減小let關鍵字。從第二個開始被放到了括號裏,而加了括號後就是個表達式。仍是那句話,表達式必定會產生一個值,這個時候逗號就是個運算符了,會把最後一個賦給變量,也就是30。

下面來詳細分析一道面試題,再深度的理解一下逗號運算符

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

不少小夥伴會說這個k的值不該該是14麼?i的值走到5不就停了,j的值走到9不也停了,那加起來應該是14啊!爲何是18,這不科學啊!!!

要明白這個緣由須要結合for循環的三條語句以及逗號運算符的做用去才能理解
說明:

  1. for循環的第一個語句var i=0,j=0,k是初始化一些變量,這裏的逗號與上個代碼塊第一條語句的逗號同樣,做用爲在一行裏聲明多個變量
  2. for循環的第二個語句i<6,j<10做用爲取一個循環範圍,這裏要注意循環範圍只能有一個條件,不能說既小於5又小於8,因此這裏的逗號就是真正的逗號運算符,它只能取一個值,取的就是最後那個j<10
  3. for循環的第三個語句i++,j++,這條語句的逗號仍是個運算符,表示在一行裏執行多條語句,可是這個語句不須要有返回值,只用把語句執行了就行
  4. 綜上所述,這個for循環表示:聲明三個變量,條件範圍爲j<10,同時i與j每走一次都要加一次。當j的值爲9的時候就再也不加了,此時i的值也同樣會加到9它已經沒有範圍限制了會無限的加,可是j有範圍並不會無限加。因此i的值是跟着j在走,得出結果i+j=18

逗號運算符的另外一個做用:交換兩個變量的值
聲明兩個變量,要求經過某種方式讓兩個變量的值進行交換,你會用什麼方法?

let a=10;
let b=20;
//問:如何讓a與b的值進行交換

有一種笨方法是利用一箇中間變量能夠完成,代碼以下:

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

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

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

利用逗號運算符,代碼以下:

let a=10;
let b=20;

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

能夠看到利用逗號運算符卻是很容易實現需求,可是代碼閱讀起來好像很費勁,分析以下:

a=[b][b=a,0];   //這條代碼的兩個中括號表示,前面爲數組,後面爲下標。在數組中取某一個數據並賦值給a

a=[20][b=10,0]  //分別把a與b的值套進去,注意第二個中括號裏的b=a,這麼寫是把a的值賦給b,因此只能套a的值

/*
 * 重點看第二個中括號裏的代碼,此時這個中括號的做用爲下標,因此裏面必需產生一個值,那裏面的逗號就是運算符了
 * 根據逗號運算符的做用,先執行兩個表達式,把b的值改爲10,再返回最後表達式的值0
 * 因此這個中括號牛比的地方有兩個,第一個是把b的值改爲了10,第二個是總體返回0。也就變成了下面
*/

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

因此,逗號運算符用巧了就是巧他媽給巧開門,巧到家了~

遞增遞減運算符

  • 它倆能夠放在操做數的前面,也能夠放在操做數的後面
  • 無論它倆放在哪一個位置,都是一個表達式,表達式的話確定返回一個值
  • 它倆具備隱式類型轉數字的做用

首先驗證表達有值,無論放前面仍是放後面都會有值

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

後自增、後自減

  • 表達式結果爲數據直接轉數字後的值
  • 數據結果爲加1或者減1的值
let a=['20'];
console.log(a++);    //20    表達式結果爲a轉數字後的值
console.log(a);        //21    數據自己變成了+1後的值

let b='20';
console.log(b--);    //20    表達式結果爲b轉數字後的值
console.log(b);        //19    數據自己變成了-1後的值

前自增、前自減

  • 表達式與數據的結果同樣,都爲數據加1或者減1的值
let a=['20'];
console.log(++a);    //21    表達式結果爲a轉數字後並加1的值
console.log(a);        //21    數據自己也爲a轉數字後並加1的值

let b='20';
console.log(--b);    //19    表達式結果爲a轉數字後並減1的值
console.log(b);        //19    數據自己也爲a轉數字後並減1的值

兩種寫法對比

  • 兩種寫法的區別在於表達式的結果不一樣。數據的結果寫前面與寫後面都同樣
  • 若是要用表達式的結果,看誰在前面
  1. 數據在前面,結果爲數據的值
  2. 符號在前面,結果爲數據+1或者數據-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
}

經過對比,a的值不論是在前面++仍是在後面++,結果都爲2(a+1的值)。但b的值(表達式的值)能夠看誰在前面,a在前面那就取a的值,++在前面那就取a+1的值

善於總結!善於總結!善於總結!重要的提醒打三遍!

相關文章
相關標籤/搜索