谈话很便宜,我会展示我的代码。
var a; // a = undefined
if(a == false){ // As I typed == not ===, a needs to be translated to boolean (undefined == false) but it doesn't
return false;
}
else {
return true;
}
// true
这返回true但我确信它会返回false,因为当我使用double equal时,undefined与false相同。
当我尝试使用
时,事情变得奇怪了if(!a){..} else {..};
// false
在这里,我得到了我的错误,但直到这一刻,我认为(!a)和(a == false)完全相同。
答案 0 :(得分:6)
答案简短:
!a
将值转换为布尔值
a == false
将值与布尔值进行比较。
这是两种不同的操作。
!a
相当于Boolean(a) ? false : true
。如果Boolean(a)
false
会返回a
undefined
null
0
''
NaN
false
在其他所有情况下,它都会返回true
。
a == false
中发生的事情是bit more evolved,但并不复杂。最重要的是false
转换为数字,因此您实际上在比较a == 0
。但是undefined
在比较算法中以特殊方式处理。它没有转换为任何其他类型,因此算法只返回false
。
I wrote the following interactive tool用于JavaScript课程,该课程显示比较两个值时执行算法的哪些步骤:
类似的问题:
答案 1 :(得分:2)
唯一正确的答案是“就是这样”。混淆的来源是JavaScript的一个功能type coercion和不同类型的等式(JavaScript中的==
,===
)。
有一个有趣的表格可以告诉您JavaScript Equality Table上的true
会产生哪些比较。
true
与==
相比,null
只有null
的{{1}}和undefined
。
换句话说,当且仅当x == null
为true
或x
时,null
才会为undefined
。
答案 2 :(得分:1)
你有一个错误的假设。 x == false
未与x
同为boolean
。事实上,==
有own equality table。
如果你不相信随机博客,那么这里是spec:
7.2.12抽象平等比较
比较x == y,其中x和y是值,产生true或 假。这样的比较如下进行:
- ReturnIfAbrupt(X)。
- ReturnIfAbrupt(Y)。
- 如果Type(x)与Type(y)相同,则返回执行Strict Equality Comparison x === y的结果。
- 如果x为null且y未定义,则返回true。
- 如果x未定义且y为null,则返回true。
- 如果Type(x)为Number且Type(y)为String,则返回比较结果x == ToNumber(y)。
- 如果Type(x)为String且Type(y)为Number,则返回比较结果ToNumber(x)== y。
- 如果Type(x)是布尔值,则返回比较结果ToNumber(x)== y。
- 如果Type(y)是布尔值,则返回比较结果x == ToNumber(y)。
- 如果Type(x)是String,Number或Symbol而Type(y)是Object,则返回比较结果x == ToPrimitive(y)。
- 如果Type(x)是Object而Type(y)是String,Number或Symbol,则返回比较结果ToPrimitive(x)== y。
- 返回false。
醇>
因此对于undefined == false
:首先我们点击#9
,然后点击#12
,其评估为false。
答案 3 :(得分:1)
(!a)和(a == false)绝对等于。
你使用两个不同的运算符并假设它们绝对等于 - 从不这样做,有一个原因存在2个不同的运算符而不是1。
现在,想想NaN
(作为一个例子,其他人可能适用)。根据定义,NaN
是 falsy 值,但不是false
值,因此:
if(!NaN) {} // this will execute
if(NaN == false) {} // this will not execute
为什么你认为这会发生?
由于==
运算符确实为每个类型/值键入强制,因此NaN
不会强制转换为false
,而其他0
可能会强制true
,但两者都可以将被视为 falsy 并使用!
转换为!
总结:
false
使用一组已定义的 falsy 值(0
,''
,""
或null
(空字符串) ),undefined
,NaN
,==
)其他一切都是真理 func modifyGadgets(_ callback: @escaping ([Gadget]) -> ()) {
var gadgetsToModify = [Gadget]()
DispatchQueue.global(qos: .userInitiated).async {
for gadget in gadgetsToModify {
modifyThisGadget(gadget)
}
DispatchQueue.main.async {
callback(gadgetsToModify)
}
}
}
使用每种类型的转换,而不是将原始值视为 falsy ,因此在转换后,它可能 truthy