这个表达式"!!"是什么意思?

5

为什么有人会使用像这样的表达:

if(!!window.JSON) alert('exists');

不仅仅是

if(window.JSON) alert('exists');

“!!”这个符号还有其他用途吗?


多重否定很难理解,这就是为什么。如果你在代码中继续使用 if(!!(!!)!!!(!)!!obj),那么只有你能够维护它(如果你很幸运的话) - 我并不蠢! - simendsjo
1
请参见http://stackoverflow.com/questions/1406604/what-does-the-operator-double-exclamation-point-mean-in-javascript/1407769#1407769;而且你是正确的,在这种情况下它是多余的,因为`if()`已经转换为布尔值。 - Christoph
5个回答

15
!! 会将值转化为布尔类型,但在 if 语句中使用这个构造是不必要的。在你的第一个代码片段中,将 对象 转换为布尔类型没有意义,它永远都是 true
只有 nullundefinedNaN0 和空字符串可以被强制转化为 false,任何其他值都将被强制转化为 true
当你想要确保得到一个布尔类型的结果时,使用 !! 是有意义的,例如在使用逻辑运算符 &&|| 时。
这些运算符可以返回操作数的值,而不是布尔类型的结果,例如:
true && "foo"; // "foo"
"foo" || "bar" ; // "foo"

假设你有一个测试两个值的函数,并且你期望获得一个布尔值的结果:

function isFoo () {
  return 0 && true;
}

isFoo(); // returns 0, here it makes sense to use !!

编辑:看了你的编辑,if (!!window.JSON) 就像我之前说的那样是多余的,因为 if 语句本身会在条件表达式评估时 内部 执行布尔转换。


看起来你想写的应该是类似这样的代码:function isFoo(obj){ return obj && true; } isFoo(0);在最后一个例子里:) 或者 return !!obj && true; - Markus Hedlund
false && "foo" 的结果为 false - Gumbo
@Gumbo:是的,那只是一个笔误,应该是 s/false/true。@Znarkus,没错,这只是为了说明问题而已 ;) 谢谢大家… - Christian C. Salvadó

2
// !! = boolean typecasting in javascript

var one = 1
var two = 2;

if (one==true) app.alert("one==true");
if (!!one==true) app.alert("!!one==true");

if (two==true) app.alert("two==true"); // won't produce any output
if (!!two==true) app.alert("!!two==true");

这就是为什么你应该使用 === 并显式转换类型:== 的类型转换规则有点让人摸不着头脑。 - Christoph

2

他们可能正在尝试将对象转换为布尔值。通过应用布尔运算符(!)到对象上,它变成了一个布尔值,但实际上他们并不想要取反,所以他们应用了第二个来取消第一个。


1

! 是逻辑否定,!! 是逻辑否定应用两次,即逻辑恒等式

我会假设你正在阅读的代码只是无害的(尽管令人困惑)冗余。


是的,但这个问题涉及到从对象到布尔值的隐式类型转换吗? - Emil Vikström

1

这是一个布尔转换,确保第一次转换为布尔值,然后再否定回原始值。

但是在这里使用不正确,只有在将其分配给另一个变量时才真正相关 - 出于性能原因。

var isJSON = (!!window.JSON);

if (isJSON) doX;
if (isJSON) doY;
if (isJSON) doZ;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接