最近重新翻開原生JS,又得到很多不同的體會(huì),雖然現(xiàn)在開發(fā)框架那么多,但很多思想都還是離不開原生的基礎(chǔ)。今天呢,我就根據(jù)自己的學(xué)習(xí)總結(jié)一下邏輯與(&&)和邏輯或(||)和邏輯非(!)。
** 基本定義**
** ||**:邏輯或,只有表達(dá)式的值都為false,才返回false,其他情況返回true 比如:(8>5)&&(4<6),返回true;(8<5)&&(4<6),返回false。
** &&**:邏輯與,若兩邊表達(dá)式的值都為true,才返回true;比如: (8>5)&&(4<6),返回true;(8<5)&&(4<6),返回false。
** !**:邏輯非,若表達(dá)式的值為true,則返回false;若表達(dá)式的值為false,則返回true 比如:!(9>2),返回false;!(9<2),返回true,
? ? ?基本定義,我們都再熟悉不過(guò)了,看似好像沒(méi)有什么大用,其實(shí)這三個(gè)運(yùn)算符在我們編寫代碼中所起到的重要作用。
** 首先看幾個(gè)例子**
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
? ? ?可見(jiàn),邏輯運(yùn)算符不是簡(jiǎn)單的返回true/false,而是返回了某一個(gè)內(nèi)容,其實(shí)它的判斷過(guò)程是這樣的:
** 邏輯運(yùn)算符是從前往后依次判斷,判斷到那個(gè)能得出最終結(jié)論的地方,就會(huì)停止往下判斷并返回最后判斷的那個(gè)內(nèi)容,不管它是真是假。**
比如:
||運(yùn)算符:只要一個(gè)為真就為真,所以你可以認(rèn)為它會(huì)從前往后一直按順序在找真,找到真就返回那個(gè)真。找不到也返回最后一個(gè)判斷的那個(gè)值。
0 || 1 || 2,判斷到1就知道結(jié)果肯定是真,不再繼續(xù)判斷,返回1。
1 || 0 || 3, 判斷到第一個(gè)就知道結(jié)果是真,不再繼續(xù)判斷,返回1。
0 || 0 || 0;一直判斷到了最后一個(gè),才知道結(jié)果為假,返回最后一個(gè)判斷的0。
同理:&&運(yùn)算符是只要一個(gè)為假就為假,所以它會(huì)從前往后一直找假的,返回最后一個(gè)判斷的值。
實(shí)際應(yīng)用
** 1 給函數(shù)參數(shù)定義默認(rèn)值**
var a = a||2;
//判斷過(guò)程:如果變量a是真就停止判斷,返回a,如果a是假就繼續(xù)判斷,所以返回2. 實(shí)際上就是給a起了個(gè)默認(rèn)值2。
也等同于:
if(a){ a = a }else{ a =2 }
//因?yàn)閖s不像php可以直接在型參數(shù)上定義func($attr=5)一個(gè)默認(rèn)值,所以可以通過(guò)這種方法給參數(shù)定義默認(rèn)值。
//(順便提醒一下,最新的es6標(biāo)準(zhǔn)已經(jīng)可以定義函數(shù)參數(shù)默認(rèn)值了。)
//可以看出用邏輯運(yùn)算符既節(jié)省代碼又實(shí)現(xiàn)功能
** 2 減少代碼量**
** 題目**:假設(shè):如果a=5的時(shí)b=1,a=10的時(shí)b=2,a=12的時(shí)候b=3,其他情況b=0, 用代碼怎么實(shí)現(xiàn)?
** 最簡(jiǎn)單的**
var b= 0;
if(a == 5){
b = 1;
}else if(a == 10){
b= 2;
}else if(a == 12){
b= 3;
}else {
b = 0;
}
** 稍好些的switch:**
var b = 0;
switch(a){
case 5 : b = 1; break;
case 10 : b = 2; break;
case 12 : b = 3; break;
default : b = 0; break;
}
更好的
var b = (a==5 && 1) || (a==10 && 2) || (a==12 && 3) || 0;
進(jìn)階
var b ={'5':1,'10':2,'12':3}[a] || 0;
等同于下面的代碼:
var obj = {'5':1,'10':2,'12':3};
var b = json[a] || 0;
如果需求改成:
如果a>5的時(shí)b=1,a>10的時(shí)b=2,a>12的時(shí)候b=3,其他情況b=0, 用代碼怎么實(shí)現(xiàn)?
var b = (a>12 && 3) || (a>10 && 2) || (a>5 && 1) || 0;
是不是發(fā)現(xiàn)代碼一下子就少了很多,但需要注意的一點(diǎn)就是:
優(yōu)點(diǎn):js代碼精簡(jiǎn),能減少網(wǎng)絡(luò)流量,尤其是大量應(yīng)用的js。
缺點(diǎn):代碼可讀性的降低,
推薦:如果是相對(duì)復(fù)雜的應(yīng)用,請(qǐng)適當(dāng)?shù)貙懸恍┳⑨尅?br>
我們可以不使用這些技巧,但是我們一定要能看懂,因?yàn)檫@些技巧已經(jīng)廣泛應(yīng)用,不理解這些你就很難看懂別人的代碼。
關(guān)于!運(yùn)算符
很多代碼寫if(!!a),為什么不直接寫if(a);因?yàn)檫@樣寫更嚴(yán)謹(jǐn)
如下:
console.log(typeof 5); //number
console.log(typeof !!5); //boolean
可以看出:!可以把變量轉(zhuǎn)成的bool類型。不管!后面是什么類型,邏輯非都會(huì)將它轉(zhuǎn)成布爾類型
&& (邏輯與) 和||(邏輯或)的優(yōu)先級(jí):
混合使用的時(shí)候要注意他們的優(yōu)先級(jí):&& (邏輯與) 優(yōu)先級(jí)高于||(邏輯或)
**return a && b || c **
先算a&&b,a 是 false ,a&&b就是返回a,再算a||c,則肯定返回 c;如果a是true ,則要看B。
先講到這里,希望能幫助到一些人。