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

我看到这件事的背景是,

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

当前回答

!! 只是两次NOT运算符。净效果就是转换任何东西以确保布尔数据类型。例如

!!undefined为false!!0为假!!null为false!!anyobject为true!!真是真!!false是false!0为真!1为假!!'' 是假的

其他回答

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

它将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

我认为值得一提的是,与逻辑“与/或”组合的条件不会返回布尔值,而是在&&的情况下返回最后一次成功或第一次失败,在条件链的||的情况下,返回第一次成功或最后一次失败。

res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'

为了将条件转换为真正的布尔文字,我们可以使用双重否定:

res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true

const foo=“bar”;console.log(!!foo);//布尔值:真

! 对值求反(反转),并始终返回/生成布尔值。所以!”bar'将产生false(因为'bar'是truthy=>否定+布尔值=false)。附加的!运算符,该值再次被求反,因此false变为true。

if和while语句以及?运算符使用真值来确定要运行的代码分支。例如,零和NaN数字以及空字符串为假,但其他数字和字符串为真。对象为true,但未定义的值和null均为false。

双重否定运算符!!计算值的真值。实际上是两个操作员,哪里!!x表示!(!x),并且行为如下:

如果x为假值!x为真,并且!!x为假。如果x是真值!x为假,并且!!x为真。

当在布尔上下文的顶层使用时(if、while或?)!!从行为上讲,操作员是一个no-op。例如,if(x)和if(!!x)表示相同的意思。

实际用途

然而,它有几个实际用途。

一种用法是将对象压缩到其真值,这样代码就不会保存对大对象的引用并保持其活动。分配!!some_big_object设置为变量,而不是some_biguobject让垃圾收集器使用它。这对于生成对象或假值(例如空值或未定义值)的情况非常有用,例如浏览器特征检测。

另一个用法,我在一个关于C对应的答案中提到了!!操作员使用“lint”工具查找常见的打字错误和打印诊断。例如,在C和JavaScript中,布尔运算的一些常见错误会产生其他输出不太布尔的行为:

如果(a=b)是赋值,然后使用b的真值;如果(a==b)是相等比较。如果(a&b)是位AND;如果(a&&b)是逻辑AND。2和5为0(假值);2&&5为真。

这个操作员向lint工具保证,您所写的就是您的意思:执行此操作,然后获取结果的真值。

第三种用途是产生逻辑XOR和逻辑XNOR。在C和JavaScript中,a&b都执行逻辑and(如果两边都为true,则为true),a&b执行逐位and。a||b执行逻辑或(如果至少有一个为真,则为真),a|b执行逐位或。有一个按位XOR(异或)作为^b,但没有用于逻辑XOR的内置运算符(如果只有一侧为真,则为真)。例如,您可能希望允许用户仅在两个字段中的一个字段中输入文本。您可以做的是将每个值转换为一个真值,并将它们进行比较:!!x!==!!y