ECMAScript运行环境会在需要时执行自动类型转换。定义一套关于转换的抽象操作有助于阐明某些结构的语义。这些抽象操作不是语言本身的一部分;它们被定义在这里是为了协助语言的语义规范。这些关于转换的抽象操作是多态的,它们可以接受任何ECMAScript语言类型,但不能接受规范类型。
ToPrimitive 抽象操作接受一个值,和一个可选的期望类型作参数。ToPrimitive 运算符把其值参数转换为非对象类型。如果对象有能力被转换为不止一种原语类型,可以使用可选的期望类型来暗示那个类型。根据下表完成转换:
|nowrap| 输入类型|结果| |----------------|----| |未定义|结果等于输入的参数(不转换)。| |空值|结果等于输入的参数(不转换)。| |布尔值|结果等于输入的参数(不转换)。| |数值|结果等于输入的参数(不转换)。| |字符串|结果等于输入的参数(不转换)。| |对象|返回该对象的默认值。调用该对象的内部方法 [[DefaultValue]] 来恢复这个默认值,调用时传递暗示期望类型(所有 ECAMScript 本地对象的 [[DefaultValue]] 一樣)。|
ToBoolean 抽象操作根据下表将其参数转换为布尔值类型的值:
|nowrap| 输入类型|结果| |----------------|----| |未定义|false| |空值|false| |布尔值|结果等于输入的参数(不转换)。| |数值|如果参数是 +0, -0, 或 NaN,结果为 false ;否则结果为 true。| |字符串|如果参数是空字符串(其长度为零),结果为 false,否则结果为 true。| |对象|true|
ToNumber 抽象操作根据下表将其参数转换为数值类型的值:
|nowrap| 输入类型|结果| |----------------|----| |未定义|NaN| |空值|+0| |布尔值|如果参数是 true,结果为 1。如果参数是 false,此结果为 +0。| |数字|结果等于输入的参数(不转换)。| |字符串|参见下文的文法和注释。| |对象|应用下列步骤:
- 令primValue为 (输入参数, 暗示数值类型)。
- 返回 ToNumber(primValue)。|
对字符串应用 ToNumber 时,对输入字符串应用如下文法。如果此文法无法将字符串解释为 StringNumericLiteral 的扩展,那么 ToNumber 的结果为 NaN。
StringNumericLiteral
:::
StrWhiteSpace
opt
StrWhiteSpace
opt
StringNumericLiteral
opt
StrWhiteSpace
opt
StrWhiteSpace
:::
StrWhiteSpaceChar
StrWhiteSpace
opt
StrWhiteSpaceChar
:::
WhiteSpace
LineTerminator
StrNumericLiteral
:::
StrDecimalLiteral
HexIntegerLiteral
StrDecimalLiteral
:::
StrUnsignedDecimalLiteral
+
StrUnsignedDecimalLiteral
-
StrUnsignedDecimalLiteral
StrUnsignedDecimalLiteral
:::
Infinity
DecimalDigits
.
DecimalDigits
opt
ExponentPart
opt
.
DecimalDigits
ExponentPart
opt
DecimalDigits
ExponentPart
opt
DecimalDigits
:::
DecimalDigit
DecimalDigits
DecimalDigit
DecimalDigit
:::
one
of
0
1
2
3
4
5
6
7
8
9
ExponentPart
:::
ExponentIndicator
SignedInteger
ExponentIndicator
:::
one
of
e
E
SignedInteger
:::
DecimalDigit
+
DecimalDigit
-
DecimalDigit
HexIntegerLiteral
:::
0x
HexDigit
0X
HexDigit
HexIntegerLiteral
HexDigit
HexDigit
:::
one
of
0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f
A
B
C
D
E
F
需要注意到 StringNumericLiteral 和 NumericLiteral 语法上的不同:
- StringNumericLiteral 的前后可以有若干的空白字符或行终止符。
- 十进制的 StringNumericLiteral 可有任意位数的 0 在前头。
- 十进制的 StringNumericLiteral 可有指示其符号的 + 或 - 前缀。
- 空的,或只包含空白的 StringNumericLiteral 會被转换为 +0。
字符串到数字值的转换,大体上类似于判定 NumericLiteral 的数字值,不过有些细节上的不同,所以,这里给出了把 StringNumericLiteral 转换为数值类型的值的全部过程。这个值分两步来判定:首先,从 StringNumericLiteral 中导出数学值;第二步,以下面所描述的方式对该数学值进行舍入。
- StringNumericLiteral ::: [empty] 的数学值是 0。
- StringNumericLiteral ::: StrWhiteSpace 的数学值是 0。
- StringNumericLiteral ::: StrWhiteSpaceopt StringNumericLiteral StrWhiteSpaceopt 的数学值是里面的 StringNumericLiteral 部分,无论前后是否存在空白。
- StrNumericLiteral ::: StrDecimalLiteral 的数学值是 StrDecimalLiteral 的数学值。
- StrNumericLiteral ::: HexIntegerLiteral 的数学值是 HexIntegerLiteral 的数学值。
- StrDecimalLiteral ::: StrUnsignedDecimalLiteral 的数学值是 StrUnsignedDecimalLiteral 的数学值。
- StrDecimalLiteral ::: + StrUnsignedDecimalLiteral 的数学值是 StrUnsignedDecimalLiteral 的数学值。
- StrDecimalLiteral ::: - StrUnsignedDecimalLiteral 的数学值是 StrUnsignedDecimalLiteral 的数学值的负数。 (需要注意的是,如果 StrUnsignedDecimalLiteral 的数学值是 0, 其负数也是 0。下面中描述的舍入规则会合适地处理小于数学零到浮点数 +0 或 -0 的变换。)
- StrUnsignedDecimalLiteral ::: Infinity 的数学值是 '''1010000'''(一个大到会舍入为 +∞ 的值)。
- StrUnsignedDecimalLiteral ::: DecimalDigits . 的数学值是 DecimalDigits 的数学值。
- StrUnsignedDecimalLiteral ::: DecimalDigits . DecimalDigits 的数学值是第一个 DecimalDigits 的数学值加(第二个 DecimalDigits 的数学值乘以 10-n),这里的 n 是第二个 DecimalDigits 的字符数量。
- StrUnsignedDecimalLiteral ::: DecimalDigits . ExponentPart 的数学值是 DecimalDigits 的数学值乘以 10e, 这里的 e 是 ExponentPart 的数学值。
- StrUnsignedDecimalLiteral ::: DecimalDigits . DecimalDigits ExponentPart 的数学值是(第一个 DecimalDigits 的数学值加(第二个 DecimalDigits 的数学值乘以 10-n))乘以 10e,这里的 n 是 第二个 DecimalDigits 中的字符个数,e 是 ExponentPart 的数学值。
- StrUnsignedDecimalLiteral ::: . DecimalDigits 的数学值是 DecimalDigits 的数学值乘以 10-n,这里的 n 是 DecimalDigits 中的字符个数。
- StrUnsignedDecimalLiteral ::: . DecimalDigits ExponentPart 的数学值是 DecimalDigits 的数学值乘以 10e-n,这里的 n 是 DecimalDigits 中的字符个数,e 是 ExponentPart 的数学值。
- StrUnsignedDecimalLiteral ::: DecimalDigits 的数学值是 DecimalDigits 的数学值。
- StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPart 的数学值是 DecimalDigits 的数学值乘以 10e,这里的 e 是 ExponentPart 的数学值。
- DecimalDigits ::: DecimalDigit 是 DecimalDigit 的数学值。
- DecimalDigits ::: DecimalDigits DecimalDigit 的数学值。是( DecimalDigits 的数学值乘以 10)加 DecimalDigit 的数学值。
- ExponentPart ::: ''ExponentIndicator SignedInteger 的数学值是 SignedInteger 的数学值。
- SignedInteger ::: DecimalDigits 的数学值是 DecimalDigits 的数学值。
- SignedInteger ::: + DecimalDigits 的数学值是 DecimalDigits 的数学值。
- SignedInteger ::: - DecimalDigits 是 DecimalDigits 的数学值的负数。
- DecimalDigit ::: 0 或 HexDigit ::: 0 的数学值是 0。
- DecimalDigit ::: 1 或 HexDigit ::: 1 的数学值是 1。
- DecimalDigit ::: 2 或 HexDigit ::: 2 的数学值是 2。
- DecimalDigit ::: 3 或 HexDigit ::: 3 的数学值是 3。
- DecimalDigit ::: 4 或 HexDigit ::: 4 的数学值是 4。
- DecimalDigit ::: 5 或 HexDigit ::: 5 的数学值是 5。
- DecimalDigit ::: 6 或 HexDigit ::: 6 的数学值是 6。
- DecimalDigit ::: 7 或 HexDigit ::: 7 的数学值是 7。
- DecimalDigit ::: 8 或 HexDigit ::: 8 的数学值是 8。
- DecimalDigit ::: 9 或 HexDigit ::: 9 的数学值是 9。
- HexDigit ::: a 或 HexDigit ::: A 的数学值是 10。
- HexDigit ::: b 或 HexDigit ::: B 的数学值是 11。
- HexDigit ::: c 或 HexDigit ::: C 的数学值是 12。
- HexDigit ::: d 或 HexDigit ::: D 的数学值是 13。
- HexDigit ::: e 或 HexDigit ::: E 的数学值是 14。
- HexDigit ::: f 或 HexDigit ::: F 的数学值是 15。
- HexIntegerLiteral ::: 0x HexDigit 的数学值是 HexDigit 的数学值。
- HexIntegerLiteral ::: 0X HexDigit 的数学值是 HexDigit 的数学值。
- HexIntegerLiteral ::: HexIntegerLiteral HexDigit 的数学值是(HexIntegerLiteral 的数学值乘以 16)加 HexDigit 的数学值。
一旦字符串数值常量的数学值被精确地确定,接下来就会被舍入为数值类型的一个值。如果数学值是 0,那么舍入值为 +0,否则如果字符串数值常量中第一个非空白字符是 ‘-’,舍入值为 -0。对于其它情况,舍入后的值必须是其数学值的数字值。如果该字面量包含一个 StrUnsignedDecimalLiteral 且该字面量大于 20 位有效数字,则此数字的值是下面两种之一:一是将其 20 位之后的每个数位用 0 替换,产生此字符串解析出的数学值的数字值;二是将其 20 位之后的每个数位用 0 替换,并在第 20 位有效数字加一,产生此字符串解析出的数学值的数字值。判断一个数位是否为有效数位,首先它不能是 ExponentPart 的一部分,且
- 它不是 0;或
- 它的左边是一个非零值,右边是一个不在 ExponentPart 中的非零值。
ToInteger 抽象操作将其参数转换为整数值。
此运算符功能如下所示:
- 令 number 为对输入的参数调用 ToNumber 的结果。
- 如果 number 是 NaN 则返回 +0。
- 如果 number 是 +0、 -0、 +∞ 或 -∞ 则返回 number。
- 返回计算 sign(number)×floor(abs(number)) 的结果。
ToInt32 抽象操作将其参数转换为 在 -231 到 231-1 闭区间内的 232 个整数中的任意一个。
此运算符功能如下所示:
- 令 number 为对输入的参数调用 ToNumber 的结果。
- 如果 number 是 NaN、 +0、 -0、 +∞ 或 -∞ 则返回 +0。
- 令 posInt 为 sign(number)×floor(abs(number)) 的结果。
- 令 int32bit 为 posInt modulo 232;也就是说,假如有一个数值类型的有限正整数 k ,它小于 232 ,那么 posInt 与 k 在数学上可能相差 232 的整数倍。
- 如果 int32bit 大于或等于 231 则返回 int32bit-232 否则返回 int32bit。
ToUint32 抽象操作将其参数转换为 在 0 到 232-1 闭区间内的 232 个整数中的任意一个。
此运算符功能如下所示:
- 令 number 为对输入的参数调用 ToNumber 的结果。
- 如果 number 是 NaN、 +0、 -0、 +∞ 或 -∞ 则返回 +0。
- 令 posInt 为 sign(number)×floor(abs(number)) 的结果。
- 令 int32bit 为 posInt modulo 232;也就是说,假如有一个数值类型的有限正整数 k ,它小于 232 ,那么 posInt 与 k 在数学上可能相差 232 的整数倍。
- 返回 int32bit。
ToUint16 抽象操作将其参数转换为 在 0 到 216-1 闭区间内的 216 个整数中的任意一个。
此运算符功能如下所示:
- 令 number 为对输入的参数调用 ToNumber 的结果。
- 如果 number 是 NaN、 +0、 -0、 +∞ 或 -∞ 则返回 +0。
- 令 posInt 为 sign(number)×floor(abs(number)) 的结果。
- 令 int16bit 为 posInt modulo 216;也就是说,假如有一个数值类型的有限正整数 k ,它小于 216 ,那么 posInt 与 k 在数学上可能相差 216 的整数倍。
- 返回 int16bit。
ToString 运算符根据下表将其参数转换为字符串类型的值:
|nowrap| 输入类型|结果| |----------------|----| |未定义|"undefined"| |空值|"null"| |布尔值|如果参数是 true,那么结果为 "true"。
如果参数是 false,那么结果为 "false"。| |数值|见 9.8.1。| |字符串|返回输入的参数(不转换)。| |对象|应用下列步骤:
- 令 primValue 为 ToPrimitive(输入参数, 暗示字符串类型)。
- 返回 ToString(primValue)。|
ToString 抽象操作将数字 m 转换为字符串格式的给出如下所示:
- 如果 m 是 NaN,返回字符串 "NaN"。
- 如果 m 是 +0 或 -0,返回字符串 "0"。
- 如果 m 小于零,返回连接 "-" 和 ToString(-m) 的字符串。
- 如果 m 无限大,返回字符串 "Infinity"。
- 否则,令 n、k 和 s 皆为整数,且满足 k ≥ 1 且 10k-1 ≤ s < 10k 、 s×10n-k 的数字值为 m 且 k 足够小。注意 k 是 s 的十进制位数。s 不能被 10 整除,且 s 的至少要求的有效数字位数不一定要被这些标准唯一确定。
- 如果 k ≤ n ≤ 21,返回由 k 个 s 在十进制表示中的数字组成的字符串(有序的,开头没有零),后面连接 n-k 个 "0" 字符。
- 如果 0 < n ≤ 21,返回由 s 在十进制表示中的、最多 n 个有效数字组成的字符串,后面跟随一个小数点 ".",再后面是余下的 k-n 个 s 在十进制表示中的数字。
- 如果 -6 < n ≤ 0,返回由字符 "0" 组成的字符串,后面跟随一个小数点 ".",再后面是 -n 个 "0" 字符,最后是 k 个 s 在十进制表示中的数字。
- 否则,如果 k = 1,返回由单个数字 s 组成的字符串,后面跟随小写字母 "e",根据 n-1 是正或负,再后面是一个加号 "+" 或减号 "-" ,再往后是整数 abs(n-1) 的十进制表示(没有前置的零)。
- 返回由 s 在十进制表示中的、最多的有效数字组成的字符串,后面跟随一个小数点 ".",再后面是余下的是 k-1 个 s 在十进制表示中的数字,再往后是小写字母 "e",根据 n-1 是正或负,再后面是一个加号 "+" 或减号 "-" ,再往后是整数 abs(n-1) 的十进制表示(没有前置的零)。
ToObject 抽象操作根据下表将其参数转换为对象类型的值:
|nowrap| 输入类型|结果| |----------------|----| |未定义|抛出 TypeError 异常。| |空值|抛出 TypeError 异常。| |布尔值|创建一个新的 Boolean 对象,其 [[PrimitiveValue]] 属性被设为该参数的值。| |数值|创建一个新的 Number 对象,其 [[PrimitiveValue]] 属性被设为该参数的值。| |字符串|创建一个新的 String 对象,其 [[PrimitiveValue]] 属性被设为该参数的值。| |对象|结果是输入的参数(不转换)。|
根据 表15 定义,抽象操作 CheckObjectCoercible 在其参数无法用 ToObject 转换成对象的情况下抛出一个异常:
|nowrap| 输入类型|结果| |----------------|----| |未定义|抛出一个 TypeError 异常| |空值|抛出一个 TypeError 异常| |布尔值|返回| |数值|返回| |字符串|返回| |对象|返回|
根据 表16,抽象操作 IsCallable 确定其必须是 ECMAScript 语言值的参数是否是一个可调用对象:
|nowrap| 输入类型|结果| |----------------|----| |未定义|返回 false。| |空值|返回 false。| |布尔值|返回 false。| |数值|返回 false。| |字符串|返回 false。| |对象|如果参数对象包含一个 [[Call]] 内部方法,则返回 true,否则返回 false。|
内部严格比较操作 SameValue(x,y),x 和 y 为 ECMAScript 语言中的值,需要产出 true 或 false。
比较过程如下:
-
如果 Type(x) 结果为 Undefined,返回 true
-
如果 Type(x) 结果为 Null,返回 true
-
如果 Type(x) 结果为 Number,则
- 如果 x 为 NaN,且 y 也为 NaN,返回 true
- 如果 x 为 +0,y 为 -0,返回 false
- 如果 x 为 -0,y 为 +0,返回 false
- 如果 x 与 y 为同一个数字,返回 true
- 返回 false
-
如果 Type(x) 结果为 String,如果 x 与 y 为完全相同的字符序列(相同的长度和相同的字符对应相同的位置),返回 true,否则,返回 false
-
如果 Type(x) 结果为 Boolean,如果 x 与 y 都为 true 或 false,则返回 true,否则,返回 false
-
如果 x 和 y 引用到同一个 Object 对象,返回 true,否则,返回 false