zoukankan      html  css  js  c++  java
  • 从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吧

  • 相关阅读:
    HDU 2196 Computer
    HDU 1520 Anniversary party
    POJ 1217 FOUR QUARTERS
    POJ 2184 Cow Exhibition
    HDU 2639 Bone Collector II
    POJ 3181 Dollar Dayz
    POJ 1787 Charlie's Change
    POJ 2063 Investment
    HDU 1114 Piggy-Bank
    Lca hdu 2874 Connections between cities
  • 原文地址:https://www.cnblogs.com/whoknows/p/javascript_short_circuiting.html
Copyright © 2011-2022 走看看