这么多答案做了一半的工作。是的,!!X 可以理解为“X 的真实性 [表示为布尔值]”。但实际上,!! 对于确定单个变量是(或者即使许多变量是)真还是假并不是那么重要。 !!myVar === true 与 myVar 相同。将 !!X 与“真正的”布尔值进行比较并不是很有用。
您使用!! 获得的唯一好处是能够以可重复、标准化(且 JSLint 友好)的方式检查多个变量的真实性相互。
简单转换:(
那是……
-
0 === false 是 false。
-
!!0 === false 是 true。
上面的用处不大。 if (!0) 为您提供与 if (!!0 === false) 相同的结果。我想不出将变量转换为布尔值然后与“真”布尔值进行比较的好案例。
请参阅来自 JSLint's directions 的“== 和 !=”(注意:Crockford 正在稍微移动他的网站;该链接可能会在某个时候失效)以了解原因:
== 和 != 运算符在比较之前进行类型强制。这很糟糕,因为它会导致 ' \t\r\n' == 0 为真。这可以掩盖类型错误。 JSLint 无法可靠地确定 == 是否被正确使用,因此最好不要使用 == 和 !=,而始终使用更可靠的 === 和 !== 运算符。
如果您只关心一个值是真还是假,那么请使用简写形式。而不是
(foo != 0)
只是说
(foo)
而不是
(foo == 0)
说
(!foo)
请注意,在将布尔值与数字进行比较时,有一些 unintuitive cases 会将布尔值转换为数字(true 转换为 1 和 false 转换为 0)。在这种情况下,!! 可能对心理有用。不过,在这些情况下,您将非布尔值与硬类型布尔值进行比较,这在 imo 中是一个严重的错误。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());
由于some historical Windows jive,这将在消息框中输出-1!在 cmd.exe 提示符下试试看!但是WScript.echo(-1 == test()) 仍然给你0,或者WScript 的false。 Look away. It's hideous.
比较真实性:)
但是,如果我需要检查两个值是否相等,该怎么办?
假设我们有myVar1 = 0; 和myVar2 = undefined;。
-
myVar1 === myVar2 是 0 === undefined 显然是错误的。
-
!!myVar1 === !!myVar2 是 !!0 === !!undefined 并且是真的!一样的真实! (在这种情况下,两者都“具有虚假的真实性”。)
因此,您真正需要使用“布尔转换变量”的唯一地方是,您需要检查两个变量是否具有 相同 的真实性,对吗?也就是说,如果您需要查看两个变量是否都为真或都为假(或不),则使用!!,即相等(或不)真实性。
我想不出一个伟大的、非人为的用例来做这个副手。也许您在表单中有“链接”字段?
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 日编辑:
第三方库需要明确的布尔值
这是一个有趣的案例...!! 在 3rd 方库需要明确的布尔值时可能很有用。
反应
例如,False in JSX (React) has a special meaning 不会因简单的虚假而触发。如果您尝试在 JSX 中返回类似以下内容,则在 messageCount 中期待 int...
{messageCount && <div>You have messages!</div>}
...当您的消息为零时,您可能会惊讶地看到 React 呈现 0。您必须显式返回 false 才能使 JSX 不呈现。上面的语句返回 0,JSX 很高兴地呈现它,正如它应该的那样。它不能告诉你没有Count: {messageCount}。
-
一个修复涉及到 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 中的相同处理:如果您有一个返回布尔值的函数(或者您正在为布尔变量分配一个值),那么您 [通常] 不能返回/分配一个 boolean-y 值;它必须是强类型的布尔值。这意味着,如果 myObject 是强类型,return !myObject; 适用于返回布尔值的函数,但 return myObject; 不适用。您必须 return !!myObject(或以另一种方式转换为正确的布尔值)才能符合 Typescript 的期望。
Typescript 的例外?如果 myObject 是 any,那么您又回到了 JavaScript 的狂野西部,并且可以在没有 !! 的情况下返回它,即使您的返回类型是布尔值。
请记住,这些是 JSX 和 Typescript 约定,而不是 JavaScript 所固有的。
但是,如果您在渲染的 JSX 中看到奇怪的 0s,请考虑松散的虚假管理。