空数组似乎同时等于 true 和 false

新手上路,请多包涵

空数组为真,但它们也等于假。

 var arr = [];
console.log('Array:', arr);
if (arr) console.log("It's true!");
if (arr == false) console.log("It's false!");
if (arr && arr == false) console.log("...what??");

我猜这是由于相等运算符操作的隐式转换。

谁能解释一下幕后发生了什么?

原文由 Patonza 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 607
2 个回答

你在这里测试不同的东西。

if (arr) 在对象上调用(数组是JS中对象的实例)将检查对象是否存在,并返回真/假。

当您调用 if (arr == false) 时,您比较此对象的 和原语 false 值。在内部, arr.toString() 被调用,它返回一个空字符串 ""

这是因为 toString 调用 Array 返回 Array.join() ,而空字符串是 JavaScript 中的虚假值之一。

原文由 wildcard 发布,翻译遵循 CC BY-SA 3.0 许可协议

关于线路:

 if (arr == false) console.log("It's false!");

也许这些会有所帮助:

 console.log(0 == false) // true
console.log([] == 0) // true
console.log([] == "") // true

我认为正在发生的是布尔值 false 被强制转换为 0 用于与对象(左侧)进行比较。该对象被强制转换为字符串(空字符串)。然后,空字符串也被强制转换为数字,即零。所以最后的比较是 0 == 0 ,即 true

编辑: 请参阅 规范的这一部分, 了解有关其具体工作原理的详细信息。

这是正在发生的事情,从规则 #1 开始:

1. 如果 Type(x) 与 Type(y) 不同,转到第 14 步。

下一条适用的规则是#19:

19. 如果Type(y)为Boolean,则返回比较结果x == ToNumber(y)。

ToNumber(false) 的结果是 0 ,所以我们现在有:

 [] == 0

同样,规则 #1 告诉我们跳到步骤 #14,但实际适用的下一步是 #21:

21. 如果 Type(x) 是 Object 且 Type(y) 是 String 或 Number,则返回比较结果 ToPrimitive(x)== y。

ToPrimitive([]) 的结果是空字符串,所以我们现在有:

 "" == 0

同样,规则 #1 告诉我们跳到步骤 #14,但实际适用的下一步是 #17:

17、如果Type(x)是String,Type(y)是Number,返回比较结果ToNumber(x)== y。

ToNumber("") 的结果是 0 ,这给我们留下了:

 0 == 0

现在,这两个值具有相同的类型,因此步骤从 #1 继续到 #7,它表示:

7. 如果 x 与 y 的数值相同,则返回 true。

所以,我们返回 true

简单来说:

 ToNumber(ToPrimitive([])) == ToNumber(false)

原文由 Wayne 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题