双感叹号?

时间:2012-02-14 21:47:17

标签: javascript

  

可能重复:
  What is the !! (not not) operator in JavaScript?
  What does the !! operator (double exclamation point) mean in JavaScript?

所以我正在调试一些代码并遇到了这个问题:

var foo.bar = 0; // this is actually passed from another function, adding it for context

function(foo) {
    var someVar = !!foo.bar;

    if (foo.bar) {
      // ..stuff happens
    } else {
      // .. something else happens
    }
}

好的,我的问题是!!的重点是什么?所做的只是制作0 === false

  1. boolean(foo.bar)相比,使用它有什么好处?

  2. foo.bar可以按原样进行评估,因为已经0 === false,所以为什么要进行转换呢? (someVar不会在其他任何地方重复使用)

3 个答案:

答案 0 :(得分:273)

这会将值转换为布尔值,确保布尔类型

"foo"      // Evaluates to "foo".
!"foo"     // Evaluates to false.
!!"foo"    // Evaluates to true.

如果foo.bar通过,那么它可能不是0而是其他一些假值。请参阅以下真值表:

javascript的真实表

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true
  

资料来源:Doug Crockford

当谈到NaN值时,Javascript也变得非常奇怪。这是我能想到的最好的情况!会对===表现不同。

NaN   ===  NaN     //false
!!NaN === !!NaN    //true

// !!NaN is false

答案 1 :(得分:13)

我认为答案是没有太多意义。我们可以推测它是如何产生的:

  • 可能是在多个地方使用someVar的函数的早期版本,或者是真正受益于truefalse的方式,所以这更有意义。
  • 也许编写该函数的人习惯使用!!转换为true / false他甚至没有注意到它是没有必要的这里。
  • 也许编写该函数的人感觉每个计算(在这种情况下,布尔转换)都应该通过为其结果赋予一些变量来赋予一个有意义的名称。
  • 也许,因为JavaScript中的布尔转换出乎意料地容易出错(因为例如new Boolean(false)是一个真值值),编写函数的人觉得它应该总是明确地而不是隐式地完成 - 即使效果是相同的 - 只是把注意力作为一个潜在的错误点。
    • 当然,这预先假定编写该函数的人认为!!是“显式”布尔转换。从技术上讲,它不是 - 它使用if所做的相同的隐式布尔转换 - 但如果你已经习惯了这个习语,那么它就等于显式转换。

但在我的主观意见中,这些原因都不是一个很好的原因!

答案 2 :(得分:5)

如上所述,它强制使用布尔类型的对象。你可以亲眼看看:

(function typecheck() {
  var a = "a";
  var b = !a;
  var c = !!a;

  alert("var a = " + typeof(a) + "\n" +
        "var b = " + typeof(b) + "\n" +
        "var c = " + typeof(c));
})();

如果您只是进行比较,转换只会在以后为您节省类型强制。

仅供参考,以下值在JavaScript中被强制为FALSE:

  • 0
  • “”
  • 未定义