类型转换 
更新: 4/9/2025 字数: 0 字 时长: 0 分钟
温馨提示
阅读《你不知道的 JavaScript(中卷)》和各个大佬的文章所归纳的总结,如有异议按你的理解为主
将值从一种类型转换为另一种类型称为类型转换 
 在 JavaScript 中进行类型转换时,根据调用形式的不同可以分为以下两种:
- 显式类型转换
 - 隐式类型转换
 
抽象操作 (内部的类型转换规则) 
在了解类型转换前我们需要知道 JavaScript 的 抽象操作 (类型转换规则)
抽象操作 是指仅供内部使用的操作
ToPrimitive将引用类型转换成相应的基本类型值ToString将非字符串值转换成字符串ToBoolean将非布尔值转换成布尔值ToNumber将非数字值转换成数字值
ToPrimitive 
ToPrimitive 用来处理引用类型到基本类型的类型转换
ToPrimitive 转换规则
- 检查是否存在 
Symbol.toPrimitive()- 返回值为基本类型直接返回该值
 - 返回值为引用类型抛出 
TypeError错误 
 - 检查是否存在 
valueOf()- 返回值为基本类型直接返回该值
 - 返回值为引用类型继续调用 
toString() 
 - 调用 
toString()- 返回值为基本类型直接返回该值
 - 返回值为引用类型抛出 
TypeError错误 
 
注意点
- 使用 
Object.create(null)创建的对象没有原型,即不存在valueOf()和toString(),当对其进行类型转换时会抛出TypeError错误 - 在做显式类型转换时 
valueOf()和toString()的调用顺序会根据转换目标不同去做相应调整- 默认情况下都是先调用 
valueOf()再调用toString() - 当使用
String做显示类型转换时,会先调用toString()再调用valueOf() 
 - 默认情况下都是先调用 
 
const obj1 = {
  toString() {
    console.log('toString')
    return []
  },
  valueOf() {
    console.log('valueOf')
    return 2021
  },
}
const obj2 = {
  toString() {
    console.log('toString')
    return 'qianxun'
  },
  valueOf() {
    console.log('valueOf')
    return []
  },
}
/** 显式类型转换 */
Number(obj1) // valueOf              => 2021
Number(obj2) // valueOf   toString   => NaN
String(obj1) // toString  valueOf    => '2021'
String(obj2) // toString             => 'qianxun'
/** 隐式类型转换 */
1 + obj1 // valueOf              => 2022
1 + obj2 // valueOf   toString   => '1qianxun'
'str: ' + obj1 // valueOf              => 'str: 2021'
'str: ' + obj2 // valueOf   toString   => 'str: qianxun'ToString 
ToString 用来处理非字符串到字符串的类型转换
ToString 转换规则
- 基本类型 
undefined=>'undefined'null=>'null'true=>'true'false=>'false'number- 普通数值直接加引号
 - 极小和极大的数字将转换成指数形式的字符串
 +0 0 -0=>'0'Infinity=>'Infinity'
 - 引用类型会先调用 
ToPrimitive逻辑将其转换成基本类型,如果返回的基本类型不是字符串,再遵循以上规则进行转换 
ToBoolean 
ToBoolean 用来处理非布尔值到布尔值的类型转换,在 JavaScript 中,布尔类型分为真值(true)和假值(false)
- 假值:可以被强制类型转换为 
false的值 - 真值:除假值之外的值
 
ToBoolean 转换规则
- 以下值会被转换成假值(
false)undefinednullfalse+0 0 -0 NaN''
 - 除假值之外的值都会被转换成真值(
true) 
ToNumber 
ToNumber 用来处理非数字值到数字值的类型转换
ToNumber 转换规则
- 基本类型 
undefined=>NaNnull=>0true=>1false=>0string- 空字符串(
'') =>0 - 非数字字符串 => 
NaN 
- 空字符串(
 
 - 引用类型会先调用 
ToPrimitive逻辑将其转换成基本类型,如果返回的基本类型不是数字,再遵循以上规则进行转换 
显式类型转换 
显式类型转换是指显式的去调用类型转换方法
- 转换成布尔值 
Boolean()
 - 转换成数值 
Number()parseInt()parseFloat()
 - 转换成字符串 
String()
 
注意点
Number()转换的是整个参数值,如果包含非数字字符就会返回NaNparseInt()和parseFloat()转换的是部分值,是对字符串逐个进行解析和转换,他们会逐字符解析,直到遇到无效字符如(果传入的参数不是字符串,会先对其进行字符串的转换)jsNumber('123abc') // NaN Number('0x10') // 16 (自动识别十六进制) Number(' 123 ') // 123 (忽略前后空格) parseInt('123abc') // 123 parseInt('12.34') // 12 (仅取整数部分) parseFloat('3.14abc') // 3.14 parseFloat('1e5') // 100000
隐式类型转换 
隐式类型转换是指在执行过程中,当实际操作的值与 JavaScript 内部期望得到的值不同时,就会对其做隐式类型转换(即不易察觉的类型转换)
 在 JavaScript 中有以下场景会发生隐式类型转换
- 相等运算符 (
==) - 四则运算符 (
+ - * /) - 关系运算符 (
> < >= <=) - 逻辑操作符 (
&& ||) - 条件判断语句 
if()while()- 三元运算符
 
 
相等运算符运算规则(重点) 
为什么 0 == null 是 false ?
0 == null // falseECMA-262 规范 7.2.12 小节对相等运算符规则的解释
比较x == y,其中x和和 y 分别是两个值,返回一个布尔值
- 如果 
x不是正常值(比如抛出一个错误),中断执行; - 如果 
y不是正常值,中断执行; - 如果 
Type(x)与Type(y)相同,执行严格相等运算x === y; - 如果 
x是null,y是undefined,返回true; - 如果 
x是undefined,y是null,返回true; - 如果 
Type(x)是数值,Type(y)是字符串,返回x == ToNumber(y)的结果; - 如果 
Type(x)是字符串,Type(y)是数值,返回ToNumber(x) == y的结果; - 如果 
Type(x)是布尔值,返回ToNumber(x) == y的结果; - 如果 
Type(y)是布尔值,返回x == ToNumber(y)的结果; - 如果 
Type(x)是字符串或数值或Symbol值,Type(y)是对象,返回x == ToPrimitive(y)的结果; - 如果 
Type(x)是对象,Type(y)是字符串或数值或Symbol值,返回ToPrimitive(x) == y的结果; - 返回 
false。 
Type(x) 是
the type of x的简写,其中的type是 ECMA-262 规范中定义的 ECMAScript 语言和规范类型
所以在计算 0 == null 时,由于 0 的类型是数值,null 的类型是 Null(这是规格 4.3.13 小节的规定,是内部 Type 运算的结果,跟 typeof 运算符无关);
 因此上面的前 11 步都得不到结果,要到第 12 步才能得到 false
相等运算符运算规则总结
- 同类型比较时,执行严格相等运算 
x === y undefined与null比较时返回truestring与number进行比较时,先将string做ToNumber处理,再进行比较boolean与其它类型进行比较时,先将boolean做ToNumber处理,再进行比较引用类型与基本类型进行比较时,将引用类型做ToPrimitive处理,再进行比较undefinednull与其它类型的比较时都返回false
四则运算符运算规则 
四则运算符运算规则
-(减)*(乘)/(除) 运算符: 先对操作数做ToNumber处理再执行运算+(加) 运算符- 做一元运算时,对操作数做 
ToNumber处理 - 做二元运算时 
- 当其中一个操作数为 
string时,将另一个操作数做ToString处理再执行字符串拼接 - 当一个操作数为 
number另一个操作数为基本类型时,将基本类型做ToNumber处理再执行运算 - 当一个操作数为 
number另一个操作数为引用类型时,都会先做ToString处理再执行字符串拼接 
 - 当其中一个操作数为 
 
- 做一元运算时,对操作数做 
 
// 一元运算符
;+'1' // 1
// 二元运算符
'1' + 1 // '11'
1 + true // 1
1 + { a: 1 } // '1[object Object]'关系、逻辑、条件运算符运算规则 
关系运算符运算规则
- 将引用类型做 
ToPrimitive处理 - 如果两个参数都是 
string类型时进行Unicode 编码大小比较 - 否则将两个参数做 
ToNumber处理,再进行数值大小比较 
let obj = { a: 1 }
let obj2 = { a: 2 }
obj > obj2 //到第二步
'a' < 'b' //到第二步
undefined > 'a' //到第三步 false
true > obj //到第三步 false
true < false //到第三步 false逻辑操作符与条件判断语句
在逻辑操作符与条件判断语句中都是做 ToBoolean 处理
// 逻辑操作符
false && console.log('不会执行') // 直接返回 false
process.env.PORT || 3000 // 环境变量未定义时用3000
'text' && 0 // 0(非布尔结果)
null || 'ok' // "ok"
// 条件判断语句
const access = age >= 18 ? '允许' : '拒绝'