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



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

  • 相关阅读:
    tomcat shutdown后,进程还存在linux系统中的解决办法
    nginx反向代理tcp协议的80端口
    redis集群搭建中遇到的一些问题
    《将博客搬至CSDN》
    最短路路径(1.1版待更新)
    线段树
    SDUT 3341 数据结构实验之二叉树二:遍历二叉树
    二叉树的遍历
    爆头题HDU
    图的入度和出度以及图的新的存储形式
  • 原文地址:https://www.cnblogs.com/whoknows/p/javascript_short_circuiting.html
Copyright © 2020-2023  润新知