为何使用!!将变量强制转换为布尔值以用于条件表达式?

时间:2013-09-06 00:49:32

标签: javascript

!!x将变量x的类型强制转换为布尔值,同时保持其真实性或缺乏真实性 - see this question - 我对在条件表达式中使用它有疑问。< / p>

在JS代码中有几次我看到!!用于在if条件下将变量强制转换为布尔类型,如此

if(!!x) {
    x.doStuff();
}

其中的想法是在调用方法之前测试是否定义了x

但是,在我自己的代码中,我总是只使用

if(x) {
    x.doStuff();
}

前提是如果定义x,则条件将通过,如果x未定义,则不会通过。

所以我的问题是在这种情况下使用x!!强制转换为布尔值是什么意思? this code做了什么{{3不是吗?

3 个答案:

答案 0 :(得分:11)

在那个特定的上下文中,我会说使用!!明确地转换为布尔值之间没有区别,或者让if表达式自然地转换为布尔值。我的意思是if (x)将被解释为if (Boolean(x)),与if (!!x)相同。

但是,如果要从函数返回值,例如,如果要实现arrayHasItems函数,则可以通过以下方式实现:

function arrayHasItems(arr) {
    return arr.length;
}

在if语句中使用该函数将起作用,因为从函数返回的数值将转换为布尔值。但是,客户端代码期望函数返回一个布尔值,因此他可能会通过执行以下操作来检查条件:

if (arrayHasItems(arr) === true) {}

在这种情况下,它会失败,因为arrayHasItems的返回结果是一个数字。 因此,最好通过返回一个类似于期望的布尔值来实现该函数。

function arrayHasItems(arr) {
    return !!arr.length;
}

编辑:

  

这提出了一个新问题:为什么!! arr.length而不仅仅是   arr.length&gt; 0

在生成的结果中,两者之间没有任何区别,因为两个语句都使用相同数量的字符,所以甚至不保存字节。但是我创建了test case并且双重否定似乎表现更好,但它可能在所有浏览器中都不一致。

答案 1 :(得分:0)

如上所述,它将值转换为布尔值,因此与if(x)没有太大区别。但是,两者都很棘手,因为它还会将0转换为false以及其他类似的东西。

答案 2 :(得分:0)

它与JavaScript类型的coersion有关。

通常你想检查对象是否为空,不是未定义,不是0等。检查对象的常用方法是

if (obj) {
  ...
}

但是,如果您希望条件等于truefalse,则可以在非布尔对象实例上使用!。下面是一个使用不执行类型coersion的等于运算符===的示例。

var obj = {};

console.log(obj === true); // returns false
console.log(!obj === false); // returns true
console.log(!!obj === true); // returns true