Skip to content

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 PreferredType argument. The operator ToPrimitive attempts to convert 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 favor 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 behavior of the [[DefaultValue]] method is defined by this
specification for all native ECMAScript objects (see section 8.6.2.5). If the return
value is of type Object or Reference, a runtime error is generated.

9.2 ToBoolean

The operator ToBoolean attempts to convert 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 attempts to convert 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 discussion 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>
<FF>
<VT>
<CR>
<LF>
StrNumericLiteral :::
StrDecimalLiteral
+ StrDecimalLiteral
- StrDecimalLiteral
HexIntegerLiteral
StrDecimalLiteral :::
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 (section 7.7.3):

  • A StringNumericLiteral may be preceded and/or followed by whitespace and/or line terminators.
  • A StringNumericLiteral may not use octal notation.
  • 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 whitespaceis 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 (section 7.7.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, ideally using IEEE 754 round-to-nearest mode, to a representable value of the number type.

  • The MV of StringNumericLiteral ::: (an empty character sequence) is 0.
  • The MV of StringNumericLiteral ::: StrWhiteSpace is 0.
  • The MV of StringNumericLiteral ::: StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt is the MV of StrNumericLiteral , no matter whether whitespace is present or not.
  • The MV of StrNumericLiteral ::: StrDecimalLiteral is the MV of StrDecimalLiteral .
  • The MV of StrNumericLiteral ::: + StrDecimalLiteral is the MV of StrDecimalLiteral .
  • The MV of StrNumericLiteral ::: - StrDecimalLiteral is the negative of the MV of StrDecimalLiteral . (Note that if the MV of StrDecimalLiteral is 0, the negative of this MV is also 0. The rounding rule described below handles the conversion of this signless mathematical zero to a floating-point +0 or − 0 as appropriate.)
  • The MV of StrNumericLiteral ::: HexIntegerLiteral is the MV of HexIntegerLiteral .
  • The MV of StrDecimalLiteral ::: Infinity is 1010000 (a value so large that it will round to + ∞).
  • The MV of StrDecimalLiteral ::: DecimalDigits . is the MV of DecimalDigits .
  • The MV of StrDecimalLiteral ::: 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 DecimalDigit s.
  • The MV of StrDecimalLiteral ::: DecimalDigits . ExponentPart is the MV of DecimalDigits times 10 e , where e is the MV of ExponentPart .
  • The MV of StrDecimalLiteral ::: DecimalDigits . DecimalDigits ExponentPart is (the MV of the first DecimalDigits plus (the MV of the second DecimalDigits times 10 n )) times 10 e , where n is the number of characters in the second DecimalDigit s and e is the MV of ExponentPart .
  • The MV of StrDecimalLiteral :::. DecimalDigits is the MV of DecimalDigits times 10 n , where n is the number of characters in DecimalDigit s.
  • The MV of StrDecimalLiteral :::. DecimalDigits ExponentPart is the MV of DecimalDigits times 10 e n , where n is the number of characters in DecimalDigit s and e is the MV of ExponentPart .
  • The MV of StrDecimalLiteral ::: DecimalDigits is the MV of DecimalDigits .
  • The MV of StrDecimalLiteral ::: DecimalDigits ExponentPart is the MV of DecimalDigits times 10 e , 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-whitespace 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 section 8.4), unless the literal includes a StrDecimalLiteral 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 (either 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 attempts to convert 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 that 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(5) − 232; otherwise return Result(5).

Discussion: Note that the ToInt32 operation is idempotent: if applied to a result that it produced, the second application leaves that value unchanged. Note also that 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.) Note that 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 that the mathematical difference of Result(3) and k is mathematically an integer multiple of 232.
  5. Return Result(4).

Discussion: Note that 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 that the mathematical difference of Result(3) and k is mathematically an integer multiple of 216.
  5. Return Result(4).

Discussion: 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 attempts to convert 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 discussion 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, 10 k 1 <= s < 10 k , the number value for s ⋅10 n 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 occurences 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 occurences 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 that if x is any number value other than − 0 , then ToNumber(ToString( x )) is exactly the same number value as x .

As noted, the least significant digit of s is not always uniquely determined by the requirements listed in step 5. The following specification for step 5 was considered, but not adopted:

(This paragraph is not part of the ECMAScript specification.) Let n , k , and s be be integers such that k ≥ 1, 10 k 1 <= s < 10 k , the number value for s ⋅10 n 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 ⋅10 n k is closest in value to m . If there are two such possible values of s , choose the one that is even.

While such a strategy is recommended to implementors, the actual rule is somewhat more permissive. Implementors of ECMAScript may find useful the paper and code written by David M. Gay for binary-todecimal conversion of floating-point numbers [Gay 1990].

9.9 ToObject

The operator ToObject attempts to convert its argument to a value of type Object according to the following table:

Input Type Result
Undefined Generate a runtime error.
Null Generate a runtime error.
Boolean Create a new Boolean object whose default value is the value of the boolean. See
section 15.6 for a description of Boolean objects.
Number Create a new Number object whose default value is the value of the number. See
section 15.7 for a description of Number objects.
String Create a new String object whose default value is the value of the string. See
section 15.5 for a description of String objects.
Object The result is the input argument (no conversion).