淺談邏輯運算符&&(與)和 ||(或)


冬游有一群奇形怪狀的小伙伴,總會問冬游一些奇形怪狀的問題。

昨天冬游有一個叫周三胖(因崇拜某國領導人以及結合其個人特點所以姓周,號三胖⊙﹏⊙)的朋友,向冬游發了這么一張圖片:

兄弟,上面那幾句什么意思?

呔!三胖休得坑貧道。老衲不會!

大哥,我是真不會,求講解?

%#@!#¥&

.....

經過三胖的一番軟磨硬泡,死纏爛打,威逼利誘之后,我終於倒在三胖的花言巧語,甜言蜜語之中。

我balabala.....

吃瓜群眾:我們瓜都吃完了你什么時候進入正題?

==============一臉懵逼的吃瓜群眾分割線==============

好吧,我們進入正題,拋去上面的代碼,我寫下如下代碼

 

1 function foo(){
2     var a = 1;  
3     var b = 2; 
4     var c = false;   
5     var d = true; 
6     console.log(c || (a = 1111),"a此刻的值:",a); 
7     console.log(d || (b = 2222),"b此刻的值:",b); 
8 }  
9 foo();

各位看官且說會輸出神馬?

好吧,瀏覽器輸出如下

why???
且慢。我們再來修改一下foo函數: 

1 function foo(){
2     var a = 1;  
3     var b = 2;    
4     var c = false; 
5     var d = true;  
6     console.log(c && (a = 1111),"a此刻的值:",a); 
7     console.log(d && (b = 2222),"b此刻的值:",b);   
8 }   
9 foo(); 

 

 然后我們在瀏覽器中會看到如下:

ok,下面進入講解部分:

&& 和 || 運算符在JavaScript中我更喜歡用初中物理中的電力並聯串聯來形容, || 運算符相當於並聯線路圖,而&&運算符則是串聯,鑒於年代久遠,老夫又出身文科轉投工科,就不向各位理工高手看官介紹何為串聯並聯。

三胖:你分明就是不會!

去去去,盒飯拿好,趕緊回公司擼你代碼!

咳咳,咱們繼續。

|| 操作符會首先對第一個操作數進行判斷,如果第一個為真,則直接返回第一個操作數的判斷結果,對第二個操作數是啥不會進行判斷運算,如果第一個為假值,則會去判斷第二個操作數並對第二個操作數進行執行操作,而后返回執行操作判斷值。所以對於||的說明我們可以用代碼這么整理:

第一個操作數 || 第二個操作數

代碼解釋:  

1 if(第一個操作數){
2     return 第一個操作數; 
3 }
4 else{
5     return 第二個操作數;
6 }

 

進一步對foo中 c || (a = 1111) 套用上述解釋就是:

 

1 if(c){ 
2     return c; 
3 } 
4 else{ 
5     return (a = 1111);      //此處在瀏覽器直接這么寫會報錯,建議先運算再取出返回值 
6 } 

 

同理 d || (b = 2222) 的套用就是

1 if(d){ 
2     return d; 
3 } 
4 else{ 
5     return (b = 2222);      //此處在瀏覽器直接這么寫會報錯,建議先運算再取出返回值 
6 } 

 

 

如此一來就會返回出上面的結果。

|| 運算符在我們處理事件兼容時廣泛的被應用,比如:

 1 e = e || event; 

這所運用的思想就是這樣一個思想,如果e為false或者undefined,則會把event賦值給e。

同時在除了在event中的應用外我們還應用在函數的傳參上,比如:

1 function test(a){
2     a = a || 111;
3     console.log(a);
4 }

用此為函數形參指定默認參數,但是這么做其實是不安全的,比如當我調用test函數時我傳入實參一個""(空字符串)或者傳入實參0,此時瀏覽器會輸出

在瀏覽器中會將""(空字符串)和0以及很多其它的假值進行隱式類型轉換,所以單純的進行這樣一個判斷是不嚴謹和不安全的,所以建議各位看官少用。

這是一個知識點。

三胖:甭廢話,盒飯我快吃完了你才講這么點?

我:哥屋恩...

各位看官別走,咱們繼續(微笑臉)。

&& 運算符則和||正好相反,如果第一個操作數為真,則進行第二個操作數的判斷運算,首先它會對第二個操作數進行運算,拿到第二個操作數的返回值,而后返回第二個操作數的返回值。如果第一個操作數為假,則進入第二個操作數的判斷,直接返回false。

三胖:什么如果否則的,看的我都暈了。

我:

ko,咱們繼續。

根據對||運算符的套路。我們繼續將&&符轉換為半代碼半中文語言:

 

操作數一 && 操作數二

 

變身:    

1 if(第一個操作數){
2     return 第二個操作數;  
3 } 
4 else{ 
5     return false; 
6 }

 

繼續對上面的 c && (a = 1111) 進行套用:   

1 if(c){
2     return (a = 1111);           //此處在瀏覽器直接這么寫會報錯,建議先運算再取出返回值 
3 }  
4 else{  
5     return false; 
6 }

 

 同理 d && (b = 2222) 的解釋如下

 

1 if(d){
2     return (b = 2222);           //此處在瀏覽器直接這么寫會報錯,建議先運算再取出返回值 
3 }  
4 else{  
5     return false; 
6 }

 

如此輸出結果如上。

三胖:嗯。(若有所思臉)

&&運算符一般用在不確定某一對象下是否有某一屬性時的判斷,比如我有如下代碼

 

1 var list = {
2     obj : {},
3     array : [1,2,3,4,5]
4 }

 

 

 

在我不確定array是否為list下的屬性時通常我們這么寫  

1 if(list.hasOwnProperty("array")){
2     //dosomething
3 }
4 else{
5     //dosomething
6 }

 

結合&&符我們可以這么寫 :

list.hasOwnProperty("array") && dosomething

 

對比以上兩種寫法,很明顯在代碼簡潔性上,第二種寫法完勝,但是在代碼可讀性上完敗,兩種方式都可以,這取決於個人習慣,我個人比較喜歡第二種寫法。

我:三胖,回答我一個問題,回答完你就可以打卡下班了,知道邏輯運算符之間的優先級嗎?

三胖:不知道。

我:哥屋恩....

三胖:得嘞(開心臉)。

滴,學生卡。

o(╯□╰)o

回來,你給我回來。

算了,各位看官,我們繼續。

現在有如下代碼: 

1 a = "hello";
2 b = false;
3 c = false;
4 console.log(a || b && c)

 

各位看官,再次猜測會輸出什么。

按照正常從左道右的邏輯思維我們先拿到  a || b  的值,而后我們再與 c 進行&&運算,最后它會輸出  false

然而,事與願違。

瀏覽器最終輸出----hello。

這里就體現了邏輯運算符之間的優先級關系,事實上瀏覽器在解析運算時是這樣做的:

1 a || (b && c)

 

也就是先拿到 b && c 的值,而后再與 a 進行 || 運算,最后返回結果。

這也就是說在進行邏輯運算時 || 運算符的優先級低於 && 運算符。但是並不建議大家這么書寫,這樣會導致邏輯關系不明朗,代碼可讀性差的后果,所以各位看官在書寫這樣的代碼時還是加上一個()為妙(手動滑稽)。

 

以上就是本次對邏輯運算符的淺談隨筆,如有不對,歡迎指出。文中我與三胖的日常大多實為劇情需要虛構而出,如有雷同實屬巧合,語言風格非喜且輕噴。

我是冬游,一條游上岸的咸魚,我的目標是翻個身,繼續曬。

 

 


免責聲明!

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



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