12

!!x将变量的类型强制x为布尔值,同时保持其真实性或缺乏真实性 -请参阅这个问题- 我有一个关于在条件表达式中使用 this 的问题。

在 JS 代码中,我曾见过几次在这样!!的条件下将变量强制转换为布尔类型if

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

想法是x在调用方法之前测试是否已定义。

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

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

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

所以我的问题是在这种情况下强制x使用布尔值有什么意义!!这段代码做了什么而这段代码没有?

4

3 回答 3

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 > 0

两者之间产生的结果没有任何区别,而且您甚至没有节省字节,因为两个语句都采用相同数量的字符。但是我创建了一个测试用例,双重否定似乎表现更好,但它可能在所有浏览器中都不一致。

于 2013-09-06T01:02:01.173 回答
0

如前所述,它将值转换为布尔值,因此与if(x). 但是,两者都很棘手,因为它也会转换0false其他类似的东西。

于 2013-09-06T00:59:43.937 回答
0

它与 JavaScript 类型强制有关。

通常你想检查一个对象是否不为空、不为未定义、不为 0 等。常见的检查方法是

if (obj) {
  ...
}

但是,如果您希望条件等于true或可以在非布尔对象实例上使用false!这是一个使用===不进行类型强制的相等运算符的示例。

var obj = {};

console.log(obj === true); // returns false
console.log(!obj === false); // returns true
console.log(!!obj === true); // returns true
于 2013-09-06T01:01:37.313 回答