为什么(!a)和(a == false)不相等?

时间:2017-09-15 16:26:33

标签: javascript

谈话很便宜,我会展示我的代码。

    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)完全相同。

4 个答案:

答案 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课程,该课程显示比较两个值时执行算法的哪些步骤:

enter image description here

类似的问题:

答案 1 :(得分:2)

唯一正确的答案是“就是这样”。混淆的来源是JavaScript的一个功能type coercion和不同类型的等式(JavaScript中的=====)。

有一个有趣的表格可以告诉您JavaScript Equality Table上的true会产生哪些比较。

true==相比,null只有null的{​​{1}}和undefined

换句话说,当且仅当x == nulltruex时,null才会为undefined

答案 2 :(得分:1)

你有一个错误的假设。 x == false未与x同为boolean。事实上,==own equality table

如果你不相信随机博客,那么这里是spec

  

7.2.12抽象平等比较

     

比较x == y,其中x和y是值,产生true或   假。这样的比较如下进行:

     
      
  1. ReturnIfAbrupt(X)。
  2.   
  3. ReturnIfAbrupt(Y)。
  4.   
  5. 如果Type(x)与Type(y)相同,则返回执行Strict Equality Comparison x === y的结果。
  6.   
  7. 如果x为null且y未定义,则返回true。
  8.   
  9. 如果x未定义且y为null,则返回true。
  10.   
  11. 如果Type(x)为Number且Type(y)为String,则返回比较结果x == ToNumber(y)。
  12.   
  13. 如果Type(x)为String且Type(y)为Number,则返回比较结果ToNumber(x)== y。
  14.   
  15. 如果Type(x)是布尔值,则返回比较结果ToNumber(x)== y。
  16.   
  17. 如果Type(y)是布尔值,则返回比较结果x == ToNumber(y)。
  18.   
  19. 如果Type(x)是String,Number或Symbol而Type(y)是Object,则返回比较结果x == ToPrimitive(y)。
  20.   
  21. 如果Type(x)是Object而Type(y)是String,Number或Symbol,则返回比较结果ToPrimitive(x)== y。
  22.   
  23. 返回false。
  24.   

因此对于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(空字符串) ),undefinedNaN==)其他一切都是真理
  • 运算符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