- 9. Type Conversion
-
The ECMAScript runtime system performs automatic type conversion as needed. To clarify the semantics of certain
constructs it is useful to define a set of conversion operators. These operators are not a part of the language; they
are defined here to aid the specification of the semantics of the language. The conversion operators are polymorphic;
that is, they can accept a value of any standard type, but not of type Reference, List, or Completion (the internal
types).
- 9.1 ToPrimitive
-
The operator ToPrimitive takes a Value argument and an optional argument PreferredType. The operator
ToPrimitive converts its value argument to a non-Object type. If an object is capable of converting to more than one
primitive type, it may use the optional hint PreferredType to favour that type. Conversion occurs according to
the following table:
| Input Type |
Result |
| Undefined |
The result equals the input argument (no conversion). |
| Null |
The result equals the input argument (no conversion). |
| Boolean |
The result equals the input argument (no conversion). |
| Number |
The result equals the input argument (no conversion). |
| String |
The result equals the input argument (no conversion). |
| Object |
Return a default value for the Object. The default value of an object is retrieved by calling the internal
[[DefaultValue]] method of the object, passing the optional hint PreferredType.
The behaviour of the [[DefaultValue]] method is defined by this specification for all
native ECMAScript objects (8.6.2.6). |
- 9.2 ToBoolean
-
The operator ToBoolean converts its argument to a value of type Boolean according to the following table:
| Input Type |
Result |
| Undefined |
false |
| Null |
false |
| Boolean |
The result equals the input argument (no conversion). |
| Number |
The result is false if the argument is +0, -0, or NaN; otherwise the result is true. |
| String |
The result is false if the argument is the empty string (its length is zero); otherwise the result is
true. |
| Object |
true |
- 9.3 ToNumber
-
The operator ToNumber converts its argument to a value of type Number according to the following table:
| Input Type |
Result |
| Undefined |
NaN |
| Null |
+0 |
| Boolean |
The result is 1 if the argument is true. The result is +0 if the argument is
false. |
| Number |
The result equals the input argument (no conversion). |
| String |
See grammar and note below. |
| Object |
Apply the following steps:
1. Call ToPrimitive(input argument, hint Number).
2. Call ToNumber(Result(1)).
3. Return Result(2).
|
- 9.3.1 ToNumber Applied to the String Type
-
ToNumber applied to strings applies the following grammar to the input string. If the grammar cannot interpret the
string as an expansion of StringNumericLiteral, then the result of ToNumber is NaN.
- StringNumericLiteral :::
- StrWhiteSpaceopt
StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt
- StrWhiteSpace :::
- StrWhiteSpaceChar StrWhiteSpaceopt
- StrWhiteSpaceChar :::
- <TAB>
<SP>
<NBSP>
<FF>
<VT>
<CR>
<LF>
<LS>
<PS>
<USP>
- 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 :::
- DecimalDigits
+ DecimalDigits
- DecimalDigits
- 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
Some differences should be noted between the syntax of a StringNumericLiteral and a NumericLiteral (see
7.8.3):
- A StringNumericLiteral may be preceded and/ or followed by white space and/ or line terminators.
- A StringNumericLiteral that is decimal may have any number of leading 0 digits.
- A StringNumericLiteral that is decimal may be preceded by + or - to
indicate its sign.
- A StringNumericLiteral that is empty or contains only white space is converted to +0.
The conversion of a string to a number value is similar overall to the determination of the number value for a
numeric literal (see 7.8.3), but some of the details are different, so the process for converting
a string numeric literal to a value of Number type is given here in full. This value is determined in two steps: first,
a mathematical value (MV) is derived from the string numeric literal; second, this mathematical value is rounded as
described below.
- The MV of StringNumericLiteral ::: [empty] is 0.
- The MV of StringNumericLiteral ::: StrWhiteSpace is 0.
- The MV of StringNumericLiteral ::: StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt
is the MV of StrNumericLiteral, no matter whether white space is present or not.
- The MV of StrNumericLiteral ::: StrDecimalLiteral is the MV of StrDecimalLiteral.
- The MV of StrNumericLiteral ::: HexIntegerLiteral is the MV of HexIntegerLiteral.
- The MV of StrDecimalLiteral ::: StrUnsignedDecimalLiteral is the MV of
StrUnsignedDecimalLiteral.
- The MV of StrDecimalLiteral::: + StrUnsignedDecimalLiteral is the MV of
StrUnsignedDecimalLiteral.
- The MV of StrDecimalLiteral::: - StrUnsignedDecimalLiteral is the negative of the
MV of StrUnsignedDecimalLiteral. (Note that if the MV of StrUnsignedDecimalLiteral is 0, the negative
of this MV is also 0. The rounding rule described below handles the conversion of this sign less mathematical zero
to a floating-point +0 or -0 as appropriate.)
- The MV of StrUnsignedDecimalLiteral::: Infinity is 1010000 (a value so large
that it will round to +∞ ).
- The MV of StrUnsignedDecimalLiteral::: DecimalDigits. is the MV of DecimalDigits. The MV of
StrUnsignedDecimalLiteral::: DecimalDigits. DecimalDigits is the MV of the first DecimalDigits plus (the
MV of the second DecimalDigits times 10-n ), where n is the number of characters in
the second DecimalDigits.
- The MV of StrUnsignedDecimalLiteral::: DecimalDigits. ExponentPart is the MV of DecimalDigits
times 10e, where e is the MV of ExponentPart.
- The MV of StrUnsignedDecimalLiteral::: DecimalDigits. DecimalDigits ExponentPart is (the MV of the first
DecimalDigits plus (the MV of the second DecimalDigits times 10-n )) times 10e,
where n is the number of characters in the second DecimalDigits and e is the MV of
ExponentPart.
- The MV of StrUnsignedDecimalLiteral:::. DecimalDigits is the MV of DecimalDigits times 10-n,
where n is the number of characters in DecimalDigits.
- The MV of StrUnsignedDecimalLiteral:::. DecimalDigits ExponentPart is the MV of DecimalDigits
times 10e-n, where n is the number of characters in DecimalDigits and e is
the MV of ExponentPart.
- The MV of StrUnsignedDecimalLiteral::: DecimalDigits is the MV of DecimalDigits.
- The MV of StrUnsignedDecimalLiteral::: DecimalDigits ExponentPart is the MV of DecimalDigits times
10e, where e is the MV of ExponentPart.
- The MV of DecimalDigits ::: DecimalDigit is the MV of DecimalDigit. The MV of
DecimalDigits ::: DecimalDigits DecimalDigit is (the MV of DecimalDigits times 10) plus the
MV of DecimalDigit.
- The MV of ExponentPart ::: ExponentIndicator SignedInteger is the MV of SignedInteger.
- The MV of SignedInteger ::: DecimalDigits is the MV of DecimalDigits.
- The MV of SignedInteger ::: + DecimalDigits is the MV of DecimalDigits.
- The MV of SignedInteger ::: - DecimalDigits is the negative of the MV of
DecimalDigits.
- The MV of DecimalDigit ::: 0 or of HexDigit ::: 0 is 0.
- The MV of DecimalDigit ::: 1 or of HexDigit ::: 1 is 1.
- The MV of DecimalDigit ::: 2 or of HexDigit ::: 2 is 2.
- The MV of DecimalDigit ::: 3 or of HexDigit ::: 3 is 3.
- The MV of DecimalDigit ::: 4 or of HexDigit ::: 4 is 4.
- The MV of DecimalDigit ::: 5 or of HexDigit ::: 5 is 5.
- The MV of DecimalDigit ::: 6 or of HexDigit ::: 6 is 6.
- The MV of DecimalDigit ::: 7 or of HexDigit ::: 7 is 7.
- The MV of DecimalDigit ::: 8 or of HexDigit ::: 8 is 8.
- The MV of DecimalDigit ::: 9 or of HexDigit ::: 9 is 9.
- The MV of HexDigit ::: a or of HexDigit ::: A is 10.
- The MV of HexDigit ::: b or of HexDigit ::: B is 11.
- The MV of HexDigit ::: c or of HexDigit ::: C is 12.
- The MV of HexDigit ::: d or of HexDigit ::: D is 13.
- The MV of HexDigit ::: e or of HexDigit ::: E is 14.
- The MV of HexDigit ::: f or of HexDigit ::: F is 15.
- The MV of HexIntegerLiteral ::: 0x HexDigit is the MV of HexDigit.
- The MV of HexIntegerLiteral ::: 0X HexDigit is the MV of HexDigit.
- The MV of HexIntegerLiteral ::: HexIntegerLiteral HexDigit is (the MV of
HexIntegerLiteral times 16) plus the MV of HexDigit.
Once the exact MV for a string numeric literal has been determined, it is then rounded to a value of the Number type.
If the MV is 0, then the rounded value is +0 unless the first non white space character in the string numeric literal is
'-', in which case the rounded value is -0. Otherwise, the rounded value must be the number value for the MV (in the
sense defined in 8.5), unless the literal includes a StrUnsignedDecimalLiteral and the
literal has more than 20 significant digits, in which case the number value may be either the number value for the MV of
a literal produced by replacing each significant digit after the 20th with a 0 digit or the number value for the MV of a
literal produced by replacing each significant digit after the 20th with a 0 digit and then incrementing the literal at
the 20th digit position. A digit is significant if it is not part of an ExponentPart and
- it is not 0; or
- there is a nonzero digit to its left and there is a nonzero digit, not in the ExponentPart, to its right.
- 9.4 ToInteger
-
The operator ToInteger converts its argument to an integral numeric value. This operator functions as follows:
1. Call ToNumber on the input argument.
2. If Result(1) is NaN, return +0.
3. If Result(1) is +0, -0, +∞, or -∞, return Result(1).
4. Compute sign(Result(1)) * floor(abs(Result(1))).
5. Return Result(4).
- 9.5 ToInt32: (Signed 32 Bit Integer)
-
The operator ToInt32 converts its argument to one of 232 integer values in the range -231
through 231-1, inclusive. This operator functions as follows:
1. Call ToNumber on the input argument.
2. If Result(1) is NaN, +0, -0, +∞, or -∞, return +0.
3. Compute sign(Result(1)) * floor(abs(Result(1))).
4. Compute Result(3) modulo 232 ; that is, a finite integer value k of Number type with positive sign and
less than 232 in magnitude such the mathematical difference of Result(3) and k is mathematically an integer
multiple of 232 .
5. If Result(4) is greater than or equal to 231 , return Result(4)-232 , otherwise return
Result(4).
NOTE
Given the above definition of ToInt32:
The ToInt32 operation is idempotent: if applied to a result that it produced, the second
application leaves that value unchanged.
ToInt32(ToUint32(x)) is equal to ToInt32(x) for all
values of x. (It is to preserve this latter property that +∞ and -∞ are mapped to +0.)
ToInt32 maps -0 to +0.
- 9.6 ToUint32: (Unsigned 32 Bit Integer)
-
The operator ToUint32 converts its argument to one of 232 integer values in the range 0 through 232-1,
inclusive. This operator functions as follows:
1. Call ToNumber on the input argument.
2. If Result(1) is NaN, +0, -0, +∞, or -∞, return +0.
3. Compute sign(Result(1)) * floor(abs(Result(1))).
4. Compute Result(3) modulo 232 ; that is, a finite integer value k of Number type with positive sign and
less than 232 in magnitude such the mathematical difference of Result(3) and k is mathematically an integer
multiple of 232 .
5. Return Result(4).
NOTE
Given the above definition of ToUInt32:
Step 5 is the only difference between ToUint32 and ToInt32.
The ToUint32 operation is idempotent: if applied to a result that it produced, the second
application leaves that value unchanged.
ToUint32(ToInt32(x)) is equal to ToUint32(x) for
all values of x. (It is to preserve this latter property that +∞ and -∞ are mapped to +0.)
ToUint32 maps -0 to +0.
- 9.7 ToUint16: (Unsigned 16 Bit Integer)
-
The operator ToUint16 converts its argument to one of 216 integer values in the range 0 through 216-1,
inclusive. This operator functions as follows:
1. Call ToNumber on the input argument.
2. If Result(1) is NaN, +0, -0, +∞, or -∞, return +0.
3. Compute sign(Result(1)) * floor(abs(Result(1))).
4. Compute Result(3) modulo 216 ; that is, a finite integer value k of Number type with positive
sign and less than 216 in magnitude such the mathematical difference of Result(3) and k is
mathematically an integer multiple of 216 .
5. Return Result(4).
NOTE
Given the above definition of ToUint16:
The substitution of 216 for 232 in step 4 is the only difference between
ToUint32 and ToUint16.
ToUint16 maps -0 to +0.
- 9.8 ToString
-
The operator ToString converts its argument to a value of type String according to the following table:
| Input Type |
Result |
| Undefined |
"undefined" |
| Null |
"null" |
| Boolean |
If the argument is true, then the result is "true".
If the argument is false, then the result is "false". |
| Number |
See note below. |
| String |
Return the input argument (no conversion) |
| Object |
Apply the following steps:
1. Call ToPrimitive(input argument, hint String).
2. Call ToString(Result(1)).
3. Return Result(2). |
- 9.8.1 ToString Applied to the Number Type
-
The operator ToString converts a number m to string format as follows:
1. If m is NaN, return the string "NaN".
2. If m is +0 or -0, return the string "0".
3. If m is less than zero, return the string concatenation of the string "-" and
ToString(-m).
4. If m is infinity, return the string "Infinity".
5. Otherwise, let n, k, and s be integers such that k >= 1, 10k-1<= s
<10k, the number value for s * 10n-k is m, and k is as
small as possible. Note that k is the number of digits in the decimal representation of s, that s
is not divisible by 10, and that the least significant digit of s is not necessarily uniquely determined by these
criteria.
6. If k <= n <= 21, return the string consisting of the k digits of the decimal representation
of s (in order, with no leading zeroes), followed by n k occurrences of the character '0'.
7. If 0 < n <= 21, return the string consisting of the most significant n digits of the decimal representation
of s, followed by a decimal point '. ', followed by the remaining k-n digits of the decimal
representation of s.
8. If -6 <n <= 0, return the string consisting of the character '0', followed by a decimal point '. ', followed by
-n occurrences of the character '0', followed by the k digits of the decimal representation of s.
9. Otherwise, if k = 1, return the string consisting of the single digit of s, followed by lowercase
character 'e', followed by a plus sign '+ ' or minus sign '-' according to whether n-1 is positive or negative,
followed by the decimal representation of the integer abs(n-1) (with no leading zeros).
10. Return the string consisting of the most significant digit of the decimal representation of s, followed by a
decimal point '. ', followed by the remaining k-1 digits of the decimal representation of s, followed by the lowercase
character 'e', followed by a plus sign '+ ' or minus sign '-' according to whether n-1 is positive or negative, followed
by the decimal representation of the integer abs(n-1) (with no leading zeros).
NOTE
The following observations may be useful as guidelines for implementations, but are not part of the normative
requirements of this Standard:
If x is any number value other than -0, then ToNumber(ToString(x))
is exactly the same number value as x.
The least significant digit of s is not always uniquely determined by the requirements listed in step 5.
For implementations that provide more accurate conversions than required by the rules above, it is recommended
that the following alternative version of step 5 be used as a guideline:
Otherwise, let n, k, and s be integers such that k >= 1, 10k-1 <= s <10k
, the number value for s * 10n-k is m, and k is as small as possible. If there are multiple possibilities for
s, choose the value of s for which s * 10n-k is closest in value to m. If there are two such possible values
of s, choose the one that is even. Note that k is the number of digits in the decimal representation of s and that s is
not divisible by 10.
Implementors of ECMAScript may find useful the paper and code written by David M. Gay for binary-to-decimal
conversion of floating-point numbers:
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. Available as
http://cm.bell-labs.com/cm/cs/doc/90/4-10.ps.gz.
Associated code available as http://cm.bell-labs.com/netlib/fp/dtoa.c.gz
and as http://cm.bell-labs.com/netlib/fp/g_fmt.c.gz
and may also be found at the various netlib mirror sites.
- 9.9 ToObject
-
The operator ToObject converts its argument to a value of type Object according to the following
table:
| Input Type |
Result |
| Undefined |
Throw a TypeError exception. |
| Null |
Throw a TypeError exception. |
| Boolean |
Create a new Boolean object whose [[value]] property is set to the value of the boolean. See
15.6 for a description of Boolean objects. |
| Number |
Create a new Number object whose [[value]] property is set to the value of the number. See
15.7 for a description of Number objects. |
| String |
Create a new String object whose [[value]] property is set to the value of the string. See
15.5 for a description of String objects. |
| Object |
The result is the input argument (no conversion). |