你不得不知的邏輯或(||)與(&&)非(!)


       最近重新翻開原生JS,又得到很多不同的體會,雖然現在開發框架那么多,但很多思想都還是離不開原生的基礎。今天呢,我就根據自己的學習總結一下邏輯與(&&)和(邏輯或(||)和邏輯非(!)。

      基本定義

      ||:邏輯或,只有表達式的值都為false,才返回false,其他情況返回true  比如:(8>5)&&(4<6),返回true;(8<5)&&(4<6),返回false

      &&:邏輯與,若兩邊表達式的值都為true,才返回true;比如: (8>5)&&(4<6),返回true;(8<5)&&(4<6),返回false

    !:邏輯非,若表達式的值為true,則返回false;若表達式的值為false,則返回true  比如:!(9>2),返回false;!(9<2),返回true,

      這是他們的基本定義,我們都再熟悉不過了,看似好像沒有什么大用,其實這三個運算符在我們編寫代碼中所起到的重要作用。

 首先看幾個例子

 var a = 0 || 1 || 2;// a = 1
 var b = 1 || 0 || 3;// b = 1
 var c = 0 || 0 || 0;// c = 0
 var a = 0 && 1 && 2;// a = 0
 var b = 1 && 0 && 3;// b = 0
 var c = 0 && 0 && 0;// c = 0
 var d = 1 || 2 || 4;// d = 1
OK.看完上面的栗子,你會發現邏輯運算符不是簡單的返回true/false,而是返回了某一個內容,其實它的判斷過程是這樣的: 邏輯運算符是從前往后依次判斷,判斷到那個能得出最終結論的地方,就會停止往下判斷返回最后判斷的那個內容,不管它是真是假。(記住這句話就行 比如:||運算符,只要一個為真就為真,所以你可以認為它會從前往后一直按順序在找真,找到真就返回那個真。找不到也返回最后一個判斷的那個值。 0 || 1 || 2,判斷到1就知道結果肯定是真,不再繼續判斷,返回1。 1 || 0 || 3, 判斷到第一個就知道結果是真,不再繼續判斷,返回1。 0 || 0 || 0;一直判斷到了最后一個,才知道結果為假,返回最后一個判斷的0。 同理:&&運算符是只要一個為假就為假,所以它會從前往后一直找假的,返回最后一個判斷的值。

實際應用

   1給函數參數定義默認值

 var a = a||2;  //判斷過程:如果變量a是真就停止判斷,返回a,如果a是假就繼續判斷,所以返回2. 實際上就是給a起了個默認值2。
 也等同於:
  if(a){
     a = a
  }else{
    a =2 
  }

//因為js不像php可以直接在型參數上定義func($attr=5)一個默認值,所以可以通過這種方法給參數定義默認值。(順便提醒一下,最新的es6標准已經可以定義函數參數默認值了。)
可以看出用邏輯運算符既節省代碼又實現功能

   2 大大減少代碼量

  首先出個題:假設:成長速度為5顯示1個箭頭;成長速度為10顯示2個箭頭;成長速度為12顯示3個箭頭;其他都顯示都顯示0各箭頭。

  用代碼怎么實現?(例子來源於網上的一個貼吧里)

  最簡單的

var add_level = 0;
if(add_step == 5){
   add_level = 1;
}else if(add_step == 10){
   add_level = 2;
}else if(add_step == 12){
   add_level = 3;
}else {
  add_level = 0;
}

 稍好些的switch:

var add_level = 0;
 switch(add_step){
    case 5 : add_level = 1;
    break;
    case 10 : add_level = 2;
    break;
    case 12 : add_level = 3;
    break;
    default : add_level = 0;
    break;
}

更好的

var add_level = (add_step==5 && 1) || (add_step==10 && 2) || (add_step==12 && 3)  || 0;

更更好的

var add_level={'5':1,'10':2,'12':3}[add_step] || 0;
等同於下面的代碼:
var obj = {'5':1,'10':2,'12':3};
var add_level=json[add_step] || 0;

如果需求改成成長速度為>12顯示4個箭頭;成長速度為>10顯示3個箭頭;成長速度為>5顯示2個箭頭;成長速度為>0顯示1個箭頭;成長速度為<=0顯示0個箭頭。

var add_level = (add_step>12 && 4) || (add_step>10 && 3) || (add_step>5 && 2) || (add_step>0 && 1) || 0;
console.log(add_level);

哇塞,是不是發現我們的代碼一下子就少了很多,但需要注意的一點就是:一方面精簡js代碼,能實質性的減少網絡流量,尤其是大量應用的js公用庫。同時,也帶來了代碼可讀性的降低,個人比較推薦的做法是:如果是相對復雜的應用,請適當地寫一些注釋。

我們可以不使用這些技巧,但是我們一定要能看懂,因為這些技巧已經廣泛應用,不理解這些你就很難看懂別人的代碼。

關於!運算符

很多代碼寫if(!!attr),為什么不直接寫if(attr);其實這是一種更嚴謹的寫法,如下:

console.log(typeof 5); //number
console.log(typeof !!5); //boolean

可以看出:!的作用是把一個其他類型的變量轉成的bool類型。
        不管!后面是什么類型,邏輯非都會將它轉成布爾類型

&& (邏輯與) 和||(邏輯或)的優先級

混合使用的時候要注意他們的優先級:&& (邏輯與) 優先級高於||(邏輯或)

return a && b || c 

先算a&&b,a 是 false ,a&&b就是返回a,再算a||c,則肯定返回 c;如果a是true ,則要看B,自己想想吧。。。

 

另附:JS運算符優先級(從高到低列出)

 運算符 描述
. [] () 字段訪問、數組下標、函數調用以及表達式分組
++ -- - ~ ! delete new typeof void 一元運算符、返回數據類型、對象創建、未定義值
* / % 乘法、除法、取模
+ - + 加法、減法、字符串連接
<< >> >>> 移位
< <= > >= instanceof 小於、小於等於、大於、大於等於、instanceof
== != === !== 等於、不等於、嚴格相等、非嚴格相等
& 按位與
^ 按位異或
| 按位或
&& 邏輯與
|| 邏輯或
?: 條件
= oP= 賦值、運算賦值
, 多重求值

 

 

 

 

 

 

 

 

 

 

 

 

如有錯誤,歡迎指正。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM