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

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

抽象相等比较算法

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

比较x == y, 其中xy是值,则返回truefalse。比较过程具体如下。

  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. 如果xNaN, 返回false

    ​ ii. 如果yNaN, 返回false

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

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

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

    vi. 返回false

  2. 如果xnullyundefined, 返回true

  3. 如果xundefinedynull, 返回true

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

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

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

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

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

  9. 如果Type(x)ObjectType(y)StringNumber,返回比较ToPrimitive(x) == y的结果

  10. 返回false

总结

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

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

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

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

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