类型转换
JavaScript 是弱类型语言,不用声明变量的类型;也是动态语言,在运行时根据需要转换类型。例如:
var a
// a 是 undefined, 自动转为 false
if (a) {
console.log('Well')
} else {
console.log('Oops')
}
那么不同的类型之间是如何转换的?
由 JavaScript 引擎自动转换类型是隐式类型转换,下面是转换规则。如果是相同类型直接返回,不进行类型转化。
ToBoolean
ToNumber(argument) 将 argument 转为 Boolean 类型:
| Argument Type | Result |
|---|---|
| Undefined | 返回 false。 |
| Null | 返回 false。 |
| Boolean | 返回 argument(不进行转换)。 |
| Number | 返回 false 若 argument 是 +0, −0, NaN; 不然返回 true。 |
| String | 返回 false 若 argument 是空字符串( length 为 0); 不然返回 true。 |
| Symbol | 返回 true。 |
| Object | 返回 true。 |
可以转换为 true 的值是真值(truthy),可以转换为 false 的值是假值(falsy)。原始类型的假值见开始的表。对象都是真值,特别是:
- 空对象都是转为 true,例如:空数组
[], 空对象{}。 - 包装对象都是转为 true,不管它对应的原始值是不是假值,例如:
new Boolean(false),new Number(0)。
另外注意 Wrapper objects
ToNumber
ToNumber(argument) 将 argument 转为 Number 类型:
| Argument Type | Result |
|---|---|
| Undefined | 返回 NaN。 |
| Null | 返回 +0。 |
| Boolean | 返回 1 若 argument 是 true;返回 +0 若 argument 是 false。 |
| Number | 返回 argument(不进行转换)。 |
| String | 见这。 |
| Symbol | 抛出一个 TypeError 异常。 |
| Object | 1. primValue = ToPrimitive(argument, hint Number),2. ToNumber(primValue)。 |
ToPrimitive
ToPrimitive(input, [PreferredType]) 将 input转为 Primitive。如果 input 是 Primitive 则返回它。
PreferredType 是 type hint。hint 默认值是 "default"。内置对象当中 Date 类型将 "default" 按 "string" 处理,其它的按 "number" 处理。
如果 hint 是 "string":
- 先使用 object 的
toString()方法,若结果不是 Object 则返回这个值,否则进行下一步。 - 再使用 object 的
valueOf()方法,若结果不是 Object 则返回这个值,否则抛出 TypeError 异常。
如果 hint 是 "number",先使用对象的 valueOf() 方法,再使用 toString() 方法。
JavaScript 所有的 object 都继承自 Object.prototype,它有两个方法 toString(),valueOf(),所以所有的 object 都可以使用这两个方法。不过 Array, Function, Date, RegExp 等定义了自己的 toString() 方法;Date 定义了自己的 valueOf() 方法。
Number([]) // 0
怎么理解?设 a = []
- ToPrimitive(a, “number”) 返回
''- a.valueOf() 返回 a
- a.toString() 返回 ‘’
- ToNumber(‘’) 返回 0
现在想一想下面表达式的值
Number([1]) // ?
Number([1, 2]) // ?
Number(new Date(1)) // ?
ToString
ToString(argument) 将 argument 转为 String 类型:
| Argument Type | Result |
|---|---|
| Undefined | 返回 “undefined”。 |
| Null | 返回 “null”。 |
| Boolean | 如果 argument 是 true, 返回 “true”。 如果 argument 是 false, 返回 “false”。 |
| Number | 转换规则见下。 |
| String | 返回 argument(不进行转换)。 |
| Symbol | 抛出一个 TypeError 异常。 |
| Object | 先让 primValue 为 ToPrimitive(argument, hint String),再 ToString(primValue)。 |
Number 类型转为 String 类型:
- NaN 转为 “NaN”;+0,-0 转为 “0”;+∞ 转为 “Infinity”
- 负数转换后添加前缀 “-“。
还可以用 Number 类的方法转为特定格式的字符串。如 toFixed(), toExponential(), toPrecision() 等。
ToObject
ToObject(argument) 将 argument 转为 Object 类型:
| Argument Type | Result |
|---|---|
| Undefined | 抛出一个 TypeError 异常。 |
| Null | 抛出一个 TypeError 异常。 |
| Boolean | 返回一个 Boolean 包装对象。 |
| Number | 返回一个 Number 包装对象。 |
| String | 返回一个 String 包装对象。 |
| Symbol | 返回一个 Symbol 包装对象。 |
| Object | 返回 argument(不进行转换)。 |
Object() 跟 ToObject 有一点不一样,Object() 参数为 undefined 或 null 时,返回一个空对象。