> For the complete documentation index, see [llms.txt](https://coolconan.gitbook.io/roadmap/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://coolconan.gitbook.io/roadmap/front-end/web-standard/javascript/ecmascript/180710-yin-shi-zhuan-huan.md).

# 隐式转换

> ref: [JS的隐式转换 从 \[\] == false 说起](https://juejin.im/post/5a220ed85188254cc067adc0)
>
> [tc39 - spec - abstract equality comparison](https://tc39.github.io/ecma262/#sec-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.
```

## ToPrimitive

**函数签名：**

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

**流程如下：**

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

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

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

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

```javascript
[] == false; // true

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

Array.prototype.toString = Object.prototype.toString;
[].toString(); // [object Array]
[] == false; // false
```

## 数学运算

* 计算两个操作数的原始值： 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](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf))

![](https://2757623353-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LQcTxgqTqhC05ckLpLr%2F-LQcULtcaTh9ZyE1-O5p%2F-LQcUMwOlmZtZjMgRjXa%2F2018-07-20-16-08-58.png?generation=1541498831536102\&alt=media)

## Relational and Equality Operators

![](https://2757623353-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LQcTxgqTqhC05ckLpLr%2F-LQcULtcaTh9ZyE1-O5p%2F-LQcUMwQ0UAFUlprdNZO%2F2018-07-20-16-09-08.png?generation=1541498831557621\&alt=media)

## What goes through If statement

![](https://2757623353-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LQcTxgqTqhC05ckLpLr%2F-LQcULtcaTh9ZyE1-O5p%2F-LQcUMwS6XhEM2wRnTaZ%2F2018-07-20-16-09-16.png?generation=1541498836462880\&alt=media)
