隐式转换

ref: JS的隐式转换 从 [] == false 说起

tc39 - spec - abstract equality comparison


Update 2019-04-23 摘自 tc39 ecma262 规范:

7.2.14 Abstract Equality Comparison

The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

1. If Type(x) is the same as Type(y), then
Return the result of performing Strict Equality Comparison x === y.
2. If x is null and y is undefined, return true.
3. If x is undefined and y is null, return true.
4. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ! ToNumber(y).
5. If Type(x) is String and Type(y) is Number, return the result of the comparison ! ToNumber(x) == y.
6. If Type(x) is Boolean, return the result of the comparison ! ToNumber(x) == y.
7. If Type(y) is Boolean, return the result of the comparison x == ! ToNumber(y).
8. If Type(x) is either String, Number, or Symbol and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
9. If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y.
10. Return false.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

ToPrimitive

函数签名:

ToPrimitive(input, PreferredType?) // PreferredType: Number 或者 String

流程如下:

  • input为原始值,直接返回;
  • 不是原始值,调用该对象的valueOf()方法,如果结果是原始值,返回原始值;
  • 调用valueOf()不是原始值,调用此对象的toString()方法,如果结果为原始值,返回原始值;
  • 如果返回的不是原始值,抛出异常TypeError。

其中PreferredType控制线调取valueOf()还是toString()。

ps: Date类型按照String去调用。

如果对prototype上的valueOf或者toString方法进行了修改,则隐式转换会有不一样的结果。可以通过以下代码看下上述流程是如何进行的。

[] == false; // true

Array.prototype.valueOf = () => true;
[].valueOf(); // true;
[] == false; // false

Array.prototype.toString = Object.prototype.toString;
[].toString(); // [object Array]
[] == false; // false
1
2
3
4
5
6
7
8
9

数学运算

  • 计算两个操作数的原始值: prima = ToPrimitive(a), prima = ToPrimitive(b);
  • 如果原始值有String,全部转换为String,返回String相加后的结果;
  • 如果原始值没有String,全部转换为Number, 返回Number相加后的结果;

比较运算

== 中的隐式转换:

  • x y都为Null或undefined,return true;
  • x或y为NaN, return false;
  • 如果x和y为String,Number,Boolean并且类型不一致,都转为Number再进行比较
  • 如果存在Object,先转换为原始值,再进行比较

valueOf(MDN)


Relational and Equality Operators

What goes through If statement