开发者社区> 问答> 正文

javascript之if(value)和if(!!value)的区别

偶然有看到高手写的代码,其中if(value)都写成了if(!!value),不太理解,所以在这里求解高手,它们的区别。

展开
收起
云栖技术 2016-05-25 10:10:23 2540 0
1 条回答
写回答
取消 提交回答
  • 社区爱好者,专为云栖社区服务!

    没有任何区别。这种写法只是想当然而已。我反对if (!!var1)的写法。
    同样无聊的写法还有:if ((var1 == var2) == true)。

    if 接受“A condition expression that evaluates to true or false”,并非必须PrimitiveBoolean类型。
    在《ECMAScript Spec》中,if (value)的语义相当于:if (ToBoolean(value))。
    而Logical Not的语义相当于:not ToBoolean(value)。
    即!!val相当于ToBoolean(value)。
    也就是说:if (!!value)的语义相当于if(ToBoolean(ToBoolean(value)))。
    如果你认为这种写法是合理的,那你为什么不继续写道:
    `if (!!(!!value))、
    if (!!(!!(!!value)))
    ……?
    `

    什么时候需要使用Logical Not !来转换类型呢?一般函数传参或返回值有这个必要。如果函数文档中说它返回一个Bool类型的值,那么函数作者就有责任保证其返回值的类型为(Primitive)Boolean。因为函数的使用者可能会写出依赖返回值类型的代码:

    /**
    @returns Bool
    */
    function has(str,substr) {
      return !!~str.indexOf(substr);
      //return ~str.indexOf(substr); // wrong!!!
    }
    //函数使用者的代码:
    JSON.stringify({
      //此选项值类型早约定为Enum(0|1)
      xxxOptionOnOff:+has(s,"xxx") //使用者依赖于Bool to Number的转换
    });

    同作向函数传参也需要注意类型:

    /**
    @param {Bool} flag
    */
    function toggle(flag) {
      //期望设置className为 toggle-on-true 或toggle-on-false
      //尽管不推荐这种过于依赖Bool参数类型的代码,但既然文档声明是Bool类型
      //传参者就有必要保证参数类型正确,即使是JS这种弱类型语言
      ele.className= "toggle-on-"+flag;
    }
    toggle(!!btn.checked);
    //toggle(btn.checked); //wrong! btn.checked可能返回String "checked"
    2019-07-17 19:13:36
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
JavaScript异步编程 立即下载
Delivering Javascript to World 立即下载
编程语言如何演化-以JS的private为例 立即下载