1、JS的且運算
記得最開始看到window.console&&console.log(123),當時知道能起什麼做用可是沒有深刻研究,最近在研究後總算弄明白了。要理解這個,首先得明白三個知識點
第一:短路原則
這個你們都很是清楚的了,在作且運算的時候,「同真才真,一假則假」,好比
true&&true==true
true&&false==false
false&&false==false
false&&true==falsechrome
第二:JS邏輯運算中哪些爲false哪些是true
在JS中,0、""、''、null、false、undefined、NaN的布爾值都是爲false,其他爲true---請注意我說的是「布爾值」瀏覽器
console.log(false==false) //true
console.log(0==false) //true
console.log(""==false) //true
console.log(''==false) //true
console.log(NaN==false) //false
console.log(null==false) //false
console.log(undefined==false) //false測試
可是若是通過boolean轉換
console.log(Boolean(false)===false);
console.log(Boolean(0)===false) ;
console.log(Boolean("")===false);
console.log(Boolean('')===false);
console.log(Boolean(NaN)===false) ;
console.log(Boolean(null)===false) ;
console.log(Boolean(undefined)===false) ;
他們終於愉快的爲false了it
接着測試其餘的:
console.log(Boolean([])===true);
console.log(Boolean({})===true);
console.log(Boolean({})===true);
console.log(Boolean('0')===true);
console.log(Boolean("0")===true);
console.log(Boolean(Function)===true);
console.log(Boolean(Object)===true);
以及很是少見的Infinity。console.log(Boolean(Infinity)===true);io
第三:JS的且運算符(&&)的運算規則
理解了第一和第二,才能真正理解JS的運算規則,爲何這麼說?
首先,JS的且運算是遵循短路原則的,
其次,&&兩邊的表達式最終是轉換爲布爾值,也就是說不管是{},[],"",NaN,undefined和null等等,毫無例外的取其布爾值,也就是取其Boolean()的值再進行對比。
接着,JS的且運算符特殊在於,它返回的是表達式的值,而不是表達式的布爾值console
綜合來說,有表達式A1,A2,......An(n>=2),當進行且運算的時候,A1&&A2&&......&&An,從A1開始,
1.若是Boolean(Ai)===true,則執行Boolean(A(i+1)),(i>=1,i+1<=n)
1.1 若是Boolean(A(i+1))===false,返回A(i+1)的值
1.2 若是i+1=n返回A(i+1)的值
1.3 若是Boolean(A(i+1))===true,則重複執行步驟1
2.若是Boolean(Ai)===false,不執行Boolean(A(i+1)),(i>=1),返回Ai的值function
舉例以下
var a=1&&2 //返回2
var a=0&&2 //返回0
var a=1&&"test" //返回"test"
var a=""&&1 //返回""
var a=1&&undefined //返回undefined
var a=1&&null //返回null
var a=1&&[]&&"test"//返回"test"
var a=1&&[]&&undefined//返回undefined
why?
上面三個點已經涉及到了,好比var a=1&&undefined 其背後的邏輯以下
1.第一個表達式,1,不是布爾值,所以轉換爲布爾值Boolean(1)
2.Boolean(1)===true,所以執行下一個表達式undefined
3.undefined不是布爾值,所以轉換爲布爾值Boolean(undefined),Boolean(undefined)===false
4.運算符兩邊比較true!==false
3.返回布爾值爲false的表達式的值,此例是undefined,賦值給atest
再看另一個例子,var a=[]&&"test"
1.第一個表達式,[],不是布爾值,所以轉換爲布爾值Boolean([])
2.Boolean([])===true,所以執行下一個表達式"test"
3."test"不是布爾值,所以轉換爲布爾值Boolean("test"),Boolean("test")===true
4.運算符兩邊比較true===true
3.由於整個求值的結果爲true,那麼則返回最後一個布爾值爲true的表達式的值,此例是"test",賦值給a程序
在現代瀏覽器中,好比chrome,由於JS引擎實現了console,而且存在console.log這個屬性,因此
1.第一個表達式,window.console,不是布爾值,所以轉換爲布爾值Boolean(window.console)
2.Boolean(window.console)===true,所以執行下一個表達式console.log(123)
3.執行console.log(123),打印了123
4.console.log(123)沒有返回值,或者說console.log(123)的返回值是undefined
5.undefined不是布爾值,所以轉換爲布爾值Boolean(undefined),Boolean(undefined)===false
6.運算符兩邊比較true!==false
7.返回布爾值爲false的表達式的值,此例是undefined,賦值給aim
若是是不支持console的瀏覽器,那麼
1.第一個表達式,window.console,不是布爾值,所以轉換爲布爾值Boolean(window.console)
2.Boolean(window.console)===false,所以不執行下一個表達式
3.返回布爾值爲false的表達式的值,此例是undefined
2、巧用JS的且運算
巧用且運算,的確能減小很多代碼,好比window.console&&console.log(123)用if來描述的話,以下程序
if(window.console){
if(&console.log){
console.log(123)
}
}
再看一個例子,經常使用的根據時間顯示問候語,0點到6點,顯示「夜深了」;6點到12點顯示「上午好」;12點到18點顯示「下午好」;18點到23點顯示「晚上好」
function showTime(curTime){
var greeting="";
if(curTime>=0&&curTime<6){
greeting="夜深了";
}else if(curTime>=6&&curTime<12){
greeting="上午好";
}else if(curTime>=12&&curTime<18){
greeting="下午好";
}else {
greeting="晚上好";
}
return greeting;
}
console.log(showTime(5));
console.log(showTime(9));
console.log(showTime(22));
若是用且運算符號的話
function showTime2(curTime){
var greeting=( (curTime>=0&&curTime<6) && "夜深了") || ( (curTime>=6&&curTime<12) && "上午好")|| ( (curTime>=12&&curTime<18) && "下午好") || ( (curTime>=16) && "晚上好")
return greeting;
}
console.log(showTime2(5));
console.log(showTime2(9));
console.log(showTime2(22));
一行代碼就搞定了一堆的if,固然,在精簡代碼的同時,也會降級了代碼的可讀性,若是要用且運算,建議寫上適當的註釋以提升代碼的可讀性。
另外,在JS中,0,"",''以及NaN的布爾值也是爲false,若是程序僅僅是判斷undefined和null, 用且運算的話,由於擴大了false的判斷範圍,會致使不可預測的BUG。若是僅僅是判斷undefined和null,仍是老實的使用if吧