是什么意思啊!!运算符在 JavaScript 中做什么?
我看到了这段代码:
this.vertical = vertical !== undefined ? !!vertical : this.vertical;
它似乎使用 !!
作为操作符,我不认识。它有什么作用?
I saw this code:
this.vertical = vertical !== undefined ? !!vertical : this.vertical;
It seems to be using !!
as an operator, which I don't recognize. What does it do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
它将
Object
转换为boolean
。如果它是假的(例如,0
、null
、undefined
等),那么它将是false
,否则,true
。所以
!!
不是一个运算符;只是两次!
运算符。通常更简单:
现实世界示例“测试 IE 版本”:
如果您 ⇒
但如果您 ⇒
It converts
Object
toboolean
. If it was falsy (e.g.,0
,null
,undefined
, etc.), it would befalse
, otherwise,true
.So
!!
is not an operator; it's just the!
operator twice.It is generally simpler to do:
Real World Example "Test IE version":
If you ⇒
But if you ⇒
这是一种非常晦涩的类型转换方式。
!
表示NOT。所以!true
是false
,!false
是true
。!0
为true
,!1
为false
。因此,您要将一个值转换为布尔值,将其反转,然后再次反转。
注意:当涉及到某些边缘情况时(当
userId
为[]
,例如)由于!=
运算符的工作方式以及哪些值被视为真实。It's a horribly obscure way to do a type conversion.
!
means NOT. So!true
isfalse
, and!false
istrue
.!0
istrue
, and!1
isfalse
.So you're converting a value to a
Boolean
, inverting it, and then inverting it again.Note: the middle two expressions aren't exactly equivalent to the first expression when it comes to some edge cases (when
userId
is[]
, for example) due to the way the!=
operator works and what values are considered truthy.!!expr
(两个!
运算符后跟一个表达式)根据 表达式的真实性。当用于非布尔表达式时它是有意义的。一些示例:
注意:< code>Boolean 函数产生完全相同的结果,并且更具可读性。
!!expr
(two!
operators followed by an expression) returns the primitivetrue
orfalse
depending on the truthiness of the expression.It makes sense when used on non-boolean expressions. Some examples:
Note: the
Boolean
function produces the exact same results, and it is more readable.泡些茶:
!!
不是操作员。它是!
的双重使用——逻辑“非”运算符。理论上:
!
确定某个值不为“真”:事实是
假 不是
true
(这就是为什么!false
结果在
true
)事实是
true
不是false
(这就是为什么!true
结果在
假
)!!
确定值的“真实性”不 not:事实是
true
不是 nottrue
(这就是为什么!!true
结果在true
)事实是
false
不是不是false
(这就是为什么!!false
结果为false
)我们希望在比较中确定的是关于引用值的“真相”,而不是值参考本身。有一个用例,我们可能想知道某个值的真实情况,即使我们期望该值是
false
(或 falsey),或者如果我们期望该值不能是boolean
类型。实践:
考虑一个简洁的函数,通过动态类型(又名“鸭子类型”)。我们希望编写一个函数,如果用户的浏览器支持 HTML5
元素,则返回
true
,但我们不希望该函数在以下情况下抛出错误: code>以下是三种方法:
每个函数接受一个
参数和一个要查找的attribute
,但它们各自根据比较确定的内容返回不同的值。但是等等,还有更多!
你们中的一些人可能注意到,在这个特定的示例中,人们可以简单地使用稍微更高效的方法来检查相关对象是否具有属性。有两种方法可以做到这一点:
我们离题了...
无论这些情况多么罕见,都可能存在一些场景,其中最简洁、最高效,因此也是获得
的首选方法。 >true
来自非布尔值、可能未定义的值确实是通过使用!!
实现的。希望这可笑地澄清了这一点。Brew some tea:
!!
is not an operator. It is the double-use of!
-- which is the logical "not" operator.In theory:
!
determines the "truth" of what a value is not:The truth is that
false
is nottrue
(that's why!false
resultsin
true
)The truth is that
true
is notfalse
(that's why!true
resultsin
false
)!!
determines the "truth" of what a value is not not:The truth is that
true
is not nottrue
(that's why!!true
results intrue
)The truth is that
false
is not notfalse
(that's why!!false
results infalse
)What we wish to determine in the comparison is the "truth" about the value of a reference, not the value of the reference itself. There is a use-case where we might want to know the truth about a value, even if we expect the value to be
false
(or falsey), or if we expect the value not to be typeofboolean
.In practice:
Consider a concise function which detects feature functionality (and in this case, platform compatibility) by way of dynamic typing (aka "duck typing"). We want to write a function that returns
true
if a user's browser supports the HTML5<audio>
element, but we don't want the function to throw an error if<audio>
is undefined; and we don't want to usetry ... catch
to handle any possible errors (because they're gross); and also we don't want to use a check inside the function that won't consistently reveal the truth about the feature (for example,document.createElement('audio')
will still create an element called<audio>
even if HTML5<audio>
is not supported).Here are the three approaches:
Each function accepts an argument for a
<tag>
and anattribute
to look for, but they each return different values based on what the comparisons determine.But wait, there's more!
Some of you probably noticed that in this specific example, one could simply check for a property using the slightly more performant means of checking if the object in question has a property. There are two ways to do this:
We digress...
However rare these situations may be, there may exist a few scenarios where the most concise, most performant, and thus most preferred means of getting
true
from a non-boolean, possibly undefined value is indeed by using!!
. Hopefully this ridiculously clears it up.!!
将其右侧的值转换为其等效的布尔值。 (想想穷人的“类型转换”方式。)它的意图通常是向读者传达代码并不关心变量中的值是什么,但是它的“真相”值是什么。!!
converts the value to the right of it to its equivalent Boolean value. (Think poor man's way of "type-casting".) Its intent is usually to convey to the reader that the code does not care what value is in the variable, but what its "truth" value is.!!foo
应用一元 not 运算符两次,用于转换为布尔类型,类似于使用一元加+foo
进行转换转换为数字并连接空字符串''+foo
以转换为字符串。除了这些技巧之外,您还可以使用与原始类型相对应的构造函数(不使用
new
)来显式转换值,即!!foo
applies the unary not operator twice and is used to cast to a Boolean type similar to the use of unary plus+foo
to cast to a number and concatenating an empty string''+foo
to cast to a string.Instead of these hacks, you can also use the constructor functions corresponding to the primitive types (without using
new
) to explicitly cast values, i.e.,这么多答案,事半功倍。是的,
!!X
可以理解为“X 的真实性[表示为布尔值]”。但实际上,!!
对于确定单个变量(或者即使许多变量是)真值还是假值来说并不那么重要。!!myVar === true
与myVar
相同。将!!X
与“真正的”布尔值进行比较并不是很有用。使用
!!
获得的唯一好处是能够以可重复的、标准化的方式(以及 JSLint 友好)时尚。简单地转换:(
也就是说...
0 === false
是false
。!!0 === false
是true 上面的代码
不太有用。
if (!0)
给出的结果与if (!!0 === false)
相同。考虑将变量转换为布尔值然后与“true”布尔值进行比较的好例子,请参阅 JSLint 的说明(注意:网站已更改;这是存档副本)了解原因:
请注意,在一些不直观的情况中,布尔值将被转换为将布尔值与数字进行比较时,数字(
true
转换为1
,false
转换为0
)。在这种情况下,!!
可能在心理上有用。不过,在这些情况下,您将非布尔值与硬类型布尔值进行比较,在我看来,这是一个严重的错误。if (-1)< /code> 仍然是这里的方法。
if (-1 == true) console.log("spam" )
if (-1 == 1)
if (-1 == false) console.log("spam")
if (-1 == 0)
if (true == -1) console.log("spam")
if (1 == -1)
...
if (!!-1 == true) console.log("spam")
if (true == true)
if (-1) console .log("spam")
if (truthy)
并且根据您的引擎,事情会变得更加疯狂。例如,WScript 赢得了奖项。
由于一些历史Windows jive,它将在消息框中输出-1!在 cmd.exe 提示符下尝试一下,看看吧!但是
WScript.echo(-1 == test())
仍然给你 0,或者 WScript 的false
。 别看别处。这太可怕了。比较真实性:)
但是如果我有两个值需要检查是否相等真实性/虚假性怎么办?
假设我们有
myVar1 = 0;
和myVar2 = undefined;
。myVar1 === myVar2
是0 === undefined
并且显然是错误的。!!myVar1 === !!myVar2
是!!0 === !!undefined
并且是真的!同样的真实! (在这种情况下,两者都“具有虚假的真实性”。)因此,您真正需要使用“布尔转换变量”的唯一地方是,如果您要检查两个变量是否都具有 < em>同样的真实性,对吗?也就是说,如果您需要查看两个变量是都是真值还是都是假(或不是),即相等,则使用
!!
(或不是)真实性。我想不出一个很好的、非人为的用例来实现这一点。也许您的表单中有“链接”字段?
因此,现在如果您的配偶姓名和年龄都为真,或者都为假,您就可以继续。否则,您只有一个具有值的字段(或很早的包办婚姻),并且需要在您的
errorObjects
集合上创建一个额外的错误。尽管即使在这种情况下,
!!
确实是多余的。一个!
足以转换为布尔值,而您只需检查相等性。编辑 2017 年 10 月 24 日,2 月 6 日:
需要显式布尔值的第三方库
这是一个有趣的案例...当第三方库需要显式布尔值时
!!
可能会很有用显式布尔值。React
例如,False 在 JSX (React) 中具有特殊含义< /a> 这不是因为简单的错误而触发的。如果您尝试在 JSX 中返回类似以下内容,并且期望
messageCount
中包含 int...{messageCount &&
}
...当你有零条消息时,你可能会惊讶地看到 React 渲染
0
。您必须显式返回 false 才能使 JSX 不呈现。上面的语句返回0
,JSX 愉快地渲染它,正如它应该的那样。它无法告诉您没有计数:{messageCount}
。一个修复涉及 bangbang,它将
0
强制转换为!!0
,即false
:{!!messageCount &&
您有消息!
}
JSX 文档建议您更加明确,编写自我注释代码,并使用比较来强制为布尔值。
<代码>{消息计数> 0 &&
}
我自己用三元来处理虚假会更自如 --
<代码>{消息计数?
:假}
TypeScript
TypeScript 中的相同处理:如果您有一个返回布尔值的函数(或者您正在为布尔变量赋值),那么您[通常]无法返回/分配布尔值 - y 值;它必须是强类型布尔值。这意味着,iff
myObject
是强类型的,return !myObject;
适用于返回布尔值的函数,但return myObject;< /code> 没有。您必须
返回!!myObject
(或以另一种方式转换为正确的布尔值)才能满足 TypeScript 的期望。请记住,这些是 JSX 和 TypeScript 约定,而不是 JavaScript 固有的。
但是,如果您在渲染的 JSX 中看到奇怪的
0
,请考虑松散的虚假管理。So many answers doing half the work. Yes,
!!X
could be read as "the truthiness of X [represented as a Boolean]". But!!
isn't, practically speaking, so important for figuring out whether a single variable is (or even if many variables are) truthy or falsy.!!myVar === true
is the same as justmyVar
. Comparing!!X
to a "real" Boolean isn't really useful.The only thing you gain with
!!
is the ability to check the truthiness of multiple variables against each other in a repeatable, standardized (and JSLint friendly) fashion.Simply casting :(
That is...
0 === false
isfalse
.!!0 === false
istrue
.The above's not so useful.
if (!0)
gives you the same results asif (!!0 === false)
. I can't think of a good case for casting a variable to Boolean and then comparing to a "true" Boolean.See "== and !=" from JSLint's directions (note: site has changed; this is an archived copy) for a little on why:
Note that there are some unintuitive cases where a Boolean will be cast to a number (
true
is cast to1
andfalse
to0
) when comparing a Boolean to a number. In this case,!!
might be mentally useful. Though, again, these are cases where you're comparing a non-Boolean to a hard-typed Boolean, which is, in my opinion, a serious mistake.if (-1)
is still the way to go here.if (-1 == true) console.log("spam")
if (-1 == 1)
if (-1 == false) console.log("spam")
if (-1 == 0)
if (true == -1) console.log("spam")
if (1 == -1)
matter...
if (!!-1 == true) console.log("spam")
if (true == true)
if (-1) console.log("spam")
if (truthy)
And things get even crazier depending on your engine. WScript, for instance, wins the prize.
Because of some historical Windows jive, that'll output -1 in a message box! Try it in a cmd.exe prompt and see! But
WScript.echo(-1 == test())
still gives you 0, or WScript'sfalse
. Look away. It's hideous.Comparing truthiness :)
But what if I have two values I need to check for equal truthiness/falsiness?
Pretend we have
myVar1 = 0;
andmyVar2 = undefined;
.myVar1 === myVar2
is0 === undefined
and is obviously false.!!myVar1 === !!myVar2
is!!0 === !!undefined
and is true! Same truthiness! (In this case, both "have a truthiness of falsy".)So the only place you'd really need to use "Boolean-cast variables" would be if you had a situation where you're checking if both variables have the same truthiness, right? That is, use
!!
if you need to see if two variables are both truthy or both falsy (or not), that is, of equal (or not) truthiness.I can't think of a great, non-contrived use case for that offhand. Maybe you have "linked" fields in a form?
So now if you have a truthy for both or a falsy for both spouse name and age, you can continue. Otherwise you've only got one field with a value (or a very early arranged marriage) and need to create an extra error on your
errorObjects
collection.Though even in this case, the
!!
really is superfluous. One!
was enough to cast to a Boolean, and you're just checking equality.EDIT 24 Oct 2017, 6 Feb 19:
Third-party libraries that expect explicit Boolean values
Here's an interesting case...
!!
might be useful when third-party libraries expect explicit Boolean values.React
For instance, False in JSX (React) has a special meaning that's not triggered on simple falsiness. If you tried returning something like the following in your JSX, expecting an int in
messageCount
...{messageCount && <div>You have messages!</div>}
... you might be surprised to see React render a
0
when you have zero messages. You have to explicitly return false for JSX not to render. The above statement returns0
, which JSX happily renders, as it should. It can't tell you didn't haveCount: {messageCount}
.One fix involves the bangbang, which coerces
0
into!!0
, which isfalse
:{!!messageCount && <div>You have messages!</div>}
JSX' documentation suggests you be more explicit, write self-commenting code, and use a comparison to force to a Boolean.
{messageCount > 0 && <div>You have messages!</div>}
I'm more comfortable handling falsiness myself with a ternary --
{messageCount ? <div>You have messages!</div> : false}
TypeScript
The same deal in TypeScript: If you have a function that returns a Boolean (or you're assigning a value to a Boolean variable), you [usually] can't return/assign a boolean-y value; it has to be a strongly typed boolean. This means, iff
myObject
is strongly typed,return !myObject;
works for a function returning a Boolean, butreturn myObject;
doesn't. You have toreturn !!myObject
(or cast to the proper Boolean another way) to match TypeScript's expectations.Keep in mind that these are JSX and TypeScript conventions, not ones inherent to JavaScript.
But if you see strange
0
s in your rendered JSX, think loose falsy management.这只是逻辑 NOT 运算符,两次。它用于将某些内容转换为布尔值,例如:
It's just the logical NOT operator, twice. It's used to convert something to Boolean, e.g.:
它将后缀转换为布尔值。
It converts the suffix to a Boolean value.
看来
!!
运算符会导致双重否定。It seems that the
!!
operator results in a double negation.它模拟
Boolean()
转换函数的行为。第一个
NOT
返回一个布尔值,无论给出什么操作数。第二个NOT
否定该Boolean
值,从而给出变量的true
布尔值。最终结果与对值使用Boolean()
函数相同。It simulates the behavior of the
Boolean()
casting function.The first
NOT
returns a Boolean value no matter what operand it is given. The secondNOT
negates thatBoolean
value and so gives thetrue
Boolean value of a variable. The end result is the same as using theBoolean()
function on a value.这是一个双重
not
操作。第一个!
将值转换为布尔值并反转其逻辑值。第二个!
将逻辑值反转。It's a double
not
operation. The first!
converts the value to Boolean and inverts its logical value. The second!
inverts the logical value back.!!
一起使用了NOT
操作两次。!
将值转换为布尔值并反转它,因此使用它两次,显示该值的布尔值(假或真)。这是一个简单的例子来看看!!
是如何工作的:首先,你所拥有的地方:
然后你做
!0
。它将被转换为布尔值并被评估为true
,因为 0 是falsy
,所以你得到相反的值并转换为布尔值,因此它被评估为正确。
但我们不想要该值的反转布尔版本,因此我们可以再次反转它以获得我们的结果!这就是我们使用另一个
!
的原因。基本上,
!!
让我们确保我们得到的值是布尔值,而不是假值、真值、字符串等......所以这就像在 JavaScript 中使用 Boolean 函数,但是将值转换为布尔值的更简单、更短的方法:
!!
is using theNOT
operation twice together.!
converts the value to a Boolean and reverses it, so using it twice, showing the Boolean (false or true) of that value. Here is a simple example to see how!!
works:At first, the place you have:
Then you do
!0
. It will be converted to Boolean and be evaluated totrue
, because 0 isfalsy
, so you get the reversed value and converted to Boolean, so it gets evaluated totrue
.But we don't want the reversed Boolean version of the value, so we can reverse it again to get our result! That's why we use another
!
.Basically,
!!
makes us sure the value we get is Boolean, not falsy, truthy, string, etc...So it's like using the Boolean function in JavaScript, but an easier and shorter way to convert a value to Boolean:
!是“布尔非”,它本质上将“enable”的值类型转换为其相反的布尔值。第二个!翻转该值。因此,
!!enable
表示“不启用”,为您提供布尔值形式的enable
值。! is "Boolean not", which essentially typecasts the value of "enable" to its boolean opposite. The second ! flips this value. So,
!!enable
means "not not enable," giving you the value ofenable
as a Boolean.我认为值得一提的是,与逻辑 AND/OR 组合的条件不会返回布尔值,但在
&&
情况下最后一次成功或第一次失败以及在条件链的||
的情况。为了将条件转换为真正的布尔文字,我们可以使用双重否定:
I think worth mentioning is that a condition combined with logical AND/OR will not return a Boolean value, but the last success or first fail in case of
&&
and the first success or last fail in case of||
of the condition chain.In order to cast the condition to a true Boolean literal we can use the double negation:
!!
构造是将任何 JavaScript 表达式转换为它的布尔等价物。
例如:
!!“他击落了我”=== true
和!!0 === false
。The
!!
construct is a simple way of turning any JavaScript expression intoits Boolean equivalent.
For example:
!!"he shot me down" === true
and!!0 === false
.这不是一个单独的操作员;而是一个操作员。是两个。它相当于以下内容,是将值转换为布尔值的快速方法。
It's not a single operator; it's two. It's equivalent to the following and is a quick way to cast a value to Boolean.
它强制所有东西都为布尔值。
例如:
It forces all things to Boolean.
For example:
我怀疑这是 C++ 的遗留问题,人们重写
!
运算符,但不重写 bool 运算符。因此,要在这种情况下获得否定(或肯定)答案,您首先需要使用
!
运算符来获取布尔值,但如果您想检查肯定情况,您将使用!!
。I suspect this is a leftover from C++ where people override the
!
operator, but not the bool operator.So to get a negative (or positive) answer in that case, you would first need to use the
!
operator to get a Boolean, but if you wanted to check the positive case you would use!!
.if
和while
语句以及?
运算符使用真值来确定要运行哪个代码分支。例如,零和 NaN 数字以及空字符串为 false,但其他数字和字符串为 true。对象为 true,但未定义值和null
均为 false。双重否定运算符
!!
计算某个值的真值。它实际上是两个运算符,其中!!x
表示!(!x)
,其行为如下:x
是 false 值,则 < code>!x 为true
,!!x
为false
。x
为 true 值,则!x
为false
,!!x
为true< /代码>。
当在布尔上下文的顶层使用时(
if
、while
或?
),!!
操作符在行为上是无操作的。例如,if (x)
和if (!!x)
表示相同的意思。实际用途
然而它有几个实际用途。
一种用途是将对象有损地压缩为其真值,这样您的代码就不会保留对大对象的引用并保持其活动状态。将
!!some_big_object
分配给变量而不是some_big_object
可以让垃圾收集器将其释放。这对于产生对象或错误值(例如null
)或未定义值(例如浏览器功能检测)的情况非常有用。我在关于 C 相应
!!
运算符的答案中提到的另一种用法是“ lint”工具,用于查找常见拼写错误并打印诊断信息。例如,在 C 和 JavaScript 中,布尔运算的一些常见拼写错误会产生其他行为,其输出并不完全是布尔值:if (a = b)
是赋值,然后使用真值b
;if (a == b)
是相等比较。if (a & b)
是按位与;if (a && b)
是逻辑 AND。 <代码>2 & 5 是0
(假值); <代码>2 && 5 是正确的。!!
运算符向 lint 工具保证您所写的就是您的意思:执行此操作,然后获取结果的真值。第三种用途是产生逻辑 XOR 和逻辑 XNOR。在 C 和 JavaScript 中,
a && b
执行逻辑 AND(如果两边都为 true,则为 true),而a & b
执行按位与。一个 || b
执行逻辑或(如果至少有一个为 true,则为 true),并且a | b
执行按位或。有一个按位 XOR(异或),如a ^ b
,但没有用于逻辑 XOR 的内置运算符(如果恰好一侧为 true,则为 true)。例如,您可能希望允许用户在两个字段之一中输入文本。您可以做的是将每个值转换为真值并进行比较:!!x !== !!y
。The
if
andwhile
statements and the?
operator use truth values to determine which branch of code to run. For example, zero and NaN numbers and the empty string are false, but other numbers and strings are true. Objects are true, but the undefined value andnull
are both false.The double negation operator
!!
calculates the truth value of a value. It's actually two operators, where!!x
means!(!x)
, and behaves as follows:x
is a false value,!x
istrue
, and!!x
isfalse
.x
is a true value,!x
isfalse
, and!!x
istrue
.When used at the top level of a Boolean context (
if
,while
, or?
), the!!
operator is behaviorally a no-op. For example,if (x)
andif (!!x)
mean the same thing.Practical uses
However it has several practical uses.
One use is to lossily compress an object to its truth value, so that your code isn't holding a reference to a big object and keeping it alive. Assigning
!!some_big_object
to a variable instead ofsome_big_object
lets go of it for the garbage collector. This is useful for cases that produce either an object or a false value such asnull
or the undefined value, such as browser feature detection.Another use, which I mentioned in an answer about C's corresponding
!!
operator, is with "lint" tools that look for common typos and print diagnostics. For example, in both C and JavaScript, a few common typos for Boolean operations produce other behaviors whose output isn't quite as Boolean:if (a = b)
is assignment followed by use of the truth value ofb
;if (a == b)
is an equality comparison.if (a & b)
is a bitwise AND;if (a && b)
is a logical AND.2 & 5
is0
(a false value);2 && 5
is true.The
!!
operator reassures the lint tool that what you wrote is what you meant: do this operation, then take the truth value of the result.A third use is to produce logical XOR and logical XNOR. In both C and JavaScript,
a && b
performs a logical AND (true if both sides are true), anda & b
performs a bitwise AND.a || b
performs a logical OR (true if at least one are true), anda | b
performs a bitwise OR. There's a bitwise XOR (exclusive OR) asa ^ b
, but there's no built-in operator for logical XOR (true if exactly one side is true). You might, for example, want to allow the user to enter text in exactly one of two fields. What you can do is convert each to a truth value and compare them:!!x !== !!y
.这个问题已经得到了相当彻底的回答,但我想添加一个答案,我希望尽可能简化,使含义!!尽可能简单易懂。
因为 JavaScript 具有所谓的“true”和“falsy”值,所以有些表达式在其他表达式中计算时将导致 true 或 false 条件,即使正在检查的值或表达式实际上不是 true代码> 或<代码>假。
例如:
如果该元素确实存在,则表达式将计算为 true,并且将执行代码块。
但是:
...将不会导致条件为真,并且即使该元素确实存在,代码块也不会被执行。
为什么?因为
document.getElementById()
是一个“真实”表达式,在此if()
语句中计算结果为 true,但它不是的实际布尔值正确。
在这种情况下,双“不”非常简单。这只是背靠背的两个
不
。第一个只是“反转”真值或假值,产生实际的布尔类型,然后第二个将其再次“反转”回其原始状态,但现在是实际的布尔值。这样你就具有一致性:
并且
将两者返回true,如预期的那样。
This question has been answered quite thoroughly, but I'd like to add an answer that I hope is as simplified as possible, making the meaning of !! as simple to grasp as can be.
Because JavaScript has what are called "truthy" and "falsy" values, there are expressions that when evaluated in other expressions will result in a true or false condition, even though the value or expression being examined is not actually
true
orfalse
.For instance:
If that element does in fact exist, the expression will evaluate as true, and the code block will be executed.
However:
...will not result in a true condition, and the code block will not be executed, even if the element does exist.
Why? Because
document.getElementById()
is a "truthy" expression that will evaluate as true in thisif()
statement, but it is not an actual Boolean value oftrue
.The double "not" in this case is quite simple. It is simply two
not
s back to back.The first one simply "inverts" the truthy or falsy value, resulting in an actual Boolean type, and then the second one "inverts" it back again to its original state, but now in an actual Boolean value. That way you have consistency:
and
will both return true, as expected.
我只是想补充一点,这
与
但是当某些内容未定义时这可能是一个问题。
这里的技巧是
&&
链将返回它找到的第一个错误值 - 并且可以将其提供给 if 语句等。因此,如果 b .foo 未定义,它将返回 undefined 并跳过 b.foo.bar 语句,并且我们不会收到错误。上面的返回未定义,但如果你有一个空字符串、false、null、0、未定义,这些值将返回,当我们在链中遇到它们时 -
[]
和{}< /code> 都是“真实的”,我们将继续沿着所谓的“&&链”向下到达右侧的下一个值。
PS 执行上述操作的另一种方法 (
b && b.foo
) 是(b || {}).foo
。这些是等效的,因为如果 b 未定义,则b || {}
将是{}
,您将访问空对象中的值(无错误),而不是尝试访问“undefined”中的值(导致错误) 。因此,
(b || {}).foo
与b && 相同。 b.foo
和((b || {}).foo || {}).bar
与b && 相同b.foo && b.foo.bar
。I just wanted to add that
is the same as
But this can be an issue when something is undefined.
The trick here is the chain of
&&
s will return the first falsey value it finds -- and this can be fed to an if statement etc. So if b.foo is undefined, it will return undefined and skip theb.foo.bar
statement, and we get no error.The above return undefined but if you have an empty string, false, null, 0, undefined those values will return and soon as we encounter them in the chain --
[]
and{}
are both "truthy" and we will continue down the so-called "&& chain" to the next value to the right.P.S. Another way of doing the above (
b && b.foo
) is(b || {}).foo
. Those are equivalent, because if b is undefined thenb || {}
will be{}
, and you'll be accessing a value in an empty object (no error) instead of trying to access a value within "undefined" (causes an error).So,
(b || {}).foo
is the same asb && b.foo
and((b || {}).foo || {}).bar
is the same asb && b.foo && b.foo.bar
.它是双重布尔否定。它通常用于检查值是否未定义。
It is double Boolean negation. It is often used to check if a value is not undefined.
这里有很多很好的答案,但如果你已经读到这里,这会帮助我“明白”。在 Chrome(等)中打开控制台,然后开始输入:
当然,这些都与仅输入 !!someThing 相同,但添加的括号可能有助于使其更容易理解。
There are tons of great answers here, but if you've read down this far, this helped me to 'get it'. Open the console in Chrome (etc.), and start typing:
Naturally, these are all the same as merely typing !!someThing, but the added parentheses might help make it more understandable.
!!x
是Boolean(x)
的简写。第一个爆炸强制 JavaScript 引擎运行
Boolean(x)
,但它也有反转值的副作用。所以第二次爆炸消除了副作用。!!x
is shorthand forBoolean(x)
.The first bang forces the JavaScript engine to run
Boolean(x)
, but it also has the side effect of inverting the value. So the second bang undoes the side effect.看到所有这些精彩的答案后,我想添加使用
!!
的另一个原因。目前我正在使用 Angular 2-4 (TypeScript),当我的用户未经过身份验证时,我想返回一个布尔值false
。如果他未通过身份验证,则令牌字符串将为null
或""
。我可以使用下一个代码块来做到这一点:After seeing all these great answers, I would like to add another reason for using
!!
. Currently I'm working in Angular 2-4 (TypeScript) and I want to return a Boolean asfalse
when my user is not authenticated. If he isn't authenticated, the token-string would benull
or""
. I can do this by using the next block of code:请务必记住 JavaScript 中对
true
和false
的评估:所有具有“值”的内容都是
true< /code>(即truthy),例如:
101
,3.1415
,“幸运大脑”
,new Object()
true
一切都没有“Value”为
false
(即falsy),例如:0
,""
(空字符串),未定义
,空
,NaN
(不是数字)假
应用“逻辑非”运算符 (
!
) 计算操作数,将其转换为boolean
,然后对其求反。应用两次将会对负数取反,从而有效地将值转换为布尔值。不应用运算符将只是精确值的常规分配。示例:value2 = value;
分配精确的对象value
,即使它不是boolean
,因此value2
不会最终必然是布尔值。value2 = !!value;
分配一个有保证的boolean
作为操作数value
双重否定的结果,它等价于以下但更短且可读:It is important to remember the evaluations to
true
andfalse
in JavaScript:Everything with a "Value" is
true
(namely truthy), for example:101
,3.1415
,-11
,"Lucky Brain"
,new Object()
true
Everything without a "Value" is
false
(namely falsy), for example:0
,-0
,""
(empty string),undefined
,null
,NaN
(not a number)false
Applying the "logical not" operator (
!
) evaluates the operand, converting it toboolean
and then negating it. Applying it twice will negate the negation, effectively converting the value toboolean
. Not applying the operator will just be a regular assignment of the exact value. Examples:value2 = value;
assigns the exact objectvalue
even if it is notboolean
hencevalue2
won't necessarily end up beingboolean
.value2 = !!value;
assigns a guaranteedboolean
as the result of the double negation of the operandvalue
and it is equivalent to the following but much shorter and readable:这是来自 AngularJS 的一段代码:
他们的目的是根据 requestAnimationFrame 中函数的可用性将 rafSupported 设置为 true 或 false。
一般来说,可以通过以下方式检查来实现:
简短的方法可以使用
!!
因此,如果 requestAnimationFrame 被分配了一个函数,那么 !requestAnimationFrame 将为 false,并且还有一个
! 是真的。
如果 requestAnimationFrame 未定义,则 !requestAnimationFrame 将为 true,而其中的一个
!
将为 false。Here is a piece of code from AngularJS:
Their intention is to set rafSupported to true or false based on the availability of function in requestAnimationFrame.
It can be achieved by checking in the following way in general:
The short way could be using
!!
So if requestAnimationFrame was assigned a function then !requestAnimationFrame would be false and one more
!
of it would be true.If requestAnimationFrame was assigned undefined then !requestAnimationFrame would be true and one more
!
of it would be false.使用逻辑非运算符两次。
这意味着
!true = false
和!!true = true
。Use the logical not operator two times.
It means
!true = false
and!!true = true
.它返回变量的布尔值。
相反,可以使用
Boolean
类。(请阅读代码说明。)
即使用
Boolean(X) = !!X
。请检查下面的代码片段↓
It returns the Boolean value of a variable.
Instead, the
Boolean
class can be used.(Please read the code descriptions.)
Namely,
Boolean(X) = !!X
in use.Please check code snippet out below ↓