EcmaScript - 相等操作符

规范链接open in new window

相等操作符

相等表达式的结果: EqualityExpression == RelationalExpression 最终计算成以下结果。

  1. 将EqualityExpression表达式的结果赋值给lref
  2. 将GetValue(lref)赋值给lref(GetValue的算法可以具体再查阅规范)
  3. 将RelationalExpression表达式的结果赋值给rref
  4. 将GetValue(rref)赋值给rref
  5. 返回执行"抽象相等"算法的结果即rval == lval

值得一提的是,不知道为什么规范里rval和lval相对于对应表达式,互相换了个位置。

抽象相等比较算法

接上小节第五个步骤,也就是核心。

比较x == y, 其中x和y是值,则返回true或false。比较过程具体如下。

  1. x和y类型相等(插一句这里的类型就是6种, null, undefined, string, number, boolean, object,不要和typeof关键字得到几种类型搞混)

    a. 如果Type(x)是Undefined, 返回true

    b. 如果Type(x)是Null, 返回true

    c. 如果Type(x)是Number,

    ​ i. 如果x是NaN, 返回false

    ​ ii. 如果y是NaN, 返回false

    iii. 如果x是和y相同的值,则返回true

    iv. 如果x是+0且y是-0, 则返回true

    v. 如果x是-0且y是+0, 则返回true

    vi. 返回false

  2. 如果x是null且y是undefined, 返回true

  3. 如果x是undefined且y是null, 返回true

  4. 如果Type(x)是Number且Type(y)是String,则返回比较x == ToNumber(y)的结果

  5. 如果Type(x)是String且Type(y)是Number,则返回比较ToNumber(x) == y的结果

  6. 如果Type(x)是Boolean, 则返回比较ToNumber(x) == y的结果

  7. 如果Type(y)是Boolean, 则返回比较x == ToNumber(y)的结果

  8. 如果Type(x)是String或是Number且Type(y)是对象,返回比较x == ToPrimitive(y)的结果

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

  10. 返回false

总结

从上面的算法来看,我们不难发现整个过程就是在转换+递归。

如果是类型相同,我们可以直接按照具体值进行比较。

但如果类型不同,则依照顺序依次转换每个值,再最终进行比较。

最后吐槽下,面试题考这个真的是八股文。谁会去记忆这种东西呢?

我又对照了红宝书第三版的相等操作符的算法。红宝书对规范总结的很好啊,所以这本书被广泛推崇不是没有原因的。