從window.console&&console.log(123)淺談JS的且運算邏輯(&&)



一、JS的且運算
記得最開始看到window.console&&console.log(123),當時知道能起什么作用但是沒有深入研究,最近在研究后總算弄明白了。要理解這個,首先得明白三個知識點
第一:短路原則
這個大家都非常清楚的了,在做且運算的時候,“同真才真,一假則假”,比如
true&&true==true
true&&false==false
false&&false==false
false&&true==false

第二: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了


接着測試其他的:
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);

第三:JS的且運算符(&&)的運算規則
理解了第一和第二,才能真正理解JS的運算規則,為什么這么說?
首先,JS的且運算是遵循短路原則的,
其次,&&兩邊的表達式最終是轉換為布爾值,也就是說無論是{},[],"",NaN,undefined和null等等,毫無例外的取其布爾值,也就是取其Boolean()的值再進行對比。
接着,JS的且運算符特殊在於,它返回的是表達式的值,而不是表達式的布爾值

綜合來講,有表達式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的值


舉例如下
var a=1&&2 //返回1
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,賦值給a

再看另外一個例子,var a=[]&&"test"
1.第一個表達式,[],不是布爾值,因此轉換為布爾值Boolean([])
2.Boolean([])===true,因此執行下一個表達式"test"
3."test"不是布爾值,因此轉換為布爾值Boolean("test"),Boolean("test")===true
4.運算符兩邊比較true===true
3.因為整個求值的結果為true,那么則返回最后一個布爾值為true的表達式的值,此例是"test",賦值給a

現在,再來分析window.console&&console.log(123)

在現代瀏覽器中,比如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,賦值給a

如果是不支持console的瀏覽器,那么
1.第一個表達式,window.console,不是布爾值,因此轉換為布爾值Boolean(window.console)
2.Boolean(window.console)===false,因此不執行下一個表達式
3.返回布爾值為false的表達式的值,此例是undefined

二、巧用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吧


免責聲明!

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



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