Warning:
This wiki has been archived and is now read-only.

ES5/类型转换与测试

From HTML5 Chinese Interest Group Wiki
< ES5
Jump to: navigation, search

ECMAScript运行环境会在需要时执行自动类型转换。定义一套关于转换的抽象操作有助于阐明某些结构的语义。这些抽象操作不是语言本身的一部分;它们被定义在这里是为了协助语言的语义规范。这些关于转换的抽象操作是多态的,它们可以接受任何ECMAScript语言类型,但不能接受规范类型

ToPrimitive

ToPrimitive 抽象操作接受一个值,和一个可选的期望类型作参数。ToPrimitive 运算符把其值参数转换为非对象类型。如果对象有能力被转换为不止一种原语类型,可以使用可选的期望类型来暗示那个类型。根据下表完成转换:
Error creating thumbnail: Unable to save thumbnail to destination
输入类型 结果
未定义 结果等于输入的参数(不转换)。
空值 结果等于输入的参数(不转换)。
布尔值 结果等于输入的参数(不转换)。
数值 结果等于输入的参数(不转换)。
字符串 结果等于输入的参数(不转换)。
对象 返回该对象的默认值。调用该对象的内部方法 [[DefaultValue]] 来恢复这个默认值,调用时传递暗示期望类型(所有 ECAMScript 本地对象的 [[DefaultValue]] 一樣)。

ToBoolean

ToBoolean 抽象操作根据下表将其参数转换为布尔值类型的值:
Error creating thumbnail: Unable to save thumbnail to destination
输入类型 结果
未定义 false
空值 false
布尔值 结果等于输入的参数(不转换)。
数值 如果参数是 +0, -0, 或 NaN,结果为 false ;否则结果为 true
字符串 如果参数是空字符串(其长度为零),结果为 false,否则结果为 true
对象 true

ToNumber

ToNumber 抽象操作根据下表将其参数转换为数值类型的值:
Error creating thumbnail: Unable to save thumbnail to destination
输入类型 结果
未定义 NaN
空值 +0
布尔值 如果参数是 true,结果为 1。如果参数是 false,此结果为 +0
数字 结果等于输入的参数(不转换)。
字符串 参见下文的文法和注释。
对象 应用下列步骤:
  1. primValueToPrimitive(输入参数, 暗示数值类型)。
  2. 返回 ToNumber(primValue)。

对字符串类型应用 ToNumber

对字符串应用 ToNumber 时,对输入字符串应用如下文法。如果此文法无法将字符串解释为 StringNumericLiteral 的扩展,那么 ToNumber 的结果为 NaN
Error creating thumbnail: Unable to save thumbnail to destination
 StringNumericLiteral :::
   StrWhiteSpaceopt
   StrWhiteSpaceopt StringNumericLiteralopt StrWhiteSpaceopt
 StrWhiteSpace :::
   StrWhiteSpaceChar StrWhiteSpaceopt
 StrWhiteSpaceChar :::
   WhiteSpace
   LineTerminator
 StrNumericLiteral :::
   StrDecimalLiteral
   HexIntegerLiteral
 StrDecimalLiteral :::
   StrUnsignedDecimalLiteral
   + StrUnsignedDecimalLiteral
   - StrUnsignedDecimalLiteral
 StrUnsignedDecimalLiteral :::
   Infinity
   DecimalDigits . DecimalDigitsopt ExponentPartopt
   . DecimalDigits ExponentPartopt
   DecimalDigits ExponentPartopt
 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

需要注意到 StringNumericLiteralNumericLiteral 语法上的不同:

字符串到数字值的转换,大体上类似于判定 NumericLiteral数字值,不过有些细节上的不同,所以,这里给出了把 StringNumericLiteral 转换为数值类型的值的全部过程。这个值分两步来判定:首先,从 StringNumericLiteral 中导出数学值;第二步,以下面所描述的方式对该数学值进行舍入。

一旦字符串数值常量的数学值被精确地确定,接下来就会被舍入为数值类型的一个值。如果数学值是 0,那么舍入值为 +0,否则如果字符串数值常量中第一个非空白字符是 ‘-’,舍入值为 -0。对于其它情况,舍入后的值必须是其数学值的数字值。如果该字面量包含一个 StrUnsignedDecimalLiteral 且该字面量大于 20有效数字,则此数字的值是下面两种之一:一是将其 20 位之后的每个数位用 0 替换,产生此字符串解析出的数学值的数字值;二是将其 20 位之后的每个数位用 0 替换,并在第 20有效数字加一,产生此字符串解析出的数学值的数字值
Error creating thumbnail: Unable to save thumbnail to destination
。判断一个数位是否为有效数位,首先它不能是 ExponentPart 的一部分,且
  • 它不是 0;或
  • 它的左边是一个非零值,右边是一个不在 ExponentPart 中的非零值。

ToInteger

ToInteger 抽象操作将其参数转换为整数值。
Error creating thumbnail: Unable to save thumbnail to destination

此运算符功能如下所示:

  1. number 为对输入的参数调用 ToNumber 的结果。
  2. 如果 numberNaN 则返回 +0
  3. 如果 number+0-0+∞-∞ 则返回 number
  4. 返回计算 sign(numberfloor(abs(number)) 的结果。

ToInt32:(32 位有符号整数)

ToInt32 抽象操作将其参数转换为 在 -231231-1 闭区间内的 232 个整数中的任意一个。
Error creating thumbnail: Unable to save thumbnail to destination

此运算符功能如下所示:

  1. number 为对输入的参数调用 ToNumber 的结果。
  2. 如果 numberNaN+0-0+∞-∞ 则返回 +0
  3. posIntsign(numberfloor(abs(number)) 的结果。
  4. int32bitposInt modulo 232;也就是说,假如有一个数值类型的有限正整数 k ,它小于 232 ,那么 posIntk 在数学上可能相差 232 的整数倍。
  5. 如果 int32bit 大于或等于 231 则返回 int32bit-232 否则返回 int32bit
注:上面对 ToInt32 的定义中:
  • ToInt32 抽象操作是幂等的:对同一个值调用一次和调用两次这个操作会得到同样的结果。
  • 对于任意的 x 值,ToInt32(ToUint32(x)) 总是等价于 ToInt32(x)。(它延续了后者将 +∞-∞ 映射到 +0 的性质)
  • ToInt32 会将 -0 映射到 +0

ToUint32:(32 位无符号整数)

ToUint32 抽象操作将其参数转换为 在 0232-1 闭区间内的 232 个整数中的任意一个。
Error creating thumbnail: Unable to save thumbnail to destination

此运算符功能如下所示:

  1. number 为对输入的参数调用 ToNumber 的结果。
  2. 如果 numberNaN+0-0+∞-∞ 则返回 +0
  3. posIntsign(numberfloor(abs(number)) 的结果。
  4. int32bitposInt modulo 232;也就是说,假如有一个数值类型的有限正整数 k ,它小于 232 ,那么 posIntk 在数学上可能相差 232 的整数倍。
  5. 返回 int32bit
注:上面对 ToUint32 的定义中:
  • ToUint32ToInt32 之间唯有 第5步 不同。
  • ToUint32 抽象操作是幂等的:对同一个值调用一次和调用两次这个操作会得到同样的结果。
  • 对于任意的 x 值,ToUint32(ToInt32(x)) 总是等价于 ToUint32(x)。(它延续了后者将 +∞-∞ 映射到 +0 的性质)
  • ToUint32 会将 -0 映射到 +0

ToUint16:(16 位无符号整数)

ToUint16 抽象操作将其参数转换为 在 0216-1 闭区间内的 216 个整数中的任意一个。
Error creating thumbnail: Unable to save thumbnail to destination

此运算符功能如下所示:

  1. number 为对输入的参数调用 ToNumber 的结果。
  2. 如果 numberNaN+0-0+∞-∞ 则返回 +0
  3. posIntsign(numberfloor(abs(number)) 的结果。
  4. int16bitposInt modulo 216;也就是说,假如有一个数值类型的有限正整数 k ,它小于 216 ,那么 posIntk 在数学上可能相差 216 的整数倍。
  5. 返回 int16bit
注: 上面给出的 ToUint16 的定义中:
  • ToUint16ToUint32 之间唯一的不同是 第4步 中,216 取代了 232
  • ToUint16 会将 -0 映射为 +0

ToString

ToString 运算符根据下表将其参数转换为字符串类型的值:
Error creating thumbnail: Unable to save thumbnail to destination
输入类型 结果
未定义 "undefined"
空值 "null"
布尔值 如果参数是 true,那么结果为 "true"

如果参数是 false,那么结果为 "false"

数值 9.8.1
字符串 返回输入的参数(不转换)。
对象 应用下列步骤:
  1. primValueToPrimitive(输入参数, 暗示字符串类型)。
  2. 返回 ToString(primValue)。

对数值类型应用 ToString

ToString 抽象操作将数字 m 转换为字符串格式的给出如下所示:
Error creating thumbnail: Unable to save thumbnail to destination
  1. 如果 mNaN,返回字符串 "NaN"
  2. 如果 m+0-0,返回字符串 "0"
  3. 如果 m 小于零,返回连接 "-"ToString(-m) 的字符串。
  4. 如果 m 无限大,返回字符串 "Infinity"
  5. 否则,令 nks 皆为整数,且满足 k110k-1s < 10ks×10n-k 的数字值为 mk 足够小。注意 ks 的十进制位数。s 不能被 10 整除,且 s 的至少要求的有效数字位数不一定要被这些标准唯一确定。
    Error creating thumbnail: Unable to save thumbnail to destination
  6. 如果 kn21,返回由 ks 在十进制表示中的数字组成的字符串(有序的,开头没有零),后面连接 n-k"0" 字符。
  7. 如果 0 < n21,返回由 s 在十进制表示中的、最多 n 个有效数字组成的字符串,后面跟随一个小数点 ".",再后面是余下的 k-ns 在十进制表示中的数字。
  8. 如果 -6 < n0,返回由字符 "0" 组成的字符串,后面跟随一个小数点 ".",再后面是 -n"0" 字符,最后是 ks 在十进制表示中的数字。
  9. 否则,如果 k = 1,返回由单个数字 s 组成的字符串,后面跟随小写字母 "e",根据 n-1 是正或负,再后面是一个加号 "+" 或减号 "-" ,再往后是整数 abs(n-1) 的十进制表示(没有前置的零)。
  10. 返回由 s 在十进制表示中的、最多的有效数字组成的字符串,后面跟随一个小数点 ".",再后面是余下的是 k-1s 在十进制表示中的数字,再往后是小写字母 "e",根据 n-1 是正或负,再后面是一个加号 "+" 或减号 "-" ,再往后是整数 abs(n-1) 的十进制表示(没有前置的零)。
注:下面的评语可能对指导实现有用,但不是本标准的常规要求。
  • 如果 x 是除 -0 以外的任一数字值,那么 ToNumber(ToString(x)) 与 x 是完全相同的数字值。
  • s 至少要求的有效数字位数并非总是由 第5步 中所列的要求唯一确定。
注:对于那些提供了比上面的规则所要求的更精确的转换的实现,我们推荐下面这个步骤 5 的可选版本,作为指导:

否则,令 n, k, 和 s 是整数,使得 k ≥ 1, 10k-1s < 10ks×10n-k 的数字值是 m,且 k 足够小。如果有数倍于 s 的可能性,选择 s × 10n-k 最接近于 m 的值作为 s 的值。如果 s 有两个这样可能的值,选择是偶数的那个。要注意的是,ks 在十进制表示中的数字的个数,且 s 不被 10 整除。

注:ECMAScript 的实现者们可能会发现,David M 所写的关于浮点数进行二进制到十进制转换方面的文章和代码很有用:

Gay, David M. Correctly Rounded Binary-Decimal and Decimal-Binary
Conversions. Numerical Analysis Manuscript 90-10. AT&T Bell
Laboratories (Murray Hill, New Jersey). November 30, 1990. 在这里取得
http://cm.bell-labs.com/cm/cs/doc/90/4-10.ps.gz 。有关的代码在这里
http://cm.bell-labs.com/netlib/fp/dtoa.c.gz 还有
http://cm.bell-labs.com/netlib/fp/g_fmt.c.gz 。这些都可在众多的 netlib 镜像站点上找到。

ToObject

ToObject 抽象操作根据下表将其参数转换为对象类型的值:
Error creating thumbnail: Unable to save thumbnail to destination
输入类型 结果
未定义 抛出 TypeError 异常。
空值 抛出 TypeError 异常。
布尔值 创建一个新的 Boolean 对象,其 [[PrimitiveValue]] 属性被设为该参数的值。
数值 创建一个新的 Number 对象,其 [[PrimitiveValue]] 属性被设为该参数的值。
字符串 创建一个新的 String 对象,其 [[PrimitiveValue]] 属性被设为该参数的值。
对象 结果是输入的参数(不转换)。

CheckObjectCoercible

根据 表15 定义,抽象操作 CheckObjectCoercible 在其参数无法用 ToObject 转换成对象的情况下抛出一个异常:
Error creating thumbnail: Unable to save thumbnail to destination


表15 - CheckObjectCoercible 结果
输入类型 结果
未定义 抛出一个 TypeError 异常
空值 抛出一个 TypeError 异常
布尔值 返回
数值 返回
字符串 返回
对象 返回

IsCallable

根据 表16,抽象操作 IsCallable 确定其必须是 ECMAScript 语言值的参数是否是一个可调用对象:
Error creating thumbnail: Unable to save thumbnail to destination
表16 - IsCallable 结果
输入类型 结果
未定义 返回 false
空值 返回 false
布尔值 返回 false
数值 返回 false
字符串 返回 false
对象 如果参数对象包含一个 [[Call]] 内部方法,则返回 true,否则返回 false

SameValue 算法

内部严格比较操作 SameValue(x,y),xy 为 ECMAScript 语言中的值,需要产出 truefalse
Error creating thumbnail: Unable to save thumbnail to destination
Error creating thumbnail: Unable to save thumbnail to destination
Error creating thumbnail: Unable to save thumbnail to destination

比较过程如下:

  1. 如果 Type(x) 与 Type(y) 的结果不一致,返回 false,否则
  2. 如果 Type(x) 结果为 Undefined,返回 true
  3. 如果 Type(x) 结果为 Null,返回 true
  4. 如果 Type(x) 结果为 Number,则
    1. 如果 xNaN,且 y 也为 NaN,返回 true
    2. 如果 x+0y-0,返回 false
    3. 如果 x-0y+0,返回 false
    4. 如果 xy 为同一个数字,返回 true
    5. 返回 false
  5. 如果 Type(x) 结果为 String,如果 xy 为完全相同的字符序列(相同的长度和相同的字符对应相同的位置),返回 true,否则,返回 false
  6. 如果 Type(x) 结果为 Boolean,如果 xy 都为 truefalse,则返回 true,否则,返回 false
  7. 如果 xy 引用到同一个 Object 对象,返回 true,否则,返回 false