JavaScript类型转换(二)——如何转换
这是JavaScript类型转换系列文章的第二篇,讲述如何向3个基本类型转换。
如何转换
前文已经说过,类型转换的最终目标是3个基本类型:number、string、boolean。本篇就是要讲解数据向这三个方向转换的细节。
首先需要讲引用类型数据如何向number、string转换,至于为什么没有boolean方向,读完本篇就会知道。
引用类型的ToPrimitive流程
ToPrimitive流程由JavaScript宿主环境实现,影响引用类型转换结果。
这个流程有很多细节,我们只需要了解:
- 进入这个流程时传入的转换方向很重要,通常转换方向倾向于
number; - 引用类型上的
[Symbol.toPrimitive]函数结果最优先; - 引用类型上的
toString和valueOf函数的结果作为备选,转换方向影响它俩的优先顺序; - 如果上述3个函数的返回仍然是引用类型,则会抛出
TypeError异常。
不需要担心引用类型没有toString()和valueOf()函数,JavaScript中所有引用对象的根父类Object定义了这两个函数,它的子孙类型只需要覆盖这两个函数就可以实现自定义。JavaScript内置的类型,绝大多数valueOf()返回的是其自身,toString()有各自的差异,如下表:
| 数据类型 | valueOf返回 | toString返回 |
|---|---|---|
| Number | 原始值 | 对应字符串 |
| String | 原始值 | 对应字符串 |
| Boolean | 原始值 | 对应字符串 |
| Date | 时间戳 | 日期时间字符串 |
| Array | 对象自身 | [数组元素拼接成的字符串(用逗号分隔)] |
| Function | 对象自身 | 函数源代码字符串 |
| RegExp | 对象自身 | 正则字符串 |
| Object | 对象自身 | 字符串:[object Object](注意大小写) |
这里有一个疑问:进入这个流程时传入的那个转换方向参数,是由谁来控制决定的?答案在后面。
向字符串转换
在确定向字符串转换后,转换的规则如下:
| 转换前的数据 | 结果 | 举例or说明 |
|---|---|---|
string |
原值 | |
Symbol |
Symbol(描述字符串) |
不支持隐式转换 |
undefined |
"undefined" |
|
null |
"null" |
|
true |
"true" |
|
false |
"false" |
|
BigInt |
转对应的10进制数字字符串,去掉末尾的n |
0x10n->"16" |
| 引用类型 | 执行其ToPrimitive流程,转换方向为string,对得到的结果再执行向字符串转换操作 |
number向string转转换规则如下:
number向字符串转换 |
结果 | 举例 |
|---|---|---|
NaN |
"NaN" |
|
-0 |
"0" |
|
Infinity |
"Infinity" |
|
-Infinity |
"-Infinity" |
|
小数部分等于0的数字 |
舍弃小数部分后再转换 | 12.0->"12" |
| 极大值或极小值 | 对应的科学记数法字符串 | 0.000000001->"1e-9" |
| 非10进制表示的数字 | 对应的10进制数字字符串 | 0x10->"16" |
| 其它情况 | 对应的字符串 |
向数字转换
在确定向数字转换后,转换的规则如下:
| 转换前的数据 | 结果 | 举例or说明 |
|---|---|---|
number |
原值 | |
ture |
1 |
|
false |
0 |
|
null |
0 |
|
undefined |
NaN |
|
Symbol |
抛出TypeError |
|
BigInt |
对应的 Number类型数字 | 可能会丢失精度。不会隐式转换为Number类型。 |
| 引用类型 | 尝试执行其ToPrimitive流程,转换方向为number,对得到的结果再执行向数字转换操作 |
Number([10])->10 |
string向number转换的情况稍复杂:
在做转换前,字符串头尾的空白字符(包括回车换行制表等)都会被剔除
空字符串转换为:
0字符串中多个前导0的会被替换为1个
合法的数字字符串会被转换为对应数字,包括如下:
- 2、8、10、16进制数字字符串
- 极大极小值数字字符串
- 科学计数法数字字符串
"Infinity"和"-Infinity"NaN
不合法的字符串符串(包括
BigInt数字字符串):NaN
向布尔值转换
向布尔值转换的结果,大多数情况为true,以下是转换为false的情况:
false- 空字符串
nullundefined0-0NaN0ndocument.all
总结
本篇讲述的在确定转换方向后,各种数据类型转换的规则。
其中引用类型的转换规则最复杂,有必要掌握为数不多的几个内置引用类型的toString()和valueOf()返回什么结果,进阶应该掌握通过自定义[Symbol.toPrimitive]函数控制类型转换的方法。
字符串和数字相互转换,需要掌握特殊情况。
向布尔值转换的规则最简单,引用类型的[Symbol.toPrimitive]函数没有必要处理这个转换方向的情况。
下一篇讲如何确定转换方向。