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

我看到这件事的背景是,

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

当前回答

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

var foo = "Hello, World!";

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

其他回答

! 是“Boolean not”,这实际上是将“enable”的值类型化为其布尔值的相反值。第二个!翻转此值。所以enable表示“不启用”,将enable值作为布尔值。

沏茶:

!! 不是运算符。这是双重用途!--这是逻辑“not”运算符。


理论上:

! 确定值不是什么的“真相”:

事实是假的不是真的(这就是为什么!假的结果真实)事实是真的不是假的(这就是为什么!真的结果假)


!! 确定值不是什么的“真相”:

事实是真的不是假的(这就是为什么!!真的结果是真的)事实是,假的不是假的(这就是为什么!!假的结果是假的)


我们希望在比较中确定的是参考值的“真相”,而不是参考本身的值。在一个用例中,我们可能想知道值的真实性,即使我们希望值为false(或false),或者如果我们希望值不是布尔类型。


在实践中:

考虑一个简洁的函数,它通过动态类型(也称为“鸭子类型”)来检测特性功能(在本例中,还包括平台兼容性)。如果用户的浏览器支持HTML5<audio>元素,我们希望编写一个返回true的函数,但如果<audio<未定义,我们不希望该函数抛出错误;我们不想使用try。。。捕捉以处理任何可能的错误(因为它们很严重);此外,我们也不希望在函数中使用无法始终揭示功能真相的检查(例如,document.createElement('audio')仍将创建一个名为<audio>的元素,即使不支持HTML5<audio')。


以下是三种方法:

// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }

// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }

// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }

foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true

每个函数都接受一个<tag>参数和一个要查找的属性,但它们都会根据比较结果返回不同的值。

但等等,还有更多!

你们中的一些人可能注意到,在这个特定的示例中,可以使用稍微更高性能的方法来检查对象是否具有属性。有两种方法可以做到这一点:

// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }

// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }

qux('audio', 'preload');  // returns true
quux('audio', 'preload'); // returns true

我们离题了。。。

无论这些情况多么罕见,可能存在一些情况,其中最简洁、最高效,因此最优选的从非布尔值(可能是未定义的值)获得真值的方法确实是使用!!。希望这可笑地澄清了这一点。

有时,有必要检查函数中是否有值,数量本身对我们来说并不重要,但它是否重要。

例如,我们想检查用户是否有专业,并且我们有一个如下的功能:

hasMajor() {return this.major} // It returns "(users major is) Science"

但答案对我们来说并不重要。我们只想检查它是否有主,我们需要一个布尔值(true或false)。我们如何得到它?

就像这样:

hasMajor() { return !(!this.major)}

或相同

hasMajor() {return !!this.major)}

如果this.major有值,那么!this.major返回false,但因为值有出口,我们需要返回true,所以我们使用!两次返回正确答案!(!this.major)。

这是我找到的最简单的答案:它的工作方式相当于布尔值。

JavaScript中的一些运算符执行隐式类型转换,有时用于类型转换。

一元!运算符将其操作数转换为布尔值并对其求反。

这一事实导致了以下习惯用法,您可以在源代码中看到:

!!x // Same as Boolean(x). Note double exclamation mark