这是双倍的 not 操作。首先 ! 将值转换为布尔值并反转其逻辑值。第二 ! 将逻辑值反转回来。
not
!
双布尔否定。通常用于检查值是否未定义。
!! 将其右侧的值转换为其等效的布尔值。 (想想穷人的“打字”方式)。它的 意图 通常是向读者传达代码并不关心 什么 值在变量中,但它是什么 “真理”的价值 是。
!!
它模拟了行为 Boolean() 铸造功能。 首先 NOT 无论给出什么操作数,都返回一个布尔值。第二 NOT 否定这一点 Boolean 价值等等给出了 true 变量的布尔值。最终结果与使用相同 Boolean() 函数值。
Boolean()
NOT
Boolean
true
该 !! construct是一种将任何JavaScript表达式转换为的简单方法 它的布尔等价物。
例如: !!"he shot me down" === true 和 !!0 === false 。
!!"he shot me down" === true
!!0 === false
返回变量的布尔值。
代替, Boolean 可以使用类。
(请阅读代码说明)
var X = "test"; // X value is "test" as a String value var booleanX = !!X // booleanX is `true` as a Boolean value beacuse non-empty strings evaluates as `true` in boolean var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again console.log(Boolean(X) === !!X) // writes `true`
也就是说, Boolean(X) = !!X 正在使用。
Boolean(X) = !!X
请检查下面的代码段 的 ↓ 强>
let a = 0 console.log("a: ", a) // writes a value in its kind console.log("!a: ", !a) // writes '0 is NOT true in boolean' value as boolean - So that's true.In boolean 0 means false and 1 means true. console.log("!!a: ", !!a) // writes 0 value in boolean. 0 means false. console.log("Boolean(a): ", Boolean(a)) // equals to `!!a` console.log("\n") // newline a = 1 console.log("a: ", a) console.log("!a: ", !a) console.log("!!a: ", !!a) // writes 1 value in boolean console.log("\n") // newline a = "" console.log("a: ", a) console.log("!a: ", !a) // writes '"" is NOT true in boolean' value as boolean - So that's true.In boolean empty strings, null and undefined values mean false and if there is a string it means true. console.log("!!a: ", !!a) // writes "" value in boolean console.log("\n") // newline a = "test" console.log("a: ", a) // writes a value in its kind console.log("!a: ", !a) console.log("!!a: ", !!a) // writes "test" value in boolean console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true
使用logical not运算符两次 的 这意味着!true = false 和!! !! true = true 强>
我认为值得一提的是,结合逻辑AND / OR的条件不会返回布尔值但是最后成功或者在&&和 在||的情况下,第一次成功或最后一次失败条件链。
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
!是“boolean not”,它基本上将“enable”的值强制转换为其布尔相反的值。第二 !翻转此值。所以, !!enable 意思是“不能启用”,给你的价值 enable 作为布尔值。
!!enable
enable
它不是一个单一的运营商,而是两个。它等同于以下内容,是一种将值转换为布尔值的快速方法。
val.enabled = !(!enable);
JavaScript中的某些运算符执行隐式类型转换,有时也是如此 用于类型转换。
一元 ! 运算符将其操作数转换为布尔值并取消它。
这个事实导致您可以在源代码中看到以下习语:
!!x // Same as Boolean(x). Note double exclamation mark
在看到所有这些好的答案之后,我想补充另一个使用原因 !! 。我正在使用Angular 2-4(TypeScript),我想返回一个布尔值 false 当我的用户未经过身份验证时。如果未经过身份验证,则令牌字符串将是 null 要么 "" 。我可以通过使用下一个代码块来做到这一点:
false
null
""
public isAuthenticated(): boolean { return !!this.getToken(); }
的 泡一些茶: 强>
!! 不是运营商。它是两用的 ! - 这是逻辑“非”运算符。
的 理论上: 强>
的 ! 强> 确定价值不是什么的“真相”:
事实是这样的 false 不是 true (这就是为什么 !false 结果 在 的 true 强> )
!false
事实是这样的 true 不是 false (这就是为什么 !true 结果 在 的 false 强> )
!true
的 !! 强> 确定价值是什么的“真相” 不 不:
事实是这样的 true 不是 不 true (这就是为什么 !!true 结果是 的 true 强> )
!!true
事实是这样的 false 不是 不 false (这就是为什么 !!false 结果是 的 false 强> )
!!false
我们希望在比较中确定的是“真相” 关于 参考的价值,而不是 的价值 引用本身。有一个用例我们可能想知道一个值的真相,即使我们期望值是这样的 false (或假的),或者如果我们期望价值不是类型的 boolean 。
boolean
的 在实践中: 强>
考虑一个简洁的功能,通过它来检测功能功能(在这种情况下,平台兼容性) 的 动态打字 强> (又名“鸭子打字”)。我们想写一个返回的函数 true 如果用户的浏览器支持HTML5 <audio> 元素,但我们不希望函数抛出错误,如果 <audio> 未定义;我们不想使用 try ... catch 处理任何可能的错误(因为它们很严重); 并且 我们不想在函数内部使用检查,这些检查不能始终如一地揭示该功能的真相(例如, document.createElement('audio') 仍然会创建一个名为的元素 <audio> 即使HTML5 <audio> 不支持)。
<audio>
try ... catch
document.createElement('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> 和 attribute 寻找,但他们每个都根据比较确定的值返回不同的值。
<tag>
attribute
的 但等等,还有更多! 强>
你们中的一些人可能已经注意到,在这个具体的例子中,人们可以简单地使用稍微检查属性 的 性能更高 强> 检查相关对象的方法 具有 财产。有两种方法可以做到这一点:
// 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
的 我们离题了...... 强>
无论这些情况多么罕见,可能存在一些场景,其中最简洁,最高效,最优选的获取方式 true 从非布尔,可能是未定义的值确实是通过使用 !! 。希望这可笑地清除它。
这里有很多很好的答案,但是如果你读到这么远,这有助于我“得到它”。在Chrome(等)上打开控制台,然后输入:
!(!(1)) !(!(0)) !(!('truthy')) !(!(null)) !(!('')) !(!(undefined)) !(!(new Object()) !(!({})) woo = 'hoo' !(!(woo)) ...etc, etc, until the light goes on ;)
当然,这些都只是键入!! someThing,但添加的括号可能有助于使其更容易理解。
胁迫 oObject 到布尔值。如果它是假的(例如0, null , undefined 等等),它会 false , 除此以外, true 。
oObject
undefined
!oObject //Inverted boolean !!oObject //Non inverted boolean so true boolean representation
所以 !! 不是运营商,只是 ! 操作员两次。
真实世界示例“测试IE版本”:
let isIE8 = false; 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
它只是逻辑NOT运算符,两次 - 它用于将某些东西转换为布尔值,例如:
true === !!10 false === !!0
好像是 !! 运算符导致双重否定。
var foo = "Hello World!"; !foo // Result: false !!foo // Result: true
!!foo 应用一元not运算符两次,并用于转换为类似于使用一元加号的布尔类型 +foo 转换为数字并连接空字符串 ''+foo 转换为字符串。
!!foo
+foo
''+foo
您也可以使用与基元类型对应的构造函数(而不是这些黑客)( 无 运用 new )明确地施放价值,即
new
Boolean(foo) === !!foo Number(foo) === +foo String(foo) === ''+foo
我怀疑这是C ++的遗留物,人们会覆盖它!运营商,但不是bool运营商。
因此,要获得负面(或肯定)答案,您首先需要使用!运算符得到一个布尔值,但如果你想检查肯定的情况会使用!!
!!x 是简写 Boolean(x)
!!x
Boolean(x)
第一次爆炸迫使js引擎运行 Boolean(x) 但也有反转价值的副作用。所以第二次爆炸会解除副作用。
a = 1; alert(!a) // -> false : a is not not defined alert(!!a) // -> true : a is not not defined
对于 !a ,它检查是否 a 是 的 不 强> 定义,而 !!a 检查变量是否已定义。
!a
a
!!a
!!a 是相同的 !(!a) 。如果 a 被定义为, a 是 true , !a 是 false ,和 !!a 是 true 。
!(!a)
它强制所有事物都布尔。
例如:
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); // -> undefined console.log(!0 === false); // -> false console.log(!!0 === false); // -> true
该 if 和 while 陈述和 ? 运算符使用真值来确定要运行的代码分支。例如,零和NaN数字以及空字符串为false,但其他数字和字符串为true。对象是真的,但未定义的值和 null 都是假的。
if
while
?
双重否定算子 !! 计算值的真值。它实际上是两个运营商,在那里 !!x 手段 !(!x) ,行为如下:
!(!x)
x
!x
在布尔上下文的顶层使用时( if , while , 要么 ? ), !! 运营商在行为上是一种无操作。例如, if (x) 和 if (!!x) 意思是一样的。
if (x)
if (!!x)
然而,它有几个实际用途。
一种用途是将对象有损压缩到其真值,这样您的代码就不会持有对大对象的引用并使其保持活动状态。分配 !!some_big_object 变量而不是变量 some_big_object 让我们去垃圾收集器吧。这对于生成对象或伪值的情况很有用 null 或未定义的值,例如浏览器功能检测。
!!some_big_object
some_big_object
另一种用途,我在一篇文章中提到过 回答关于C的相应问题 !! 操作者 ,使用“lint”工具寻找常见的拼写错误和打印诊断。例如,在C和JavaScript中,布尔运算的一些常见拼写错误会产生其输出不完全布尔的其他行为:
if (a = b)
b
if (a == b)
if (a & b)
if (a && b)
2 & 5
0
2 && 5
该 !! 操作员向lint工具保证你写的是你的意思:做这个操作,然后取结果的真值。
第三种用途是产生逻辑XOR和逻辑XNOR。在C和JavaScript中, a && b 执行逻辑AND(如果双方都为真,则为true),和 a & b 执行按位AND。 a || b 执行逻辑OR(如果至少有一个为真,则为true),和 a | b 执行按位OR。有一个按位XOR(异或) a ^ b ,但是没有用于逻辑XOR的内置运算符(如果恰好一侧为真,则为true)。例如,您可能希望允许用户在两个字段中的一个字段中输入文本。你可以做的是将每个转换为真值并比较它们: !!x !== !!y 。
a && b
a & b
a || b
a | b
a ^ b
!!x !== !!y
这是一段来自角js的代码
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被定义为undefined则 !requestAnimationFrame将是真的,还有一个!这将是错误的