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

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

  1. 浅谈JS之AJAX

    0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HT ...

  2. 浅谈 js eval作用域

    原文:浅谈 js eval作用域 就简单聊下如何全局 eval 一个代码. var x = 1; (function () { eval('var x = 123;'); })(); console. ...

  3. 浅谈JS中的闭包

    浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...

  4. 浅谈 js 字符串之神奇的转义

    原文:浅谈 js 字符串之神奇的转义 字符串在js里是非常常用的,但是你真的了解它么?翻阅<MDN String>就可以了解它的常见用法了,开门见山的就让你了解了字符串是怎么回事. 'st ...

  5. 浅谈JavaScript浮点数及其运算

    原文:浅谈JavaScript浮点数及其运算     JavaScript 只有一种数字类型 Number,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的.浮点数的精度问题 ...

  6. 浅谈 js 正则字面量 与 new RegExp 执行效率

    原文:浅谈 js 正则字面量 与 new RegExp 执行效率 前几天谈了正则匹配 js 字符串的问题:<js 正则学习小记之匹配字符串> 和 <js 正则学习小记之匹配字符串优化 ...

  7. 浅谈 js 正则之 test 方法

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

  8. 浅谈 js 字符串 trim 方法之正则篇

    原文:浅谈 js 字符串 trim 方法之正则篇 关于 trim 其实没啥好说的,无非就是去除首位空格,对于现代浏览器来说只是简单的正则 /^\s+|\s+$/ 就可以搞定了.而且支持中文空格   等 ...

  9. 浅谈 js 字符串 search 方法

    原文:浅谈 js 字符串 search 方法 这是一个很久以前的事情了,好像是安心兄弟在学习js的时候做的练习.具体记不清了,今天就来简单分析下 search 究竟是什么用的. 从字面意思理解,一个是 ...

随机推荐

  1. Atitit..组件化事件化的编程模型--(2)---------Web datagridview 服务器端控件的实现原理and总结

    Atitit..组件化事件化的编程模型--(2)---------Web datagridview 服务器端控件的实现原理and总结 1. 服务端table控件的几个流程周期 1 1.1. 确认要显示 ...

  2. Leetcode 326 Power of Three 数论

    判断一个数是否是3的n次幂 这里我用了一点巧,所有的int范围的3的n次幂是int范围最大的3的n次幂数(即3^((int)log3(MAXINT)) =  1162261467)的约数 这种方法是我 ...

  3. Struts2入门1 Struts2基础知识

    Struts2入门1 Struts2基础知识 20131130 代码下载: 链接: http://pan.baidu.com/s/11mYG1 密码: aua5 前言: 之前学习了Spring和Hib ...

  4. python遍历数据

    #coding=utf-8 import MySQLdb conn = MySQLdb.Connect(host = '127.0.0.1',port=3306,user='root',passwd= ...

  5. vs2012 MSDN帮助文档离线包下载安装方法

    vs2012安装文件 自带的 MSDN帮助文档不全, 需要自己手动添加需要的离线文档包, 具体方法如下 1. 打开 vs2012 2. 按 ctrl + alt + F1 打开帮助文档管理器 3. 在 ...

  6. Windows 8.1 with update 官方最新镜像汇总

    Windows 8.1 with update 官方最新镜像汇总,发布日期: 2014/12/16,Microsoft MSDN. 镜像更新日志: 12/29:32位大客户专业版中文版 12/24:6 ...

  7. 用DOS批处理实现FTP自动上传、下载、清理文件

    用DOS批处理实现FTP自动上传.下载.清理文件 最近好像特别的忙,好久没来写点东西了,今天写了一个利用批处理程序完成FTP自动上传.下载.清理文件的程序.赶紧 记录下来,以备日后之用.功能介绍:自动 ...

  8. IOS适配

    • Default.png(图片尺寸为320x480):显示在非Retina-3.5英寸屏幕上(iPhone3G\iPhone3GS,屏幕分辨率为320x480) • Default@2x.png(图 ...

  9. 100+诡异的数据集,20万Eclipse Bug、死囚遗言等

    摘要:近日,Robert Seaton整理了100多个最有趣的数据集,其中包括Jeopardy真题,死囚的最后一句话,20万个Eclipse Bug,足球比赛相关,柏拉图式的爱情,太阳系以外的行星,1 ...

  10. SK-Learn使用NMF(非负矩阵分解)和LDA(隐含狄利克雷分布)进行话题抽取

    英文链接:http://scikit-learn.org/stable/auto_examples/applications/topics_extraction_with_nmf_lda.html 这 ...