这么多的答案完成了一半的工作。是的,!!X
可以理解为“ X(表示为布尔值)的真实性”。但是!!
,实际上,对于弄清单个变量是真实的还是虚假的,并不是那么重要。!!myVar === true
和刚好一样myVar
。与!!X
“真实”布尔值进行比较并没有真正的用处。
您将获得以可重复,标准化(和JSLint友好)方式相互!!
检查多个变量的真实性的能力。
简单地铸造:(
那是...
0 === false
是false
。
!!0 === false
是true
。
以上不是那么有用。if (!0)
给您与相同的结果if (!!0 === false)
。我想不出将变量转换为布尔值然后与“ true”布尔值进行比较的好例子。
请从JSLint的指导中查看“ ==和!=“ (注意:Crockford 会将其站点稍微移动一下;该链接可能会在某个时间点消失),其中有一些原因:
==和!=运算符会在比较之前键入强制。这很糟糕,因为它导致'\ t \ r \ n'== 0为真。这可以掩盖类型错误。JSLint无法可靠地确定==是否正确使用,因此最好不要使用==和!=,而始终使用更可靠的===和!==运算符。
如果只在乎某个值是真实的还是虚假的,则使用缩写形式。代替
(foo != 0)
说啊
(foo)
而不是
(foo == 0)
说
(!foo)
请注意,有一些直观的情况下,其中一个布尔值将被转换为数值(true
强制转换1
并false
以0
比较一个布尔值的号码时)。在这种情况下,!!
可能对精神有用。同样,在这些情况下,您正在将非布尔值与硬类型的布尔值进行比较,这是一个严重的错误。 if (-1)
仍然是去这里的路。
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║ Original ║ Equivalent ║ Result ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam") ║ if (-1 == 1) ║ undefined ║
║ if (-1 == false) console.log("spam") ║ if (-1 == 0) ║ undefined ║
║ Order doesn't matter... ║ ║ ║
║ if (true == -1) console.log("spam") ║ if (1 == -1) ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam") ║ if (truthy) ║ spam ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
而且取决于您的引擎,事情变得更加疯狂。以WScript为例。
function test()
{
return (1 === 1);
}
WScript.echo(test());
由于Windows的某些历史记录,将在消息框中输出-1!在cmd.exe提示中尝试一下,看看!但WScript.echo(-1 == test())
仍然给您0或WScript的false
。别看 太可怕了
比较真实性:)
但是,如果我有两个值需要检查真实性/虚假性,该怎么办?
假装我们有myVar1 = 0;
和myVar2 = undefined;
。
myVar1 === myVar2
是0 === undefined
而且显然是错误的。
!!myVar1 === !!myVar2
是!!0 === !!undefined
,是真的!同样的真实性!(在这种情况下,两个“都具有虚假的真实性”。)
因此,您真正需要使用“布尔值转换变量”的唯一地方是,如果您要检查两个变量是否具有相同的真实性,对吗?也就是说,使用!!
,如果你需要查看两个瓦尔是既truthy或两者falsy(或没有),也就是相等(或没有)感实性。
我无法想到一个出色的,非人为的用例。也许您具有表单中的“链接”字段?
if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
errorObjects.spouse = "Please either enter a valid name AND age "
+ "for your spouse or leave all spouse fields blank.";
}
因此,现在,如果您对配偶双方的姓名和年龄均不真实,或者对配偶姓名和年龄均不真实,则可以继续。否则,您只有一个带有值的字段(或者很早就安排了婚姻),并且需要在errorObjects
集合上创建一个额外的错误。
编辑2017年10月24日,19年2月6日:
期望显式布尔值的第三方库
这是一个有趣的情况... !!
当第三方库期望显式布尔值时可能会有用。
例如,JSX(React)中的False具有特殊含义,不会因简单的虚假行为而触发。如果您尝试在JSX中返回类似以下的内容,则期望int messageCount
...
{messageCount && <div>You have messages!</div>}
...当您收到0
零条消息时,看到React渲染一个可能会让您感到惊讶。您必须显式返回false才能使JSX无法呈现。上面的语句返回0
,由JSX愉快地呈现。它不能告诉您没有Count: {messageCount && <div>Get your count to zero!</div>}
(或其他较不人为的东西)。
一种解决方法是将bangbang强制0
转换为!!0
,即false
:
{!!messageCount && <div>You have messages!</div>}
JSX的文档建议您更加明确,编写自我注释的代码,并使用比较来强制使用布尔值。
{messageCount > 0 && <div>You have messages!</div>}
我更愿意用三元来处理虚假行为-
{messageCount ? <div>You have messages!</div> : false}
在Typescript中也是如此:如果您有一个返回布尔值的函数(或者您正在为布尔变量赋值),则[通常]您不能返回/分配布尔y值;它必须是一个强类型的布尔值。这意味着,iff myObject
是强类型的,return !myObject;
适用于返回布尔值的函数,但return myObject;
不能返回布尔值。您必须return !!myObject
符合Typescript的期望。
Typescript例外?如果myObject
为any
,则返回JavaScript的Wild West !!
,即使返回类型为布尔值,也可以不带返回。
请记住,这些是JSX和Typescript约定,而不是JavaScript固有的约定。
但是,如果0
在渲染的JSX中看到奇怪的,请考虑宽松的虚假管理。