我看到一些代码似乎使用了我不认识的运算符,以两个感叹号的形式,像这样:!!。有人能告诉我这个接线员做什么吗?

我看到这件事的背景是,

this.vertical = vertical !== undefined ? !!vertical : this.vertical;

当前回答

这个问题已经得到了非常彻底的回答,但我想补充一个答案,我希望这个答案尽可能简化,使!!尽可能简单地掌握。

因为JavaScript具有所谓的“truthy”和“falsy”值,所以有些表达式在其他表达式中求值时会导致true或false条件,即使所检查的值或表达式实际上不是true或false。

例如:

if (document.getElementById('myElement')) {
    // Code block
}

如果该元素确实存在,则表达式将求值为true,并执行代码块。

然而:

if (document.getElementById('myElement') == true) {
    // Code block
}

…将不会导致真条件,并且代码块将不会被执行,即使元素确实存在。

为什么?因为document.getElementById()是一个“truthy”表达式,它在这个if()语句中的值为true,但它不是一个真正的布尔值true。

在这种情况下,双“not”相当简单。这只是背靠背的两个不。

第一个简单地“反转”真值或假值,产生实际的布尔类型,然后第二个简单地将其“反转”回原始状态,但现在是实际的布尔值。这样你就有了一致性:

if (!!document.getElementById('myElement')) {}

and

if (!!document.getElementById('myElement') == true) {}

将如预期的那样返回true。

其他回答

这是一种非常晦涩的类型转换方法。

! 表示不。所以真是假的,而且!假是真!0为真,并且!1为假。

所以你要将一个值转换成布尔值,将其反转,然后再次反转。

// Maximum Obscurity:
val.enabled = !!userId;

// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;

// And finally, much easier to understand:
val.enabled = (userId != 0);

// Or just
val.enabled = Boolean(userId);

注意:由于!=运算符的作用以及哪些值被认为是正确的。

它将所有的东西都强制为布尔值。

例如:

console.log(undefined);   // -> undefined
console.log(!undefined);  // -> true
console.log(!!undefined); // -> false

console.log('abc');   // -> abc
console.log(!'abc');  // -> false
console.log(!!'abc'); // -> true

console.log(0 === false);   // -> false
console.log(!0 === false);  // -> false
console.log(!!0 === false); // -> true

!!expr(后跟表达式的两个!运算符)根据表达式的真实性返回布尔值(true或false)。当用于非布尔类型时,它更有意义。考虑以下示例,尤其是第三个示例及其后续示例:

          !!false === false
           !!true === true

              !!0 === false
!!parseInt("foo") === false // NaN is falsy
              !!1 === true
             !!-1 === true  // -1 is truthy
          !!(1/0) === true  // Infinity is truthy

             !!"" === false // empty string is falsy
          !!"foo" === true  // non-empty string is truthy
        !!"false" === true  // ...even if it contains a falsy value

     !!window.foo === false // undefined value is falsy
      !!undefined === false // undefined primitive is falsy
           !!null === false // null is falsy

             !!{} === true  // an (empty) object is truthy
             !![] === true  // an (empty) array is truthy; PHP programmers beware!

以下是AngularJS的一段代码:

var requestAnimationFrame = $window.requestAnimationFrame ||
                            $window.webkitRequestAnimationFrame ||
                            $window.mozRequestAnimationFrame;

var rafSupported = !!requestAnimationFrame;

他们的意图是根据requestAnimationFrame中函数的可用性将rafSupported设置为true或false。

通常可以通过以下方式进行检查:

if(typeof requestAnimationFrame === 'function')
    rafSupported =true;
else
    rafSupported =false;

这条短路可以用!!

rafSupported = !!requestAnimationFrame;

因此,如果requestAnimationFrame被分配了一个函数,那么!requestAnimationFrame将为false,还有一个!这是真的。

如果requestAnimationFrame未定义,则!requestAnimationFrame将是真的,还有一个!这将是错误的。

它模拟Boolean()转换函数的行为。无论给定什么操作数,第一个NOT都返回布尔值。第二个NOT否定该布尔值,从而给出变量的真正布尔值。最终结果与对值使用Boolean()函数相同。