关于window.console&&console.log(123)的思考

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吧

相关文章
相关标签/搜索