关于javascript:双感叹号?

Double exclamation points?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What is the !! (not not) operator in JavaScript?
What does the !! operator (double exclamation point) mean in JavaScript?

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

1
2
3
4
5
6
7
8
9
10
11
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
    }
}

好吧,我的问题是,!!的意义是什么?现在所做的一切都是制造江户X(1)。

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

  • foo.bar可以在if-as-is中进行评估,因为0 === false已经存在,那么为什么要进行转换呢?(somevar不能在其他任何地方重复使用)


  • 这会将值转换为布尔值并确保布尔类型。

    1
    2
    3
    "foo"      // Evaluates to"foo".
    !"foo"     // Evaluates to false.
    !!"foo"    // Evaluates to true.

    如果通过foo.bar,那么它可能不是0,而是其他一些不稳定的值。见下表:

    javascript的真值表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ''        ==   '0'           // false
    0         ==   ''            // true
    0         ==   '0'           // true
    false     ==   'false'       // false
    false     ==   '0'           // true
    false     ==   undefined     // false
    false     ==   null          // false
    null      ==   undefined     // true
    " \t

    "
    ==   0             // true

    Source: Doug Crockford

    当涉及到NaN值时,JavaScript也会变得非常奇怪。这是我能想到的唯一一个例子,在我的头顶上!!的行为与===不同。

    1
    2
    3
    4
    NaN   ===  NaN     //false
    !!NaN === !!NaN    //true

    // !!NaN is false


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

    • 可能早期版本的函数在多个地方使用了someVar,或者以真正受益于truefalse的方式使用,所以这更合理。
    • 也许编写函数的人习惯于使用!!转换为truefalse,他甚至没有注意到这里没有必要。
    • 也许编写函数的人认为,每一个计算(在本例中是布尔转换)都应该通过为其结果分配一些变量来赋予一个有意义的名称。
    • 也许,因为javascript中的布尔转换非常容易出错(例如,new Boolean(false)是一个真正的值),所以编写函数的人认为应该始终显式地进行转换,而不是隐式地进行转换,即使效果是相同的,只是为了引起人们的注意,将其作为一个潜在的错误点。
      • 当然,这是假定编写函数的人认为!!是一个"显式"布尔转换。从技术上讲,它并不像if那样使用隐式布尔转换,但如果您习惯了这种习惯用法,那么它就相当于显式转换。

    但在我的主观看法中,这些理由都不是很好的理由!


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    (function typecheck() {
      var a ="a";
      var b = !a;
      var c = !!a;

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

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

    仅供参考,以下值在javascript中被强制为false:

    • "
    • 无效的
    • 未定义