一、JS的且运算记得最开始看到window.console&&console.log(123),当时知道能起什么作用但是没有深入研究,最近在研究后总算弄明白了。要理解这个,首先得明白三个知识点第一:短路原则这个大家都非常清楚的了,在做且运算的时候,“同真才真,一假则假”,比如true&&true==truetrue&&false==falsefalse&&false==falsefalse&&true==false
第二:JS逻辑运算中哪些为false哪些是true在JS中,0、""、''、null、false、undefined、NaN的布尔值都是为false,其余为true---请注意我说的是“布尔值”
console.log(false==false) //trueconsole.log(0==false) //trueconsole.log(""==false) //trueconsole.log(''==false) //trueconsole.log(NaN==false) //falseconsole.log(null==false) //falseconsole.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,则重复执行步骤12.如果Boolean(Ai)===false,不执行Boolean(A(i+1)),(i>=1),返回Ai的值
举例如下var a=1&&2 //返回1var a=0&&2 //返回0var a=1&&"test" //返回"test"var a=""&&1 //返回""var a=1&&undefined //返回undefinedvar a=1&&null //返回nullvar a=1&&[]&&"test"//返回"test"var a=1&&[]&&undefined//返回undefinedwhy?上面三个点已经涉及到了,比如var a=1&&undefined 其背后的逻辑如下1.第一个表达式,1,不是布尔值,因此转换为布尔值Boolean(1)2.Boolean(1)===true,因此执行下一个表达式undefined3.undefined不是布尔值,因此转换为布尔值Boolean(undefined),Boolean(undefined)===false4.运算符两边比较true!==false3.返回布尔值为false的表达式的值,此例是undefined,赋值给a
再看另外一个例子,var a=[]&&"test"1.第一个表达式,[],不是布尔值,因此转换为布尔值Boolean([])2.Boolean([])===true,因此执行下一个表达式"test"3."test"不是布尔值,因此转换为布尔值Boolean("test"),Boolean("test")===true4.运算符两边比较true===true3.因为整个求值的结果为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),打印了1234.console.log(123)没有返回值,或者说console.log(123)的返回值是undefined5.undefined不是布尔值,因此转换为布尔值Boolean(undefined),Boolean(undefined)===false6.运算符两边比较true!==false7.返回布尔值为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吧
新闻热点
疑难解答