从window.console&&console.log(123)浅谈JS的且运算逻辑(&&)

  • 从window.console&&console.log(123)浅谈JS的且运算逻辑(&&)

作者:www.cnblogs.com  来源:www.cnblogs.com  发布日期:2015-03-01

一、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吧

  • 相关文章
时间: 2024-10-05 07:01:31

从window.console&&console.log(123)浅谈JS的且运算逻辑(&&)的相关文章

浅谈 js eval作用域

就简单聊下如何全局 eval 一个代码. var x = 1; (function () { eval('var x = 123;'); })(); console.log(x); 这个代码得到的是 1 而不是 123如果想让 eval 执行的代码是全局的,那么有几种方法. var x = 1; (function () { window.eval('var x = 123;'); })(); console.log(x); 这个方法标准浏览器都可以得到 123 而IE6-8则依然是 1 相同的

浅谈JS之AJAX

0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HTTP和web服务器进行数据交换(用户不知道也感觉不出来,就跟桌面应用程序似的进行数据交互),它不会导致页面重新加载,这样才有更好的用户体验. Ajax是基于以下开放标准: javascript(DOM) css html xml(json) 通俗的说就是使用了javascript(DOM)的XMLH

浅谈js中的this关键字

浅谈js中的this关键字 全局作用域中的this 函数作用域中的this 不同函数调用方法下的this 直接调用 作为对象的方法调用 作为构造函数调用 通过call或apply方法调用 嵌套函数作用域中的this 浅谈js中的this关键字 this是JavaScript中的关键字之一,在编写程序的时候经常会用到,正确的理解和使用关键字this尤为重要.接下来,笔者就从作用域的角度粗谈下自己对this关键字的理解,希望能给到大家一些启示,权当交流之用. 全局作用域中的this 本文将以作用域由

浅谈 js 正则之 test 方法

原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. ? 1 2 3 4 5 var re = /\d/; console.log( re.test("1") ); console.log( re.test("1") ); console.log( re.test("1") ); console.log( re.test("1"

浅谈 js 下 with 对性能的影响

这几天多次看到有博主们在写 with 的文章,这货确实非常方便,但是却是个性能杀手,所以一直都是上不得台面的.那么他究竟会让效率低下到什么程度呢?先来看下 with 是如何的便捷吧.. // 正常调用 console.log(location.host); console.log(location.pathname); // 在 with 下 with (location) { console.log(host); console.log(pathname); } 如果不影响性能,确实是非常霸气

浅谈 js 对象 toJSON 方法

前些天在<浅谈 JSON.stringify 方法>说了他的正确使用姿势,今天来说下 toJSON 方法吧.其实我觉得这货跟 toString 一个道理,他是给 stringify 方法字符串化的时候调用的.看下 MDN 官方文档吧<toJSON behavior>.非常简单,但是要注意的是他和 stringify 方法第二个参数稍微有点不同.因为 stringify 第二个参数是回调函数时,只是对当前 key 对应的值进行修改.而 toJSON 则是对当前对象进行修改.例如: v

浅谈 js 字符串 search 方法

原文:浅谈 js 字符串 search 方法 这是一个很久以前的事情了,好像是安心兄弟在学习js的时候做的练习.具体记不清了,今天就来简单分析下 search 究竟是什么用的. 从字面意思理解,一个是搜索字符串吧. var str = "123456789abcde"; console.log( str.search("abc") ); // 9 确实是搜索指定字符在一个字符串中出现的位置,如果不存在就返回 -1可是这样就跟 indexOf 功能一样了,何必单独搞一

浅谈 js 数字格式类型

原文:浅谈 js 数字格式类型 很多人也许只知道 123,123.456,0xff 之类的数字格式.其实 js 格式还有很多数字格式类型,比如 1., .1 这样的,也有 .1e2 这样的. 可能有人说这是什么个格式?其实还不止呢.1          //11.2       //1.21.2e3    //12001.2e+3  //12001.2e-3  //0.0012.12e+2 //12-.12e-2 //-0.0012 当然这些只是十进制.我们来说说 八进制 和 十六进制.0x00

浅谈 js 语句块与标签

原文:浅谈 js 语句块与标签 语句块是什么?其实就是用 {} 包裹的一些js代码而已,当然语句块不能独立作用域.可以详细参见这里<MDN block> 也许很多人第一印象 {} 不是对象字面量么?怎么成了语句块了?如果在赋值语句或者表达式里用的时候,确实是对象字面量,如: var a = {}; ({toString:function(){return "hehe"}}) + "..."; 是不是很有意思..但是直接使用如: {toString: fu