||(邏輯或)
從字面上來說,只有前后都是false的時候才返回false男韧,否則返回true。
alert(true||false); // true
alert(false||true); // true
alert(true||true); // true
alert(false||false); // false
但是备恤,從深層意義上來說的話编整,卻有另一番天地,試下面代碼
alert(0||1);//1
顯然元镀,我們知道绍填,前面0意味著false,而后面1意味著true,那么上面的結(jié)果應該是true,而事實返回的結(jié)果是1。
再看下面代碼:
alert(2||1);//2
我們知道栖疑,前面2是true,后面1也是true,那返回結(jié)果又是什么呢讨永?測試結(jié)果是2,繼續(xù)看:
alert('a'||1);//'a'
同樣,前面'a'是true遇革,后面1也是true;測試結(jié)果是'a',下面
alert(''||1);//1
由上卿闹,我們知道前面”是false,后面1是true,而返回結(jié)果是1。再看下面
alert('a'||0);//'a'
前面'a'是true萝快,而后面0是false,返回結(jié)果是'a'锻霎,繼續(xù)下面
alert(''||0);//0
前面”是false,后面0同樣是false,返回結(jié)果是0
alert(0||'');//''
前面0是false,后面”是false揪漩,返回結(jié)果是''''
這就意味
1旋恼、只要“||”前面為false,不管“||”后面是true還是false,都返回“||”后面的值奄容。
2冰更、只要“||”前面為true,不管“||”后面是true還是false产徊,都返回“||”前面的值。
我稱這種為短路原理: 知道了前面第一個的結(jié)果就知道后的輸出冬殃,如果為第一個為:true囚痴,則取第一個的值,如果第一個為false审葬,則取第二個的值深滚。
js必須牢記的6個蛋蛋: 請你一定要記住:在js邏輯運算中涣觉,0痴荐、”“、null官册、false生兆、undefined、NaN都會判為false膝宁,其他都為true(好像沒有遺漏了吧鸦难,請各位確認下)。這個一定要記住员淫,不然應用||和&&就會出現(xiàn)問題合蔽。
這里順便提下:經(jīng)常有人問我,看到很多代碼if(!!attr)介返,為什么不直接寫if(attr)拴事;
其實這是一種更嚴謹?shù)膶懛ǎ?br>
請測試 typeof 5和typeof !!5的區(qū)別。!!的作用是把一個其他類型的變量轉(zhuǎn)成的bool類型圣蝎。
&&(邏輯與)
從字面上來說刃宵,只有前后都是true的時候才返回true,否則返回false徘公。
alert(true&&false); // false
alert(true&&true); // true
alert(false&&false); // false
alert(false&&true); // false
然后牲证,根據(jù)上面經(jīng)驗,我們看看“&&”號前后关面,不單單是布爾類型的情況坦袍。
alert(''&&1);//''
結(jié)是返回”,“&&”前面”是false,后面是1是true。
alert(''&&0);//''
結(jié)是返回”,“&&”前面”是false,后面是0也是false缭裆。
alert('a'&&1);//1
結(jié)是返回1,“&&”前面”a是true,后面是1也是true键闺。
alert('a'&&0);//0
結(jié)是返回0,“&&”前面”a是true,后面是0是false寿烟。
alert('a'&&'');//''
結(jié)是返回”,“&&”前面”a是true,后面是”是false澈驼。
alert(0&&'a');//0
結(jié)是返回0,“&&”前面”0是false,后面是'a'是true。
alert(0&&''); //0
結(jié)是返回0,“&&”前面”0是false,后面是”也是false筛武。
短路原理
1缝其、只要“&&”前面是false挎塌,無論“&&”后面是true還是false,結(jié)果都將返“&&”前面的值;
2内边、只要“&&”前面是true,無論“&&”后面是true還是false漠其,結(jié)果都將返“&&”后面的值;
在開發(fā)中的應用
1.下面三段代碼等價:
a=a||"defaultValue";
if(!a){
a="defaultValue";
}
if(a==null||a==""||a==undefined){
a="defaultValue";
}
你愿意用哪一個呢嘴高?
2.像var Yahoo = Yahoo || {};
這種是非常廣泛應用的。 獲得初值的方式是不是很優(yōu)雅辉巡?比if...else…
好很多谎砾,比aaa惑灵?bbb:ccc
也好不少。
3.callback&&callback()
在回調(diào)中套啤,經(jīng)常這么寫,更嚴謹随常,先判斷 callback 是不是存在潜沦,如果存在就執(zhí)行,這樣寫的目的是為了防止報錯
如果直接寫 callback(); 當callback不存在時代碼就會報錯绪氛。
4唆鸡、綜合實例
需求如圖:
這里寫圖片描述
假設對成長速度顯示規(guī)定如下:
成長速度為5顯示1個箭頭;
成長速度為10顯示2個箭頭钞楼;
成長速度為12顯示3個箭頭喇闸;
成長速度為15顯示4個箭頭;
其他都顯示都顯示0各箭頭询件。
用代碼怎么實現(xiàn)燃乍?
差一點的if,else:
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 if(add_step == 15){
add_level = 4;
}
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;
case 15 : add_level = 4;
break;
default : add_level = 0;
break;
}
如果需求改成:
成長速度為>12顯示4個箭頭宛琅;
成長速度為>10顯示3個箭頭刻蟹;
成長速度為>5顯示2個箭頭;
成長速度為>0顯示1個箭頭嘿辟;
成長速度為<=0顯示0個箭頭舆瘪。
那么用switch實現(xiàn)起來也很麻煩了。
那么你有沒有想過用一行就代碼實現(xiàn)呢红伦?
ok英古,讓我們來看看js強大的表現(xiàn)力吧:
var add_level = (add_step==5 && 1) || (add_step==10 && 2) || (add_step==12 && 3) || (add_step==15 && 4) || 0;
更強大的,也更優(yōu)的:
var add_level={'5':1,'10':2,'12':3,'15':4}[add_step] || 0;
第二個需求:
var add_level = (add_step>12 && 4) || (add_step>10 && 3) || (add_step>5 && 2) || (add_step>0 && 1)||(add_step<=0&& 0 );