我看到一些代码似乎使用了我不认识的运算符,以两个感叹号的形式,像这样:!!。有人能告诉我这个接线员做什么吗?
我看到这件事的背景是,
this.vertical = vertical !== undefined ? !!vertical : this.vertical;
我看到一些代码似乎使用了我不认识的运算符,以两个感叹号的形式,像这样:!!。有人能告诉我这个接线员做什么吗?
我看到这件事的背景是,
this.vertical = vertical !== undefined ? !!vertical : this.vertical;
当前回答
它将所有的东西都强制为布尔值。
例如:
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); // -> false
console.log(!0 === false); // -> false
console.log(!!0 === false); // -> true
其他回答
这么多答案做了一半的工作。对X可以理解为“X的真实性[表示为布尔值]”。但是实际上,对于弄清楚一个变量是真是假(或者即使很多变量都是真的)来说,不是那么重要!!myVar==true与myVar相同。比较!!将X转换为“真实”布尔值并不是很有用。
你唯一的收获!!是以可重复、标准化(和JSLint友好)的方式检查多个变量之间的真实性的能力。
简单铸造:(
那就是。。。
0===false为false。!!0===假为真。
上面的没有那么有用。if(!0)给出的结果与if(!!0===false)相同。我想不出将变量转换为布尔值,然后与“真”布尔值进行比较的好例子。
请参阅JSLint的指示中的“==and!=”(注意:Crockford正在移动他的站点;该链接可能会在某一点上失效),了解原因:
==和!=运算符在比较之前执行类型强制。这很糟糕,因为它导致'\t\t'==0为真。这会掩盖类型错误。JSLint无法可靠地确定==是否正确使用,因此最好不要使用==和!=并始终使用更可靠的==和!==运算符。如果你只关心一个值是真的还是假的,那么就使用简短的形式(foo!=0)说吧(foo)而不是(foo==0)说(!foo)
注意,在将布尔值与数字进行比较时,有一些不直观的情况,布尔值将被转换为数字(true被转换为1,false被转换为0)。在这种情况下!!可能在精神上有用。不过,在这些情况下,您将非布尔值与硬类型布尔值进行比较,在我看来,这是一个严重的错误。如果(-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 jive,它将在消息框中输出-1!在cmd.exe提示符下尝试,然后查看!但是WScript.echo(-1==test())仍然为0,或者WScript为false。移开视线。这太可怕了。
比较真实性:)
但是,如果我有两个值需要检查是否相等的真/假呢?
假设我们有myVar1=0;并且myVar2=undefined;。
myVar1==myVar2为0==未定义,显然为假。!!myVar1==!!myVar2是!!0 === !!未定义且为真!同样的道理!(在这种情况下,两者都“具有虚假的真实性”。)
所以,你真正需要使用“布尔转换变量”的唯一地方是,如果你在检查两个变量是否具有相同的真实性,对吗?那就是,使用!!如果您需要查看两个变量是否都是真的或都是假的,也就是说,是否具有相等的真实性。
我想不出一个很棒的、不做作的用例。也许您在表单中“链接”了字段?
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日,2月19日:
期望显式布尔值的第三方库
这是一个有趣的案例!!当第三方库需要显式布尔值时,可能很有用。
反应
例如,JSX(React)中的False有一个特殊的含义,它不会在简单的错误中触发。如果您尝试在JSX中返回以下内容,则messageCount中应为int。。。
{messageCount&&<div>您有消息!</div>}
…当您没有消息时,您可能会惊讶地看到React呈现0。您必须显式返回false,以便JSX不呈现。上面的语句返回0,JSX很高兴地将其呈现出来。它不能告诉你没有计数:{messageCount}。
一个修复方法涉及bangbang,它将0强制为!!0,这是错误的:{!!messageCount&&<div>您有消息!</div>}JSX的文档建议您更加明确,编写自我注释代码,并使用比较强制转换为布尔值。{messageCount>0&&<div>您有消息!</div>}我自己用三元表处理错误更舒服--{messageCount?<div>您有消息!</div>:false}
TypeScript(类型脚本)
TypeScript中的相同处理:如果你有一个返回布尔值的函数(或者你正在给布尔变量赋值),你(通常)不能返回/赋值布尔值;它必须是强类型布尔值。这意味着,iff myObject是强类型的,返回!myObject;适用于返回布尔值的函数,但返回myObject;不。你必须回来!!myObject(或以另一种方式转换为正确的布尔值)以匹配TypeScript的期望。
TypeScript的例外?如果myObject是any,那么您将返回JavaScript的Wild West,并且可以不使用!!,即使您的返回类型是布尔值。
请记住,这些是JSX和TypeScript约定,而不是JavaScript固有的约定。
但如果您在渲染的JSX中看到奇怪的0,请考虑松散的错误管理。
它不是一个操作员;它是两个。它相当于以下内容,是将值转换为布尔值的快速方法。
val.enabled = !(!enable);
记住JavaScript中对true和false的求值很重要:
具有“价值”的一切都是真实的(即真实的),例如:101,3.1415,-11,“幸运的大脑”,新建对象()当然,这是真的没有“Value”的所有内容都是假的(即falsy),例如:0,-0,“”(空字符串),未定义,无效的NaN(不是数字)当然,也是假的
应用“逻辑非”运算符(!)计算操作数,将其转换为布尔值,然后对其求反。应用两次将对求反进行求反,从而有效地将值转换为布尔。不应用运算符将只是精确值的常规赋值。示例:
var value = 23; // number
var valueAsNegatedBoolean = !value; // boolean falsy (because 23 is truthy)
var valueAsBoolean = !!value; // boolean truthy
var copyOfValue = value; // number 23
var value2 = 0;
var value2AsNegatedBoolean = !value2; // boolean truthy (because 0 is falsy)
var value2AsBoolean = !!value2; // boolean falsy
var copyOfValue2 = value2; // number 0
value2=值;指定精确的对象值,即使它不是布尔值,因此value2不一定最终是布尔值。value2=!!价值作为操作数值的双重否定的结果,指定一个保证布尔值,它相当于以下内容,但要短得多,可读性强:
if(值){value2=真;}其他{value2=false;}
JavaScript中的一些运算符执行隐式类型转换,有时用于类型转换。
一元!运算符将其操作数转换为布尔值并对其求反。
这一事实导致了以下习惯用法,您可以在源代码中看到:
!!x // Same as Boolean(x). Note double exclamation mark
只是为了检查是否存在
if(!!isComplianceOnHold){
//write code here is not undefined
//if isComplianceOnHold is undefined or null will not enter in net is false
// if isComplianceOnHold is not null or even boolean net result is true and enter inside if block
}
任何值未定义或为null的对象,包括值为false的布尔对象,在传递给条件语句时其计算结果为true