本文档提供了 JavaScript 类型强制转换系统的技术概述,该系统在“You Don't Know JS Yet”代码库中实现。类型强制转换是指在 JavaScript 中将一个值从一种类型转换为另一种类型的过程。本文档涵盖了显式和隐式强制转换机制、ECMAScript 规范中定义了控制强制转换的抽象操作,以及在 JavaScript 代码中激活这些操作的具体表达式。有关利用强制转换的相等性比较信息,请参阅相等性比较。
当一个值从一种类型转换为另一种类型时,就会发生类型强制转换。在 JavaScript 中,强制转换是该语言类型系统的基本方面,代表了 JavaScript 的三大支柱之一(与作用域/闭包和原型并列)。
JavaScript 中有两类强制转换
显式强制转换和隐式强制转换之间的区别在某种程度上是主观的,并且可能取决于上下文。
JavaScript 规范定义了几个“抽象操作”,它们规定了类型如何转换。这些是概念性机制,不能直接在代码中作为函数调用,但可以通过各种 JavaScript 表达式和语句激活。
来源: types-grammar/ch4.md40-47 types-grammar/ch4.md87-105 types-grammar/ch4.md106-126 types-grammar/ch4.md165-187
ToBoolean 抽象操作将值转换为布尔值。所有 JavaScript 值都分为真值(转换为 true)或假值(转换为 false)。
假值的完整列表
| 值 | 类型 |
|---|---|
未定义 | 未定义 |
null | null |
false | 布尔值 |
+0, -0, 0 | 数字 |
0n | bigint |
NaN | 数字 |
"" (空字符串) | 字符串 |
所有其他值都被认为是真值并转换为 true。
ToPrimitive 抽象操作将对象转换为原始值。它接受一个 hint 参数,该参数会影响转换过程。
hint 为“string”时toString() 方法valueOf() 方法hint 为“number”(或没有提示)时valueOf() 方法toString() 方法如果两种方法都不能生成原始值,则会抛出 TypeError。
来源: types-grammar/ch4.md87-104
ToString 抽象操作将值转换为字符串表示
| 值类型 | 结果示例 |
|---|---|
| 未定义 | "undefined" |
| null | "null" |
| 布尔值 | "true" 或 "false" |
| 数字 | "42"、"Infinity"、"NaN" |
| -0 | "0"(注意:负号丢失) |
| bigint | "42"(不带 n 后缀) |
| symbol | TypeError(无法隐式转换) |
| 对象 | 委托给 ToPrimitive,提示为“string” |
来源: types-grammar/ch4.md106-162
ToNumber 抽象操作将值转换为数字
| 值类型 | 结果示例 |
|---|---|
| 未定义 | NaN |
| null | 0 |
| 布尔值 | true 为 1,false 为 0 |
| 字符串 | 解析后的数值或 NaN(如果无效) |
| 空字符串 | 0 |
| 仅空白符 | 0 |
| symbol | TypeError |
| bigint | TypeError |
| 对象 | 委托给 ToPrimitive,提示为“number” |
来源: types-grammar/ch4.md165-254
有几种专门的数值转换操作
ToNumeric()ToIntegerOrInfinity()ToInt32()、ToUint32()、ToInt16()、ToUint16()、ToInt8()、ToUint8()、ToUint8Clamp()ToBigInt()、StringToBigInt()、ToBigInt64()、ToBigUint64()来源: types-grammar/ch4.md216-237
JavaScript 有多种用于比较相等性的抽象操作
SameValue() 确定两个值是否完全相同,没有任何例外
NaN 视为与其自身相等0 和 -0SameValueZero() 类似但认为 0 和 -0 相同。
IsStrictlyEqual()(由 === 激活)
falseNaN 和 -0 有特殊处理IsLooselyEqual()(由 == 激活)
IsStrictlyEqual()null 和 undefined 视为彼此相等ToPrimitive() 将对象强制转换为原始值来源: types-grammar/ch4.md257-349
IsLessThan() 抽象操作处理关系比较(<、>、<=、>=)
来源: types-grammar/ch4.md352-412
抽象操作由 JavaScript 代码中的具体表达式和语句激活。
来源: types-grammar/ch4.md419-494
显式地将值转换为布尔值,使用
Boolean(value) 函数(不带 new)!!value布尔值强制转换隐式发生在
if、for、while)condition ? value1 : value2)&&、||)的左操作数来源: types-grammar/ch4.md424-492
来源: types-grammar/ch4.md497-574
显式地将值转换为字符串,使用
String(value) 函数(不带 new)value.toString() 方法(原始值的自动装箱)字符串强制转换隐式发生在
value + "" 或 "" + value`${value}`来源: types-grammar/ch4.md498-573
来源: types-grammar/ch1.md582-615 types-grammar/ch4.md575-700
显式地将值转换为数字,使用
Number(value) 函数(不带 new)+valueparseInt(string, radix) 用于整数解析parseFloat(string) 用于浮点数解析解析与强制转换的区别
parseInt/parseFloat):从字符串开头提取数字字符,遇到非数字字符停止Number/+):要求整个字符串都是有效的数字格式来源: types-grammar/ch1.md582-615 types-grammar/ch4.md575-700
将值转换为对象,使用
Object(value) 函数new String(value)、new Number(value) 等来源: types-grammar/ch3.md114-147
JavaScript 强制转换系统的几个方面特别值得注意或出乎意料
"" 强制转换为 0,而不是 NaNString(sym)),但不能隐式转换(sym + "" 会抛出错误)NaN === NaN 为 false,但 Object.is(NaN, NaN) 为 true-0 强制转换为字符串 "0",而不是 "-0"true 变为 1,false 变为 0null == undefined 为 true)来源: types-grammar/ch4.md197-203 types-grammar/ch4.md516-517 types-grammar/ch4.md319-324 types-grammar/ch4.md132-138 types-grammar/ch4.md187-190 types-grammar/ch4.md332
自动装箱是当访问属性或方法时,原始值隐式转换为其对象包装形式的过程。
这种机制允许原始值“借用”其构造函数的原型方法
| 基本类型 | 对象包装器 | 原型 |
|---|---|---|
| 字符串 | 字符串 | String.prototype |
| 数字 | 数字 | Number.prototype |
| 布尔值 | 布尔值 | Boolean.prototype |
| symbol | 符号 | Symbol.prototype |
| bigint | BigInt | BigInt.prototype |
原始值临时包装在其相应的对象包装器中,允许在丢弃包装器之前访问原型方法。
来源: types-grammar/ch2.md98-101 types-grammar/ch3.md114-146
不同的 JavaScript 运算符会触发不同的强制转换模式
| 运算符 | 强制转换模式 |
|---|---|
+ | 如果任一操作数为字符串则进行字符串连接,否则进行数值加法 |
-, *, /, % | 两个操作数都进行数值转换 |
<, >, <=, >= | 如果操作数并非都为字符串则进行数值比较,否则进行词典字符串比较 |
==, != | 如果类型不同则进行类型强制转换,遵循特定规则 |
===, !== | 无强制转换,严格相等检查 |
&&, ` |
来源: types-grammar/ch2.md511-542 types-grammar/ch4.md471-483
来源: types-grammar/ch4.md42-254
类型强制转换是 JavaScript 类型系统的一个基本方面,它允许值通过显式转换或隐式操作在不同类型之间进行转换。理解各种强制转换路径及其行为对于编写可预测的 JavaScript 代码至关重要。
刷新此 Wiki
最后索引时间2025年4月17日(7e08b2)