当[] == false时,类型强制如何发生?

时间:2016-02-16 13:11:59

标签: javascript

ECMA脚本documentation 抽象平等比较算法 中说明,

  

如果Type(y)是布尔值,则返回比较结果x ==   ToNumber(Y)。

例如,[] == false将被强迫,

1.   [] == Number(false)
2.   [] == 0 //comparison happens here.

我的问题是,强制将以递归方式发生,直到两个操作数变得原始或不是?强制如何发生在这里?

我认为强制将重复进行,直到将两个操作数转换为原语,如下面的

1.   [] == Number(false)
2.   [] == 0
3.   ToPrimitive([]) == 0
4.   0 == 0 
5.   true

我的推定是真的吗?如果没有,谁能解释这里有什么问题?另外,如何在任何浏览器的控制台中验证ToPrimitive([])的结果是否为0?

2 个答案:

答案 0 :(得分:5)

请参阅spec[] == false可以解析为以下表格

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

以下是更多详情

  

如果Type(y)是布尔值,则返回比较结果x == ToNumber(y)

[] == ToNumber(false)
  

如果Type(x)是Object而Type(y)是String,Number或Symbol,则返回比较结果ToPrimitive(x)== y

ToPrimitive([]) == 0

根据ToPrimitive算法,首先调用valueOf。但是因为它返回一个对象,而不是一个原始值,其次会调用toString,返回一个字符串'',空字符串

  

如果Type(x)是String而Type(y)是Number,则返回比较结果ToNumber(x)== y

ToNumber('') == 0

然后ToNumber到0.比较ToNumber(false)也是0.结果,它们是相同的。

答案 1 :(得分:4)

规范说

  

如果Type(y)是布尔值,则返回比较结果x == ToNumber(y)。

所以是的,这意味着Abstract Equality Comparison将被递归调用,直到它返回true或false,或者直到抛出错误为止。其中一个最终会发生,所以保证递归完成。

一步一步,它的

[] == false;
[] == +0; // ToNumber(false)
"" == +0; // ToPrimitive([])
+0 == +0; // ToNumber("")
true;

请注意,如果两个操作数都是基元,则递归不会结束。例如,比较两个对象时,没有递归。或者,当您比较不同类型的两个基元时,可以进行递归。

ToPrimitive([])"",而不是+0。那是因为

  1. 数组没有@@ toPrimitive方法,因此使用OrdinaryToPrimitive
  2. 抽象相等没有提示,因此使用了数字
  3. 然后首先调用valueOf(继承自Object.prototype),但不会返回原语。
  4. 最后toString(继承自Array.prototype)是最后一次尝试。它执行join,在这种情况下返回空字符串。这是原始的。