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

我看到这件事的背景是,

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

当前回答

在看到所有这些伟大的答案后,我想补充一个使用!!的理由!!。目前,我正在使用Angular 2-4(TypeScript),当我的用户未通过身份验证时,我希望将布尔值返回为false。如果他未通过身份验证,则令牌字符串将为null或“”。我可以通过使用下一段代码来实现这一点:

public isAuthenticated(): boolean {
   return !!this.getToken();
}

其他回答

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

看来是!!运算符导致双重否定。

var foo = "Hello, World!";

!foo // Result: false
!!foo // Result: true

这是一次双重手术。第一个!将值转换为布尔值并反转其逻辑值。第二个!反转逻辑值。

我怀疑这是C++遗留下来的东西,在那里人们会重写!运算符,但不是布尔运算符。

因此,在这种情况下,要获得否定(或肯定)答案,首先需要使用!运算符来获取布尔值,但如果您想检查正数,则可以使用!!。

我只是想补充一下

if(variableThing){
  // do something
}

if(!!variableThing){
  // do something
}

但当某些东西未定义时,这可能是一个问题。

// a === undefined, b is an empty object (eg. b.asdf === undefined)
var a, b = {};

// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar

a.foo 
b.foo.bar

// This works -- these return undefined

a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar

这里的技巧是,&&s链将返回它找到的第一个假值,这可以被馈送到if语句等。因此,如果b.foo未定义,它将返回undefined并跳过b.foo.bar语句,我们不会得到任何错误。

上面的返回未定义,但如果您有一个空字符串,false,null,0,undefined,这些值将返回,一旦我们在链中遇到它们——[]和{}都是“truthy”,我们将沿着所谓的“&&链”继续到右边的下一个值。

P.S.执行上述(b&&b.foo)的另一种方法是(b||{}).foo。这些方法是等效的,因为如果b未定义,则b||{}将为{},并且您将访问空对象中的值(无错误),而不是尝试访问“undefined”中的值。

因此,(b||{}).foo与b&&b.foo相同,((b||{})/foo||{}).bar与b&&b.foo&&b.foo.bar相同。