2.2 Operations that help implement coercion in the ECMAScript specification
The following sections describe the most important internal functions used by the ECMAScript specification to convert actual parameters to expected types.
For example, in TypeScript, we would write:
function isNaN(number: number) {
// ···
}
In the specification, this looks as follows (translated to JavaScript, so that it is easier to understand):
function isNaN(number) {
let num = ToNumber(number);
// ···
}
2.2.1 Converting to primitive types and objects
Whenever primitive types or objects are expected, the following conversion functions are used:
ToBoolean()
ToNumber()
ToBigInt()
ToString()
ToObject()
These internal functions have analogs in JavaScript that are very similar:
> Boolean(0)
false
> Boolean(1)
true
> Number('123')
123
After the introduction of bigints, which exists alongside numbers, the specification often uses ToNumeric()
where it previously used ToNumber()
. Read on for more information.
2.2.2 Converting to numeric types
At the moment, JavaScript has two built-in numeric types: number and bigint.
ToNumeric()
returns a numeric valuenum
. Its callers usually invoke a methodmthd
of the specification type ofnum
:Type(num)::mthd(···)
Among others, the following operations use
ToNumeric
:- Prefix and postfix
++
operator *
operator
ToInteger(x)
is used whenever a number without a fraction is expected. The range of the result is often restricted further afterwards.- It calls
ToNumber(x)
and removes the fraction (similar toMath.trunc()
). - Operations that use
ToInteger()
:Number.prototype.toString(radix?)
String.prototype.codePointAt(pos)
Array.prototype.slice(start, end)
- Etc.
- It calls
ToInt32()
,ToUint32()
coerce numbers to 32-bit integers and are used by bitwise operators (see tbl. 1).ToInt32()
: signed, range [−231, 231−1] (limits are included)ToUint32()
: unsigned (hence theU
), range [0, 232−1] (limits are included)
Operator | Left operand | Right operand | result type |
---|---|---|---|
<< | ToInt32() | ToUint32() | Int32 |
signed >> | ToInt32() | ToUint32() | Int32 |
unsigned >>> | ToInt32() | ToUint32() | Uint32 |
& , ^ , | | ToInt32() | ToUint32() | Int32 |
~ | — | ToInt32() | Int32 |
2.2.3 Converting to property keys
ToPropertyKey()
returns a string or a symbol and is used by:
- The bracket operator
[]
- Computed property keys in object literals
- The left-hand side of the
in
operator Object.defineProperty(_, P, _)
Object.fromEntries()
Object.getOwnPropertyDescriptor()
Object.prototype.hasOwnProperty()
Object.prototype.propertyIsEnumerable()
- Several methods of
Reflect
2.2.4 Converting to Array indices
ToLength()
is used (directly) mainly for string indices.- Helper function for
ToIndex()
- Range of result
l
: 0 ≤l
≤ 253−1
- Helper function for
ToIndex()
is used for Typed Array indices.- Main difference with
ToLength()
: throws an exception if argument is out of range. - Range of result
i
: 0 ≤i
≤ 253−1
- Main difference with
ToUint32()
is used for Array indices.- Range of result
i
: 0 ≤i
< 232−1 (the upper limit is excluded, to leave room for the.length
)
- Range of result
2.2.5 Converting to Typed Array elements
When we set the value of a Typed Array element, one of the following conversion functions is used:
ToInt8()
ToUint8()
ToUint8Clamp()
ToInt16()
ToUint16()
ToInt32()
ToUint32()
ToBigInt64()
ToBigUint64()