隐式转换可谓是JS中的一大难点之一,也是我们平时写代码遇见最多的东西。如果搞不清楚,我们就不能完全掌控我们的代码,因为不知道它会有什么结果。今天我们就来好好唠唠这玩意。
抽象操作
ES5规范的第9节中定义了一些抽象操作(abstract operation),这些操作仅供内部使用。通俗的解释就是我们不能去调用他们,你可以理解为这只是一个规则,用于隐式转换的规则,这些规则都有他们自己的名字,方便理解记忆。
- ToString
- ToNumber
- ToBoolean
- ToPrimitive
这里我们只是简单的介绍,想要知道更具体的转换规则可以参考ES5规范第9节。
ToString
参数 | 结果 |
---|---|
undefined | “undefined” |
null | “null” |
boolean | “true” or “false” |
number | 123 -> “123”,和Number()类似 |
string | 不需要转换 |
object | 根据ToPrimitive得到基本类型再进行上述操作 |
ToNumber
参数 | 结果 |
---|---|
undefined | NaN |
null | 0 |
boolean | true -> 1 & false -> 0 |
number | 不需要转换 |
string | “123” -> 123 |
object | 根据ToPrimitive得到基本类型再进行上述操作 |
ToBoolean
JavaScript 中的值可以分成两类:
- 可以被强制类型转换为 false 的值
- 被强制转换成 true 的值
而被强制转换成 false 的值是下面这些:
- undefined
- null
- false
- +0,-0,NaN
- “”
也就是说,除此之外,在通常情况下,其他值均会被转换成 true 。比如对象均会被转换成 true 。
既然我们说了通常情况,那肯定也有不通常情况。浏览器在某些特定情况下,在常规 JavaScript 语法基础上自己创建了一些外来值,这些被称为假值对象。
假值对象和普通对象没有太多差别,但是将他们强制类型转换为布尔值是结果为 false 。比如 document.all 。我们这里只是了解就行了,不作详细讨论。
大部分情况下除了上面所说的会被转换为 false 的值之外都会被转换为 true 。
ToPrimitive
通常我们对对象进行比较操作时,会发生隐式类型转换。ToPrimitive 操作会返回一个基本类型。对于大部分对象,它会先调用 valueOf 方法,如果返回的不是一个基本类型,再调用 toString 方法,如果返回的仍然不是基本对象,会抛出一个错误。
但是对于Date对象,它首先会调用 toString 方法,再调用 valueOf 方法,这里我们不细说了,大家只做了解就行了。
let x = new Date();
let y = {
};
let myToString = () => {
return 1;
}
let myValueOf = () => {
return 2;
}
x.toString = y.toString = myToString;
x.valueOf = y.valueOf = myValueOf;
console.log(x == 1);