Skip to content

类型转换

提示

JavaScript 是一种弱类型语言,这意味着变量没有固定的类型,值可以在不同类型之间自动转换。理解类型转换机制(尤其是隐式转换)对于编写健壮的代码至关重要。

类型转换主要分为显式类型转换隐式类型转换

1. 抽象操作 (Abstract Operations)

在了解具体的转换规则前,我们需要先了解 ECMAScript 规范中定义的几个内部抽象操作。

ToPrimitive

将引用类型转换为基本类型。

转换规则

  1. 检查对象是否有 Symbol.toPrimitive 方法。如果有,调用它。
  2. 如果没有,检查是否有 valueOf() 方法。如果是基本类型值,返回它。
  3. 如果没有 valueOf 或返回的不是基本类型,调用 toString()。如果是基本类型值,返回它。
  4. 如果都没有返回基本类型,抛出 TypeError

注意:对于 Date 对象,默认优先调用 toString()

js
const obj = {
  valueOf() {
    return 100
  },
  toString() {
    return 'obj'
  },
}
console.log(Number(obj)) // 100 (valueOf)
console.log(String(obj)) // 'obj' (toString)

ToString

将非字符串值转换为字符串。

输入类型转换结果
undefined'undefined'
null'null'
true / false'true' / 'false'
Number'123', 'NaN', 'Infinity'
ObjectToPrimitive,再 ToString

ToNumber

将非数字值转换为数字。

输入类型转换结果
undefinedNaN
null0
true / false1 / 0
String'123' -> 123, '' -> 0, 'abc' -> NaN
ObjectToPrimitive,再 ToNumber

ToBoolean

将值转换为布尔值。

假值 (Falsy Values)

  • undefined
  • null
  • false
  • +0, -0, NaN
  • "" (空字符串)

真值 (Truthy Values)

  • 除上述假值以外的所有值(包括空对象 {} 和空数组 [])。

2. 显式类型转换

显式调用函数进行转换,代码意图清晰。

转换为字符串

  • String(value)
  • value.toString()

转换为数值

  • Number(value)
  • parseInt(string, radix)
  • parseFloat(string)

转换为布尔值

  • Boolean(value)
  • !!value (双重取反,虽然是操作符但常用于显式转换)

3. 隐式类型转换

发生在运算符操作或流程控制语句中,容易产生意想不到的结果。

四则运算符

加法 (+)

  • 如果有一个操作数是字符串,则进行字符串拼接(另一个操作数也会被转为字符串)。
  • 否则,进行数字加法(将操作数转为数字)。
js
1 + '1' // '11'
1 + true // 2
1 + null // 1
1 + undefined // NaN

减、乘、除 (-, *, /)

  • 都会将操作数转换为数字进行运算。
js
'5' - '2' // 3
'5' * '2' // 10
'5' / '2' // 2.5

相等运算符 (==)

== 会进行类型转换后再比较,规则较为复杂(建议优先使用 ===)。

核心规则

  1. null == undefined // true
  2. String == Number -> ToNumber(String) == Number
  3. Boolean == Any -> ToNumber(Boolean) == Any
  4. Object == String/Number -> ToPrimitive(Object) == String/Number

经典面试题

js
;[] == ![] // true

解析

  1. ![] 转换为 false
  2. [] == false
  3. false 转换为 0
  4. [] == 0
  5. [] ToPrimitive 转换为 '',再 ToNumber 转换为 0
  6. 0 == 0 -> true

关系运算符 (>, <)

  1. 如果两个操作数都是字符串,比较 Unicode 编码。
  2. 否则,转换为数字比较。
js
'10' < '9' // true (因为 '1' 的编码 < '9')
'10' < 9 // false (10 < 9)

4. 总结与建议

  1. 尽量使用显式转换:如 Number(), String(),让代码意图更明确。
  2. 使用 === 代替 ==:避免隐式转换带来的不可预期结果。
  3. 注意 if 判断:直接使用 if (obj) 时,利用的是 ToBoolean 规则。

如有转载或 CV 的请标注本站原文地址