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

我看到这件事的背景是,

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

当前回答

使用逻辑not运算符两次。

这意味着!true=false和!!true=真。

其他回答

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

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

!! 将其右侧的值转换为其等效的布尔值。(想想穷人的“类型转换”方式。)其目的通常是向读者传达,代码不关心变量中的值,而是关心变量的“真值”值。

我只是想补充一下

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相同。

它将Object转换为布尔值。如果为假(例如,0、null、undefined等),则为假,否则为真。

!object  // Inverted Boolean
!!object // Noninverted Boolean, so true Boolean representation

所以不是操作员;这只是!操作员两次。

这样做可能更简单:

Boolean(object) // Boolean

真实世界示例“测试IE版本”:

const isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);
console.log(isIE8); // Returns true or false

如果你⇒

console.log(navigator.userAgent.match(/MSIE 8.0/));
// Returns either an Array or null

但如果你⇒

console.log(!!navigator.userAgent.match(/MSIE 8.0/));
// Returns either true or false

!! 不是运算符。这只是!操作员两次。

但使用JavaScript,应用!!在大多数情况下,将Object转换为Boolean是冗余和冗长的,因为:

值未定义或为空的任何对象,包括值为false的布尔对象,传递给有条件的陈述

示例:if({}){console.log(“{}是true”)}//logs:“{}是true”