Skip to content

6 ECMAScript Data Types and Values

Algorithms within this specification manipulate values each of which has an associated type. The possible value types are exactly those defined in this clause. Types are further subclassified into ECMAScript language types and specification types.

Within this specification, the notation “Type(x)” is used as shorthand for “the type of x” where “type” refers to the ECMAScript language and specification types defined in this clause. When the term “empty” is used as if it was naming a value, it is equivalent to saying “no value of any type”.

6.1 ECMAScript Language Types

An ECMAScript language type corresponds to values that are directly manipulated by an ECMAScript programmer using the ECMAScript language. The ECMAScript language types are Undefined, Null, Boolean, String, Symbol, Number, BigInt, and Object. An ECMAScript language value is a value that is characterized by an ECMAScript language type.

6.1.1 The Undefined Type

The Undefined type has exactly one value, called undefined. Any variable that has not been assigned a value has the value undefined.

6.1.2 The Null Type

The Null type has exactly one value, called null.

6.1.3 The Boolean Type

The Boolean type represents a logical entity having two values, called true and false.

6.1.4 The String Type

The String type is the set of all ordered sequences of zero or more 16-bit unsigned integer values (“elements”) up to a maximum length of 253 - 1 elements. The String type is generally used to represent textual data in a running ECMAScript program, in which case each element in the String is treated as a UTF-16 code unit value. Each element is regarded as occupying a position within the sequence. These positions are indexed with nonnegative integers. The first element (if any) is at index 0, the next element (if any) at index 1, and so on. The length of a String is the number of elements (i.e., 16-bit values) within it. The empty String has length zero and therefore contains no elements.

ECMAScript operations that do not interpret String contents apply no further semantics. Operations that do interpret String values treat each element as a single UTF-16 code unit. However, ECMAScript does not restrict the value of or relationships between these code units, so operations that further interpret String contents as sequences of Unicode code points encoded in UTF-16 must account for ill-formed subsequences. Such operations apply special treatment to every code unit with a numeric value in the inclusive range 0xD800 to 0xDBFF (defined by the Unicode Standard as a leading surrogate, or more formally as a high-surrogate code unit) and every code unit with a numeric value in the inclusive range 0xDC00 to 0xDFFF (defined as a trailing surrogate, or more formally as a low-surrogate code unit) using the following rules:

The function String.prototype.normalize (see 21.1.3.13) can be used to explicitly normalize a String value. String.prototype.localeCompare (see 21.1.3.10) internally normalizes String values, but no other operations implicitly normalize the strings upon which they operate. Only operations that are explicitly specified to be language or locale sensitive produce language-sensitive results.

Note

The rationale behind this design was to keep the implementation of Strings as simple and high-performing as possible. If ECMAScript source text is in Normalized Form C, string literals are guaranteed to also be normalized, as long as they do not contain any Unicode escape sequences.

In this specification, the phrase "the string-concatenation of A, B, ..." (where each argument is a String value, a code unit, or a sequence of code units) denotes the String value whose sequence of code units is the concatenation of the code units (in order) of each of the arguments (in order).

6.1.5 The Symbol Type

The Symbol type is the set of all non-String values that may be used as the key of an Object property (6.1.7).

Each possible Symbol value is unique and immutable.

Each Symbol value immutably holds an associated value called [[Description]] that is either undefined or a String value.

6.1.5.1 Well-Known Symbols

Well-known symbols are built-in Symbol values that are explicitly referenced by algorithms of this specification. They are typically used as the keys of properties whose values serve as extension points of a specification algorithm. Unless otherwise specified, well-known symbols values are shared by all realms (8.2).

Within this specification a well-known symbol is referred to by using a notation of the form @@name, where “name” is one of the values listed in Table 1.

Specification Name [[Description]] Value and Purpose
@@asyncIterator "Symbol.asyncIterator" A method that returns the default AsyncIterator for an object. Called by the semantics of the for-await-of statement.
@@hasInstance "Symbol.hasInstance" A method that determines if a constructor object recognizes an object as one of the constructor's instances. Called by the semantics of the instanceof operator.
@@isConcatSpreadable "Symbol.isConcatSpreadable" A Boolean valued property that if true indicates that an object should be flattened to its array elements by Array.prototype.concat.
@@iterator "Symbol.iterator" A method that returns the default Iterator for an object. Called by the semantics of the for-of statement.
@@match "Symbol.match" A regular expression method that matches the regular expression against a string. Called by the String.prototype.match method.
@@matchAll "Symbol.matchAll" A regular expression method that returns an iterator, that yields matches of the regular expression against a string. Called by the String.prototype.matchAll method.
@@replace "Symbol.replace" A regular expression method that replaces matched substrings of a string. Called by the String.prototype.replace method.
@@search "Symbol.search" A regular expression method that returns the index within a string that matches the regular expression. Called by the String.prototype.search method.
@@species "Symbol.species" A function valued property that is the constructor function that is used to create derived objects.
@@split "Symbol.split" A regular expression method that splits a string at the indices that match the regular expression. Called by the String.prototype.split method.
@@toPrimitive "Symbol.toPrimitive" A method that converts an object to a corresponding primitive value. Called by the ToPrimitive abstract operation.
@@toStringTag "Symbol.toStringTag" A String valued property that is used in the creation of the default string description of an object. Accessed by the built-in method Object.prototype.toString.
@@unscopables "Symbol.unscopables" An object valued property whose own and inherited property names are property names that are excluded from the with environment bindings of the associated object.

6.1.6 Numeric Types

ECMAScript has two built-in numeric types: Number and BigInt. In this specification, every numeric type T contains a multiplicative identity value denoted T::unit. The specification types also have the following abstract operations, likewise denoted T::op for a given operation with specification name op. All argument types are T. The "Result" column shows the return type, along with an indication if it is possible for some invocations of the operation to return an abrupt completion.

Invocation Synopsis Example source Invoked by the Evaluation semantics of ... Result
T::unaryMinus(x) -x Unary - Operator T
T::bitwiseNOT(x) ~x Bitwise NOT Operator ( ~ ) T
T::exponentiate(x, y) x ** y Exponentiation Operator and Math.pow ( base, exponent ) T, may throw RangeError
T::multiply(x, y) x * y Multiplicative Operators T
T::divide(x, y) x / y Multiplicative Operators T, may throw RangeError
T::remainder(x, y) x % y Multiplicative Operators T, may throw RangeError
T::add(x, y) x ++
++ x
x + y
Postfix Increment Operator, Prefix Increment Operator, and The Addition Operator ( + ) T
T::subtract(x, y) x --
-- x
x - y
Postfix Decrement Operator, Prefix Decrement Operator, and The Subtraction Operator ( - ) T
T::leftShift(x, y) x << y The Left Shift Operator ( << ) T
T::signedRightShift(x, y) x >> y The Signed Right Shift Operator ( >> ) T
T::unsignedRightShift(x, y) x >>> y The Unsigned Right Shift Operator ( >>> ) T, may throw TypeError
T::lessThan(x, y) x < y
x > y
x <= y
x >= y
Relational Operators, via Abstract Relational Comparison Boolean or undefined (for unordered inputs)
T::equal(x, y) x == y
x != y
x === y
x !== y
Equality Operators, via Strict Equality Comparison Boolean
T::sameValue(x, y) Object internal methods, via SameValue ( x, y ), to test exact value equality Boolean
T::sameValueZero(x, y) Array, Map, and Set methods, via SameValueZero ( x, y ), to test value equality ignoring differences among members of the zero cohort (e.g., -0 and +0) Boolean
T::bitwiseAND(x, y) x & y Binary Bitwise Operators T
T::bitwiseXOR(x, y) x ^ y Binary Bitwise Operators T
T::bitwiseOR(x, y) x | y Binary Bitwise Operators T
T::toString(x) String(x) Many expressions and built-in functions, via ToString ( argument ) String

The T::unit value and T::op operations are not a part of the ECMAScript language; they are defined here solely to aid the specification of the semantics of the ECMAScript language. Other abstract operations are defined throughout this specification.

Because the numeric types are in general not convertible without loss of precision or truncation, the ECMAScript language provides no implicit conversion among these types. Programmers must explicitly call Number and BigInt functions to convert among types when calling a function which requires another type.

Note

The first and subsequent editions of ECMAScript have provided, for certain operators, implicit numeric conversions that could lose precision or truncate. These legacy implicit conversions are maintained for backward compatibility, but not provided for BigInt in order to minimize opportunity for programmer error, and to leave open the option of generalized value types in a future edition.

6.1.6.1 The Number Type

The Number type has exactly 18437736874454810627 (that is, 264 - 253 + 3) values, representing the double-precision 64-bit format IEEE 754-2019 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic, except that the 9007199254740990 (that is, 253 - 2) distinct “Not-a-Number” values of the IEEE Standard are represented in ECMAScript as a single special NaN value. (Note that the NaN value is produced by the program expression NaN.) In some implementations, external code might be able to detect a difference between various Not-a-Number values, but such behaviour is implementation-dependent; to ECMAScript code, all NaN values are indistinguishable from each other.

Note

The bit pattern that might be observed in an ArrayBuffer (see 24.1) or a SharedArrayBuffer (see 24.2) after a Number value has been stored into it is not necessarily the same as the internal representation of that Number value used by the ECMAScript implementation.

There are two other special values, called positive Infinity and negative Infinity. For brevity, these values are also referred to for expository purposes by the symbols +∞ and -∞, respectively. (Note that these two infinite Number values are produced by the program expressions +Infinity (or simply Infinity) and -Infinity.)

The other 18437736874454810624 (that is, 264 - 253) values are called the finite numbers. Half of these are positive numbers and half are negative numbers; for every finite positive Number value there is a corresponding negative value having the same magnitude.

Note that there is both a positive zero and a negative zero. For brevity, these values are also referred to for expository purposes by the symbols +0 and -0, respectively. (Note that these two different zero Number values are produced by the program expressions +0 (or simply 0) and -0.)

The 18437736874454810622 (that is, 264 - 253 - 2) finite nonzero values are of two kinds:

18428729675200069632 (that is, 264 - 254) of them are normalized, having the form

s × m × 2e

where s is +1 or -1, m is a positive mathematical integer less than 253 but not less than 252, and e is a mathematical integer ranging from -1074 to 971, inclusive.

The remaining 9007199254740990 (that is, 253 - 2) values are denormalized, having the form

s × m × 2e

where s is +1 or -1, m is a positive mathematical integer less than 252, and e is -1074.

Note that all the positive and negative mathematical integers whose magnitude is no greater than 253 are representable in the Number type (indeed, the mathematical integer 0 has two representations, +0 and -0).

A finite number has an odd significand if it is nonzero and the mathematical integer m used to express it (in one of the two forms shown above) is odd. Otherwise, it has an even significand.

In this specification, the phrase “the Number value for x” where x represents an exact real mathematical quantity (which might even be an irrational number such as π) means a Number value chosen in the following manner. Consider the set of all finite values of the Number type, with -0 removed and with two additional values added to it that are not representable in the Number type, namely 21024 (which is +1 × 253 × 2971) and -21024 (which is -1 × 253 × 2971). Choose the member of this set that is closest in value to x. If two values of the set are equally close, then the one with an even significand is chosen; for this purpose, the two extra values 21024 and -21024 are considered to have even significands. Finally, if 21024 was chosen, replace it with +∞; if -21024 was chosen, replace it with -∞; if +0 was chosen, replace it with -0 if and only if x is less than zero; any other chosen value is used unchanged. The result is the Number value for x. (This procedure corresponds exactly to the behaviour of the IEEE 754-2019 roundTiesToEven mode.)

Some ECMAScript operators deal only with integers in specific ranges such as -231 through 231 - 1, inclusive, or in the range 0 through 216 - 1, inclusive. These operators accept any value of the Number type but first convert each such value to an integer value in the expected range. See the descriptions of the numeric conversion operations in 7.1.

The Number::unit value is 1.

6.1.6.1.1 Number::unaryMinus ( x )

  1. If x is NaN, return NaN.
  2. Return the result of negating x; that is, compute a Number with the same magnitude but opposite sign.

6.1.6.1.2 Number::bitwiseNOT ( x )

  1. Let oldValue be ! ToInt32(x).
  2. Return the result of applying bitwise complement to oldValue. The result is a signed 32-bit integer.

6.1.6.1.3 Number::exponentiate ( base, exponent )

Returns an implementation-dependent approximation of the result of raising base to the power exponent.

  • If exponent is NaN, the result is NaN.
  • If exponent is +0, the result is 1, even if base is NaN.
  • If exponent is -0, the result is 1, even if base is NaN.
  • If base is NaN and exponent is nonzero, the result is NaN.
  • If abs(base) > 1 and exponent is +∞, the result is +∞.
  • If abs(base) > 1 and exponent is -∞, the result is +0.
  • If abs(base) is 1 and exponent is +∞, the result is NaN.
  • If abs(base) is 1 and exponent is -∞, the result is NaN.
  • If abs(base) < 1 and exponent is +∞, the result is +0.
  • If abs(base) < 1 and exponent is -∞, the result is +∞.
  • If base is +∞ and exponent > 0, the result is +∞.
  • If base is +∞ and exponent < 0, the result is +0.
  • If base is -∞ and exponent > 0 and exponent is an odd integer, the result is -∞.
  • If base is -∞ and exponent > 0 and exponent is not an odd integer, the result is +∞.
  • If base is -∞ and exponent < 0 and exponent is an odd integer, the result is -0.
  • If base is -∞ and exponent < 0 and exponent is not an odd integer, the result is +0.
  • If base is +0 and exponent > 0, the result is +0.
  • If base is +0 and exponent < 0, the result is +∞.
  • If base is -0 and exponent > 0 and exponent is an odd integer, the result is -0.
  • If base is -0 and exponent > 0 and exponent is not an odd integer, the result is +0.
  • If base is -0 and exponent < 0 and exponent is an odd integer, the result is -∞.
  • If base is -0 and exponent < 0 and exponent is not an odd integer, the result is +∞.
  • If base < 0 and base is finite and exponent is finite and exponent is not an integer, the result is NaN.
Note

The result of base ** exponent when base is 1 or -1 and exponent is +Infinity or -Infinity differs from IEEE 754-2019. The first edition of ECMAScript specified a result of NaN for this operation, whereas later versions of IEEE 754-2019 specified 1. The historical ECMAScript behaviour is preserved for compatibility reasons.

6.1.6.1.4 Number::multiply ( x, y )

The * MultiplicativeOperator performs multiplication, producing the product of x and y. Multiplication is commutative. Multiplication is not always associative in ECMAScript, because of finite precision.

The result of a floating-point multiplication is governed by the rules of IEEE 754-2019 binary double-precision arithmetic:

  • If either operand is NaN, the result is NaN.
  • The sign of the result is positive if both operands have the same sign, negative if the operands have different signs.
  • Multiplication of an infinity by a zero results in NaN.
  • Multiplication of an infinity by an infinity results in an infinity. The sign is determined by the rule already stated above.
  • Multiplication of an infinity by a finite nonzero value results in a signed infinity. The sign is determined by the rule already stated above.
  • In the remaining cases, where neither an infinity nor NaN is involved, the product is computed and rounded to the nearest representable value using IEEE 754-2019 roundTiesToEven mode. If the magnitude is too large to represent, the result is then an infinity of appropriate sign. If the magnitude is too small to represent, the result is then a zero of appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754-2019.

6.1.6.1.5 Number::divide ( x, y )

The / MultiplicativeOperator performs division, producing the quotient of x and y. x is the dividend and y is the divisor. ECMAScript does not perform integer division. The operands and result of all division operations are double-precision floating-point numbers. The result of division is determined by the specification of IEEE 754-2019 arithmetic:

  • If either operand is NaN, the result is NaN.
  • The sign of the result is positive if both operands have the same sign, negative if the operands have different signs.
  • Division of an infinity by an infinity results in NaN.
  • Division of an infinity by a zero results in an infinity. The sign is determined by the rule already stated above.
  • Division of an infinity by a nonzero finite value results in a signed infinity. The sign is determined by the rule already stated above.
  • Division of a finite value by an infinity results in zero. The sign is determined by the rule already stated above.
  • Division of a zero by a zero results in NaN; division of zero by any other finite value results in zero, with the sign determined by the rule already stated above.
  • Division of a nonzero finite value by a zero results in a signed infinity. The sign is determined by the rule already stated above.
  • In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the quotient is computed and rounded to the nearest representable value using IEEE 754-2019 roundTiesToEven mode. If the magnitude is too large to represent, the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of the appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754-2019.

6.1.6.1.6 Number::remainder ( n, d )

The % MultiplicativeOperator yields the remainder of its operands from an implied division; n is the dividend and d is the divisor.

Note

In C and C++, the remainder operator accepts only integral operands; in ECMAScript, it also accepts floating-point operands.

The result of a floating-point remainder operation as computed by the % operator is not the same as the “remainder” operation defined by IEEE 754-2019. The IEEE 754-2019 “remainder” operation computes the remainder from a rounding division, not a truncating division, and so its behaviour is not analogous to that of the usual integer remainder operator. Instead the ECMAScript language defines % on floating-point operations to behave in a manner analogous to that of the Java integer remainder operator; this may be compared with the C library function fmod.

The result of an ECMAScript floating-point remainder operation is determined by the rules of IEEE arithmetic:

  • If either operand is NaN, the result is NaN.
  • The sign of the result equals the sign of the dividend.
  • If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.
  • If the dividend is finite and the divisor is an infinity, the result equals the dividend.
  • If the dividend is a zero and the divisor is nonzero and finite, the result is the same as the dividend.
  • In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the floating-point remainder r from a dividend n and a divisor d is defined by the mathematical relation r = n - (d × q) where q is an integer that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d. r is computed and rounded to the nearest representable value using IEEE 754-2019 roundTiesToEven mode.

6.1.6.1.7 Number::add ( x, y )

The + operator performs addition when applied to x and y, producing the sum of the operands.

Addition is a commutative operation, but not always associative.

The result of an addition is determined using the rules of IEEE 754-2019 binary double-precision arithmetic:

  • If either operand is NaN, the result is NaN.
  • The sum of two infinities of opposite sign is NaN.
  • The sum of two infinities of the same sign is the infinity of that sign.
  • The sum of an infinity and a finite value is equal to the infinite operand.
  • The sum of two negative zeroes is -0. The sum of two positive zeroes, or of two zeroes of opposite sign, is +0.
  • The sum of a zero and a nonzero finite value is equal to the nonzero operand.
  • The sum of two nonzero finite values of the same magnitude and opposite sign is +0.
  • In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, and the operands have the same sign or have different magnitudes, the sum is computed and rounded to the nearest representable value using IEEE 754-2019 roundTiesToEven mode. If the magnitude is too large to represent, the operation overflows and the result is then an infinity of appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754-2019.

6.1.6.1.8 Number::subtract ( x, y )

The - operator performs subtraction when applied to two operands of numeric type, producing the difference of its operands; x is the minuend and y is the subtrahend. It is always the case that x - y produces the same result as x + (-y).

The result of - operator is then x + (-y).

6.1.6.1.9 Number::leftShift ( x, y )

  1. Let lnum be ! ToInt32(x).
  2. Let rnum be ! ToUint32(y).
  3. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  4. Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer.

6.1.6.1.10 Number::signedRightShift ( x, y )

  1. Let lnum be ! ToInt32(x).
  2. Let rnum be ! ToUint32(y).
  3. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  4. Return the result of performing a sign-extending right shift of lnum by shiftCount bits. The most significant bit is propagated. The result is a signed 32-bit integer.

6.1.6.1.11 Number::unsignedRightShift ( x, y )

  1. Let lnum be ! ToUint32(x).
  2. Let rnum be ! ToUint32(y).
  3. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  4. Return the result of performing a zero-filling right shift of lnum by shiftCount bits. Vacated bits are filled with zero. The result is an unsigned 32-bit integer.

6.1.6.1.12 Number::lessThan ( x, y )

  1. If x is NaN, return undefined.
  2. If y is NaN, return undefined.
  3. If x and y are the same Number value, return false.
  4. If x is +0 and y is -0, return false.
  5. If x is -0 and y is +0, return false.
  6. If x is +∞, return false.
  7. If y is +∞, return true.
  8. If y is -∞, return false.
  9. If x is -∞, return true.
  10. If the mathematical value of x is less than the mathematical value of y—note that these mathematical values are both finite and not both zero—return true. Otherwise, return false.

6.1.6.1.13 Number::equal ( x, y )

  1. If x is NaN, return false.
  2. If y is NaN, return false.
  3. If x is the same Number value as y, return true.
  4. If x is +0 and y is -0, return true.
  5. If x is -0 and y is +0, return true.
  6. Return false.

6.1.6.1.14 Number::sameValue ( x, y )

  1. If x is NaN and y is NaN, return true.
  2. If x is +0 and y is -0, return false.
  3. If x is -0 and y is +0, return false.
  4. If x is the same Number value as y, return true.
  5. Return false.

6.1.6.1.15 Number::sameValueZero ( x, y )

  1. If x is NaN and y is NaN, return true.
  2. If x is +0 and y is -0, return true.
  3. If x is -0 and y is +0, return true.
  4. If x is the same Number value as y, return true.
  5. Return false.

6.1.6.1.16 NumberBitwiseOp ( op, x, y )

  1. Let lnum be ! ToInt32(x).
  2. Let rnum be ! ToInt32(y).
  3. Return the result of applying the bitwise operator op to lnum and rnum. The result is a signed 32-bit integer.

6.1.6.1.17 Number::bitwiseAND ( x, y )

  1. Return NumberBitwiseOp(&, x, y).

6.1.6.1.18 Number::bitwiseXOR ( x, y )

  1. Return NumberBitwiseOp(^, x, y).

6.1.6.1.19 Number::bitwiseOR ( x, y )

  1. Return NumberBitwiseOp(|, x, y).

6.1.6.1.20 Number::toString ( x )

The abstract operation Number::toString converts a Number x to String format as follows:

  1. If x is NaN, return the String "NaN".
  2. If x is +0 or -0, return the String "0".
  3. If x is less than zero, return the string-concatenation of "-" and ! Number::toString(-x).
  4. If x is +∞, return the String "Infinity".
  5. Otherwise, let n, k, and s be integers such that k ≥ 1, 10k - 1s < 10k, the Number value for ℝ(s) × 10ℝ(n) - ℝ(k) is x, 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 kn ≤ 21, return the string-concatenation of:
    • the code units of the k digits of the decimal representation of s (in order, with no leading zeroes)
    • n - k occurrences of the code unit 0x0030 (DIGIT ZERO)
  7. If 0 < n ≤ 21, return the string-concatenation of:
    • the code units of the most significant n digits of the decimal representation of s
    • the code unit 0x002E (FULL STOP)
    • the code units of the remaining k - n digits of the decimal representation of s
  8. If -6 < n ≤ 0, return the string-concatenation of:
    • the code unit 0x0030 (DIGIT ZERO)
    • the code unit 0x002E (FULL STOP)
    • -n occurrences of the code unit 0x0030 (DIGIT ZERO)
    • the code units of the k digits of the decimal representation of s
  9. Otherwise, if k = 1, return the string-concatenation of:
    • the code unit of the single digit of s
    • the code unit 0x0065 (LATIN SMALL LETTER E)
    • the code unit 0x002B (PLUS SIGN) or the code unit 0x002D (HYPHEN-MINUS) according to whether n - 1 is positive or negative
    • the code units of the decimal representation of the integer abs(n - 1) (with no leading zeroes)
  10. Return the string-concatenation of:
    • the code units of the most significant digit of the decimal representation of s
    • the code unit 0x002E (FULL STOP)
    • the code units of the remaining k - 1 digits of the decimal representation of s
    • the code unit 0x0065 (LATIN SMALL LETTER E)
    • the code unit 0x002B (PLUS SIGN) or the code unit 0x002D (HYPHEN-MINUS) according to whether n - 1 is positive or negative
    • the code units of the decimal representation of the integer abs(n - 1) (with no leading zeroes)
Note 1

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.
Note 2

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:

5. Otherwise, let n, k, and s be integers such that k ≥ 1, 10k - 1s < 10k, the Number value for ℝ(s) × 10ℝ(n) - ℝ(k) is x, 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 ℝ(x). 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.
Note 3

Implementers 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://ampl.com/REFS/abstracts.html#rounding. Associated code available as
http://netlib.sandia.gov/fp/dtoa.c and as
http://netlib.sandia.gov/fp/g_fmt.c and may also be found at the various netlib mirror sites.

6.1.6.2 The BigInt Type

The BigInt type represents a mathematical integer value. The value may be any size and is not limited to a particular bit-width. Generally, where not otherwise noted, operations are designed to return exact mathematically-based answers. For binary operations, BigInts act as two's complement binary strings, with negative numbers treated as having bits set infinitely to the left.

The BigInt::unit value is 1n.

6.1.6.2.1 BigInt::unaryMinus ( x )

  1. If x is 0n, return 0n.
  2. Return the BigInt value that represents the mathematical value of negating x.

6.1.6.2.2 BigInt::bitwiseNOT ( x )

The abstract operation BigInt::bitwiseNOT with an argument x of type BigInt returns the one's complement of x; that is, -x - 1.

6.1.6.2.3 BigInt::exponentiate ( base, exponent )

  1. If exponent < 0n, throw a RangeError exception.
  2. If base is 0n and exponent is 0n, return 1n.
  3. Return the BigInt value that represents the mathematical value of base raised to the power exponent.

6.1.6.2.4 BigInt::multiply ( x, y )

The abstract operation BigInt::multiply with two arguments x and y of type BigInt returns the BigInt value that represents the result of multiplying x and y.

Note
Even if the result has a much larger bit width than the input, the exact mathematical answer is given.

6.1.6.2.5 BigInt::divide ( x, y )

  1. If y is 0n, throw a RangeError exception.
  2. Let quotient be the mathematical value of x divided by y.
  3. Return the BigInt value that represents quotient rounded towards 0 to the next integral value.

6.1.6.2.6 BigInt::remainder ( n, d )

  1. If d is 0n, throw a RangeError exception.
  2. If n is 0n, return 0n.
  3. Let r be the BigInt defined by the mathematical relation r = n - (d × q) where q is a BigInt that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d.
  4. Return r.
Note
The sign of the result equals the sign of the dividend.

6.1.6.2.7 BigInt::add ( x, y )

The abstract operation BigInt::add with two arguments x and y of type BigInt returns the BigInt value that represents the sum of x and y.

6.1.6.2.8 BigInt::subtract ( x, y )

The abstract operation BigInt::subtract with two arguments x and y of type BigInt returns the BigInt value that represents the difference x minus y.

6.1.6.2.9 BigInt::leftShift ( x, y )

The abstract operation BigInt::leftShift with two arguments x and y of type BigInt performs the following steps:

  1. If y < 0n, then
    1. Return the BigInt value that represents x ÷ 2-y, rounding down to the nearest integer, including for negative numbers.
  2. Return the BigInt value that represents x × 2y.
Note
Semantics here should be equivalent to a bitwise shift, treating the BigInt as an infinite length string of binary two's complement digits.

6.1.6.2.10 BigInt::signedRightShift ( x, y )

The abstract operation BigInt::signedRightShift with arguments x and y of type BigInt performs the following steps:

  1. Return BigInt::leftShift(x, -y).

6.1.6.2.11 BigInt::unsignedRightShift ( x, y )

The abstract operation BigInt::unsignedRightShift with two arguments x and y of type BigInt performs the following steps:

  1. Throw a TypeError exception.

6.1.6.2.12 BigInt::lessThan ( x, y )

The abstract operation BigInt::lessThan with two arguments x and y of type BigInt returns true if x is less than y and false otherwise.

6.1.6.2.13 BigInt::equal ( x, y )

The abstract operation BigInt::equal with two arguments x and y of type BigInt returns true if x and y have the same mathematical integer value and false otherwise.

6.1.6.2.14 BigInt::sameValue ( x, y )

The abstract operation BigInt::sameValue with two arguments x and y of type BigInt performs the following steps:

  1. Return BigInt::equal(x, y).

6.1.6.2.15 BigInt::sameValueZero ( x, y )

The abstract operation BigInt::sameValueZero with two arguments x and y of type BigInt performs the following steps:

  1. Return BigInt::equal(x, y).

6.1.6.2.16 BinaryAnd ( x, y )

  1. Assert: x is 0 or 1.
  2. Assert: y is 0 or 1.
  3. If x is 1 and y is 1, return 1.
  4. Else, return 0.

6.1.6.2.17 BinaryOr ( x, y )

  1. Assert: x is 0 or 1.
  2. Assert: y is 0 or 1.
  3. If x is 1 or y is 1, return 1.
  4. Else, return 0.

6.1.6.2.18 BinaryXor ( x, y )

  1. Assert: x is 0 or 1.
  2. Assert: y is 0 or 1.
  3. If x is 1 and y is 0, return 1.
  4. Else if x is 0 and y is 1, return 1.
  5. Else, return 0.

6.1.6.2.19 BigIntBitwiseOp ( op, x, y )

  1. Assert: op is "&", "|", or "^".
  2. Let result be 0n.
  3. Let shift be 0.
  4. Repeat, until (x = 0 or x = -1) and (y = 0 or y = -1),
    1. Let xDigit be x modulo 2.
    2. Let yDigit be y modulo 2.
    3. If op is "&", set result to result + 2shift × BinaryAnd(xDigit, yDigit).
    4. Else if op is "|", set result to result + 2shift × BinaryOr(xDigit, yDigit).
    5. Else,
      1. Assert: op is "^".
      2. Set result to result + 2shift × BinaryXor(xDigit, yDigit).
    6. Set shift to shift + 1.
    7. Set x to (x - xDigit) / 2.
    8. Set y to (y - yDigit) / 2.
  5. If op is "&", let tmp be BinaryAnd(x modulo 2, y modulo 2).
  6. Else if op is "|", let tmp be BinaryOr(x modulo 2, y modulo 2).
  7. Else,
    1. Assert: op is "^".
    2. Let tmp be BinaryXor(x modulo 2, y modulo 2).
  8. If tmp ≠ 0, then
    1. Set result to result - 2shift.
    2. NOTE: This extends the sign.
  9. Return result.

6.1.6.2.20 BigInt::bitwiseAND ( x, y )

  1. Return BigIntBitwiseOp("&", x, y).

6.1.6.2.21 BigInt::bitwiseXOR ( x, y )

  1. Return BigIntBitwiseOp("^", x, y).

6.1.6.2.22 BigInt::bitwiseOR ( x, y )

  1. Return BigIntBitwiseOp("|", x, y).

6.1.6.2.23 BigInt::toString ( x )

The abstract operation BigInt::toString converts a BigInt x to String format as follows:

  1. If x is less than zero, return the string-concatenation of the String "-" and ! BigInt::toString(-x).
  2. Return the String value consisting of the code units of the digits of the decimal representation of x.

6.1.7 The Object Type

An Object is logically a collection of properties. Each property is either a data property, or an accessor property:

  • A data property associates a key value with an ECMAScript language value and a set of Boolean attributes.
  • An accessor property associates a key value with one or two accessor functions, and a set of Boolean attributes. The accessor functions are used to store or retrieve an ECMAScript language value that is associated with the property.

Properties are identified using key values. A property key value is either an ECMAScript String value or a Symbol value. All String and Symbol values, including the empty String, are valid as property keys. A property name is a property key that is a String value.

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.21) and whose numeric value is either +0 or a positive integer ≤ 253 - 1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232 - 1.

Property keys are used to access properties and their values. There are two kinds of access for properties: get and set, corresponding to value retrieval and assignment, respectively. The properties accessible via get and set access includes both own properties that are a direct part of an object and inherited properties which are provided by another associated object via a property inheritance relationship. Inherited properties may be either own or inherited properties of the associated object. Each own property of an object must each have a key value that is distinct from the key values of the other own properties of that object.

All objects are logically collections of properties, but there are multiple forms of objects that differ in their semantics for accessing and manipulating their properties. Please see 6.1.7.2 for definitions of the multiple forms of objects.

6.1.7.1 Property Attributes

Attributes are used in this specification to define and explain the state of Object properties. A data property associates a key value with the attributes listed in Table 3.

Attribute Name Value Domain Description
[[Value]] Any ECMAScript language type The value retrieved by a get access of the property.
[[Writable]] Boolean If false, attempts by ECMAScript code to change the property's [[Value]] attribute using [[Set]] will not succeed.
[[Enumerable]] Boolean If true, the property will be enumerated by a for-in enumeration (see 13.7.5). Otherwise, the property is said to be non-enumerable.
[[Configurable]] Boolean If false, attempts to delete the property, change the property to be an accessor property, or change its attributes (other than [[Value]], or changing [[Writable]] to false) will fail.

An accessor property associates a key value with the attributes listed in Table 4.

Attribute Name Value Domain Description
[[Get]] Object | Undefined If the value is an Object it must be a function object. The function's [[Call]] internal method (Table 7) is called with an empty arguments list to retrieve the property value each time a get access of the property is performed.
[[Set]] Object | Undefined If the value is an Object it must be a function object. The function's [[Call]] internal method (Table 7) is called with an arguments list containing the assigned value as its sole argument each time a set access of the property is performed. The effect of a property's [[Set]] internal method may, but is not required to, have an effect on the value returned by subsequent calls to the property's [[Get]] internal method.
[[Enumerable]] Boolean If true, the property is to be enumerated by a for-in enumeration (see 13.7.5). Otherwise, the property is said to be non-enumerable.
[[Configurable]] Boolean If false, attempts to delete the property, change the property to be a data property, or change its attributes will fail.

If the initial values of a property's attributes are not explicitly specified by this specification, the default value defined in Table 5 is used.

Attribute Name Default Value
[[Value]] undefined
[[Get]] undefined
[[Set]] undefined
[[Writable]] false
[[Enumerable]] false
[[Configurable]] false

6.1.7.2 Object Internal Methods and Internal Slots

The actual semantics of objects, in ECMAScript, are specified via algorithms called internal methods. Each object in an ECMAScript engine is associated with a set of internal methods that defines its runtime behaviour. These internal methods are not part of the ECMAScript language. They are defined by this specification purely for expository purposes. However, each object within an implementation of ECMAScript must behave as specified by the internal methods associated with it. The exact manner in which this is accomplished is determined by the implementation.

Internal method names are polymorphic. This means that different object values may perform different algorithms when a common internal method name is invoked upon them. That actual object upon which an internal method is invoked is the “target” of the invocation. If, at runtime, the implementation of an algorithm attempts to use an internal method of an object that the object does not support, a TypeError exception is thrown.

Internal slots correspond to internal state that is associated with objects and used by various ECMAScript specification algorithms. Internal slots are not object properties and they are not inherited. Depending upon the specific internal slot specification, such state may consist of values of any ECMAScript language type or of specific ECMAScript specification type values. Unless explicitly specified otherwise, internal slots are allocated as part of the process of creating an object and may not be dynamically added to an object. Unless specified otherwise, the initial value of an internal slot is the value undefined. Various algorithms within this specification create objects that have internal slots. However, the ECMAScript language provides no direct way to associate internal slots with an object.

Internal methods and internal slots are identified within this specification using names enclosed in double square brackets [[ ]].

Table 6 summarizes the essential internal methods used by this specification that are applicable to all objects created or manipulated by ECMAScript code. Every object must have algorithms for all of the essential internal methods. However, all objects do not necessarily use the same algorithms for those methods.

An ordinary object is an object that satisfies all of the following criteria:

  • For the internal methods listed in Table 6, the object use those defined in 9.1.
  • If the object has a [[Call]] internal method, it uses the one defined in 9.2.1.
  • If the object has a [[Construct]] internal method, it uses the one defined in 9.2.2.

An exotic object is an object that is not an ordinary object.

This specification recognizes different kinds of exotic objects by those objects' internal methods. An object that is behaviourally equivalent to a particular kind of exotic object (such as an Array exotic object or a bound function exotic object), but does not have the same collection of internal methods specified for that kind, is not recognized as that kind of exotic object.

The “Signature” column of Table 6 and other similar tables describes the invocation pattern for each internal method. The invocation pattern always includes a parenthesized list of descriptive parameter names. If a parameter name is the same as an ECMAScript type name then the name describes the required type of the parameter value. If an internal method explicitly returns a value, its parameter list is followed by the symbol “→” and the type name of the returned value. The type names used in signatures refer to the types defined in clause 6 augmented by the following additional names. “any” means the value may be any ECMAScript language type.

In addition to its parameters, an internal method always has access to the object that is the target of the method invocation.

An internal method implicitly returns a Completion Record, either a normal completion that wraps a value of the return type shown in its invocation pattern, or a throw completion.

Internal Method Signature Description
[[GetPrototypeOf]] ( ) Object | Null Determine the object that provides inherited properties for this object. A null value indicates that there are no inherited properties.
[[SetPrototypeOf]] (Object | Null) Boolean Associate this object with another object that provides inherited properties. Passing null indicates that there are no inherited properties. Returns true indicating that the operation was completed successfully or false indicating that the operation was not successful.
[[IsExtensible]] ( ) Boolean Determine whether it is permitted to add additional properties to this object.
[[PreventExtensions]] ( ) Boolean Control whether new properties may be added to this object. Returns true if the operation was successful or false if the operation was unsuccessful.
[[GetOwnProperty]] (propertyKey) Undefined | Property Descriptor Return a Property Descriptor for the own property of this object whose key is propertyKey, or undefined if no such property exists.
[[DefineOwnProperty]] (propertyKey, PropertyDescriptor) Boolean Create or alter the own property, whose key is propertyKey, to have the state described by PropertyDescriptor. Return true if that property was successfully created/updated or false if the property could not be created or updated.
[[HasProperty]] (propertyKey) Boolean Return a Boolean value indicating whether this object already has either an own or inherited property whose key is propertyKey.
[[Get]] (propertyKey, Receiver) any Return the value of the property whose key is propertyKey from this object. If any ECMAScript code must be executed to retrieve the property value, Receiver is used as the this value when evaluating the code.
[[Set]] (propertyKey, value, Receiver) Boolean Set the value of the property whose key is propertyKey to value. If any ECMAScript code must be executed to set the property value, Receiver is used as the this value when evaluating the code. Returns true if the property value was set or false if it could not be set.
[[Delete]] (propertyKey) Boolean Remove the own property whose key is propertyKey from this object. Return false if the property was not deleted and is still present. Return true if the property was deleted or is not present.
[[OwnPropertyKeys]] ( ) List of propertyKey Return a List whose elements are all of the own property keys for the object.

Table 7 summarizes additional essential internal methods that are supported by objects that may be called as functions. A function object is an object that supports the [[Call]] internal method. A constructor is an object that supports the [[Construct]] internal method. Every object that supports [[Construct]] must support [[Call]]; that is, every constructor must be a function object. Therefore, a constructor may also be referred to as a constructor function or constructor function object.

Internal Method Signature Description
[[Call]] (any, a List of any) any Executes code associated with this object. Invoked via a function call expression. The arguments to the internal method are a this value and a list containing the arguments passed to the function by a call expression. Objects that implement this internal method are callable.
[[Construct]] (a List of any, Object) Object Creates an object. Invoked via the new operator or a super call. The first argument to the internal method is a list containing the arguments of the constructor invocation or the super call. The second argument is the object to which the new operator was initially applied. Objects that implement this internal method are called constructors. A function object is not necessarily a constructor and such non-constructor function objects do not have a [[Construct]] internal method.

The semantics of the essential internal methods for ordinary objects and standard exotic objects are specified in clause 9. If any specified use of an internal method of an exotic object is not supported by an implementation, that usage must throw a TypeError exception when attempted.

6.1.7.3 Invariants of the Essential Internal Methods

The Internal Methods of Objects of an ECMAScript engine must conform to the list of invariants specified below. Ordinary ECMAScript Objects as well as all standard exotic objects in this specification maintain these invariants. ECMAScript Proxy objects maintain these invariants by means of runtime checks on the result of traps invoked on the [[ProxyHandler]] object.

Any implementation provided exotic objects must also maintain these invariants for those objects. Violation of these invariants may cause ECMAScript code to have unpredictable behaviour and create security issues. However, violation of these invariants must never compromise the memory safety of an implementation.

An implementation must not allow these invariants to be circumvented in any manner such as by providing alternative interfaces that implement the functionality of the essential internal methods without enforcing their invariants.

Definitions:

  • The target of an internal method is the object upon which the internal method is called.
  • A target is non-extensible if it has been observed to return false from its [[IsExtensible]] internal method, or true from its [[PreventExtensions]] internal method.
  • A non-existent property is a property that does not exist as an own property on a non-extensible target.
  • All references to SameValue are according to the definition of the SameValue algorithm.

Return value:

The value returned by any internal method must be a Completion Record with either:

  • [[Type]] = normal, [[Target]] = empty, and [[Value]] = a value of the "normal return type" shown below for that internal method, or
  • [[Type]] = throw, [[Target]] = empty, and [[Value]] = any ECMAScript language value.
Note 1

An internal method must not return a completion with [[Type]] = continue, break, or return.

[[GetPrototypeOf]] ( )

  • The normal return type is either Object or Null.
  • If target is non-extensible, and [[GetPrototypeOf]] returns a value V, then any future calls to [[GetPrototypeOf]] should return the SameValue as V.
Note 2

An object's prototype chain should have finite length (that is, starting from any object, recursively applying the [[GetPrototypeOf]] internal method to its result should eventually lead to the value null). However, this requirement is not enforceable as an object level invariant if the prototype chain includes any exotic objects that do not use the ordinary object definition of [[GetPrototypeOf]]. Such a circular prototype chain may result in infinite loops when accessing object properties.

[[SetPrototypeOf]] ( V )

  • The normal return type is Boolean.
  • If target is non-extensible, [[SetPrototypeOf]] must return false, unless V is the SameValue as the target's observed [[GetPrototypeOf]] value.

[[IsExtensible]] ( )

  • The normal return type is Boolean.
  • If [[IsExtensible]] returns false, all future calls to [[IsExtensible]] on the target must return false.

[[PreventExtensions]] ( )

  • The normal return type is Boolean.
  • If [[PreventExtensions]] returns true, all future calls to [[IsExtensible]] on the target must return false and the target is now considered non-extensible.

[[GetOwnProperty]] ( P )

  • The normal return type is either Property Descriptor or Undefined.
  • If the Type of the return value is Property Descriptor, the return value must be a complete property descriptor.
  • If P is described as a non-configurable, non-writable own data property, all future calls to [[GetOwnProperty]] ( P ) must return Property Descritor whose [[Value]] is SameValue as P's [[Value]] attribute.
  • If P's attributes other than [[Writable]] may change over time or if the property might be deleted, then P's [[Configurable]] attribute must be true.
  • If the [[Writable]] attribute may change from false to true, then the [[Configurable]] attribute must be true.
  • If the target is non-extensible and P is non-existent, then all future calls to [[GetOwnProperty]] (P) on the target must describe P as non-existent (i.e. [[GetOwnProperty]] (P) must return undefined).
Note 3

As a consequence of the third invariant, if a property is described as a data property and it may return different values over time, then either or both of the [[Writable]] and [[Configurable]] attributes must be true even if no mechanism to change the value is exposed via the other essential internal methods.

[[DefineOwnProperty]] ( P, Desc )

  • The normal return type is Boolean.
  • [[DefineOwnProperty]] must return false if P has previously been observed as a non-configurable own property of the target, unless either:
    1. P is a writable data property. A non-configurable writable data property can be changed into a non-configurable non-writable data property.
    2. All attributes of Desc are the SameValue as P's attributes.
  • [[DefineOwnProperty]] (P, Desc) must return false if target is non-extensible and P is a non-existent own property. That is, a non-extensible target object cannot be extended with new properties.

[[HasProperty]] ( P )

  • The normal return type is Boolean.
  • If P was previously observed as a non-configurable own data or accessor property of the target, [[HasProperty]] must return true.

[[Get]] ( P, Receiver )

  • The normal return type is any ECMAScript language type.
  • If P was previously observed as a non-configurable, non-writable own data property of the target with value V, then [[Get]] must return the SameValue as V.
  • If P was previously observed as a non-configurable own accessor property of the target whose [[Get]] attribute is undefined, the [[Get]] operation must return undefined.

[[Set]] ( P, V, Receiver )

  • The normal return type is Boolean.
  • If P was previously observed as a non-configurable, non-writable own data property of the target, then [[Set]] must return false unless V is the SameValue as P's [[Value]] attribute.
  • If P was previously observed as a non-configurable own accessor property of the target whose [[Set]] attribute is undefined, the [[Set]] operation must return false.

[[Delete]] ( P )

  • The normal return type is Boolean.
  • If P was previously observed as a non-configurable own data or accessor property of the target, [[Delete]] must return false.

[[OwnPropertyKeys]] ( )

  • The normal return type is List.
  • The returned List must not contain any duplicate entries.
  • The Type of each element of the returned List is either String or Symbol.
  • The returned List must contain at least the keys of all non-configurable own properties that have previously been observed.
  • If the object is non-extensible, the returned List must contain only the keys of all own properties of the object that are observable using [[GetOwnProperty]].

[[Call]] ( )

[[Construct]] ( )

  • The normal return type is Object.

6.1.7.4 Well-Known Intrinsic Objects

Well-known intrinsics are built-in objects that are explicitly referenced by the algorithms of this specification and which usually have realm-specific identities. Unless otherwise specified each intrinsic object actually corresponds to a set of similar objects, one per realm.

Within this specification a reference such as %name% means the intrinsic object, associated with the current realm, corresponding to the name. A reference such as %name.a.b% means, as if the "b" property of the "a" property of the intrinsic object %name% was accessed prior to any ECMAScript code being evaluated. Determination of the current realm and its intrinsics is described in 8.3. The well-known intrinsics are listed in Table 8.

Intrinsic Name Global Name ECMAScript Language Association
%Array% Array The Array constructor (22.1.1)
%ArrayBuffer% ArrayBuffer The ArrayBuffer constructor (24.1.2)
%ArrayBufferPrototype% ArrayBuffer.prototype The initial value of the "prototype" data property of %ArrayBuffer%; i.e., %ArrayBuffer.prototype%
%ArrayIteratorPrototype% The prototype of Array iterator objects (22.1.5); i.e., %ArrayIterator.prototype%
%ArrayPrototype% Array.prototype The initial value of the "prototype" data property of %Array% (22.1.3); i.e., %Array.prototype%
%ArrayProto_entries% Array.prototype.entries The initial value of the "entries" data property of %Array.prototype% (22.1.3.4); i.e., %Array.prototype.entries%
%ArrayProto_forEach% Array.prototype.forEach The initial value of the "forEach" data property of %Array.prototype% (22.1.3.12); i.e., %Array.prototype.forEach%
%ArrayProto_keys% Array.prototype.keys The initial value of the "keys" data property of %Array.prototype% (22.1.3.16); i.e., %Array.prototype.keys%
%ArrayProto_values% Array.prototype.values The initial value of the "values" data property of %Array.prototype% (22.1.3.32); i.e., %Array.prototype.values%
%AsyncFromSyncIteratorPrototype% The prototype of async-from-sync iterator objects (25.1.4)
%AsyncFunction% The constructor of async function objects (25.7.1)
%AsyncFunctionPrototype% The initial value of the "prototype" data property of %AsyncFunction%; i.e., %AsyncFunction.prototype%
%AsyncGenerator% The initial value of the "prototype" property of %AsyncGeneratorFunction%; i.e., %AsyncGeneratorFunction.prototype%
%AsyncGeneratorFunction% The constructor of async iterator objects (25.3.1)
%AsyncGeneratorPrototype% The initial value of the "prototype" property of %AsyncGenerator%; i.e., %AsyncGenerator.prototype%
%AsyncIteratorPrototype% An object that all standard built-in async iterator objects indirectly inherit from
%Atomics% Atomics The Atomics object (24.4)
%BigInt% BigInt The BigInt constructor (20.2.1)
%BigInt64Array% BigInt64Array The BigInt64Array constructor (22.2)
%BigUint64Array% BigUint64Array The BigUint64Array constructor (22.2)
%Boolean% Boolean The Boolean constructor (19.3.1)
%BooleanPrototype% Boolean.prototype The initial value of the "prototype" data property of %Boolean% (19.3.3); i.e., %Boolean.prototype%
%DataView% DataView The DataView constructor (24.3.2)
%DataViewPrototype% DataView.prototype The initial value of the "prototype" data property of %DataView%; i.e., %DataView.prototype%
%Date% Date The Date constructor (20.4.2)
%DatePrototype% Date.prototype The initial value of the "prototype" data property of %Date%.; i.e., %Date.prototype%
%decodeURI% decodeURI The decodeURI function (18.2.6.2)
%decodeURIComponent% decodeURIComponent The decodeURIComponent function (18.2.6.3)
%encodeURI% encodeURI The encodeURI function (18.2.6.4)
%encodeURIComponent% encodeURIComponent The encodeURIComponent function (18.2.6.5)
%Error% Error The Error constructor (19.5.1)
%ErrorPrototype% Error.prototype The initial value of the "prototype" data property of %Error%; i.e., %Error.prototype%
%eval% eval The eval function (18.2.1)
%EvalError% EvalError The EvalError constructor (19.5.5.1)
%EvalErrorPrototype% EvalError.prototype The initial value of the "prototype" data property of %EvalError%; i.e., %EvalError.prototype%
%Float32Array% Float32Array The Float32Array constructor (22.2)
%Float32ArrayPrototype% Float32Array.prototype The initial value of the "prototype" data property of %Float32Array%; i.e., %Float32Array.prototype%
%Float64Array% Float64Array The Float64Array constructor (22.2)
%Float64ArrayPrototype% Float64Array.prototype The initial value of the "prototype" data property of %Float64Array%; i.e., %Float64Array.prototype%
%ForInIteratorPrototype% The prototype of For-In iterator objects (13.7.5.16)
%Function% Function The Function constructor (19.2.1)
%FunctionPrototype% Function.prototype The initial value of the "prototype" data property of %Function%; i.e., %Function.prototype%
%Generator% The initial value of the "prototype" data property of %GeneratorFunction%
%GeneratorFunction% The constructor of generator objects (25.2.1)
%GeneratorPrototype% The initial value of the "prototype" data property of %Generator%; i.e., %Generator.prototype%
%Int8Array% Int8Array The Int8Array constructor (22.2)
%Int8ArrayPrototype% Int8Array.prototype The initial value of the "prototype" data property of %Int8Array%; i.e., %Int8Array.prototype%
%Int16Array% Int16Array The Int16Array constructor (22.2)
%Int16ArrayPrototype% Int16Array.prototype The initial value of the "prototype" data property of %Int16Array%; i.e., %Int16Array.prototype%
%Int32Array% Int32Array The Int32Array constructor (22.2)
%Int32ArrayPrototype% Int32Array.prototype The initial value of the "prototype" data property of %Int32Array%; i.e., %Int32Array.prototype%
%isFinite% isFinite The isFinite function (18.2.2)
%isNaN% isNaN The isNaN function (18.2.3)
%IteratorPrototype% An object that all standard built-in iterator objects indirectly inherit from
%JSON% JSON The JSON object (24.5)
%JSONParse% JSON.parse The initial value of the "parse" data property of %JSON%; i.e., %JSON.parse%
%JSONStringify% JSON.stringify The initial value of the "stringify" data property of %JSON%; i.e., %JSON.stringify%
%Map% Map The Map constructor (23.1.1)
%MapIteratorPrototype% The prototype of Map iterator objects (23.1.5)
%MapPrototype% Map.prototype The initial value of the "prototype" data property of %Map%; i.e., %Map.prototype%
%Math% Math The Math object (20.3)
%Number% Number The Number constructor (20.1.1)
%NumberPrototype% Number.prototype The initial value of the "prototype" data property of %Number%; i.e., %Number.prototype%
%Object% Object The Object constructor (19.1.1)
%ObjectPrototype% Object.prototype The initial value of the "prototype" data property of %Object% (19.1.3); i.e., %Object.prototype%
%ObjProto_toString% Object.prototype.toString The initial value of the "toString" data property of %Object.prototype% (19.1.3.6); i.e., %Object.prototype.toString%
%ObjProto_valueOf% Object.prototype.valueOf The initial value of the "valueOf" data property of %Object.prototype% (19.1.3.7); i.e., %Object.prototype.valueOf%
%parseFloat% parseFloat The parseFloat function (18.2.4)
%parseInt% parseInt The parseInt function (18.2.5)
%Promise% Promise The Promise constructor (25.6.3)
%PromisePrototype% Promise.prototype The initial value of the "prototype" data property of %Promise%; i.e., %Promise.prototype%
%PromiseProto_then% Promise.prototype.then The initial value of the "then" data property of %Promise.prototype% (25.6.5.4); i.e., %Promise.prototype.then%
%Promise_all% Promise.all The initial value of the "all" data property of %Promise% (25.6.4.1); i.e., %Promise.all%
%Promise_reject% Promise.reject The initial value of the "reject" data property of %Promise% (25.6.4.5); i.e., %Promise.reject%
%Promise_resolve% Promise.resolve The initial value of the "resolve" data property of %Promise% (25.6.4.6); i.e., %Promise.resolve%
%Proxy% Proxy The Proxy constructor (26.2.1)
%RangeError% RangeError The RangeError constructor (19.5.5.2)
%RangeErrorPrototype% RangeError.prototype The initial value of the "prototype" data property of %RangeError%; i.e., %RangeError.prototype%
%ReferenceError% ReferenceError The ReferenceError constructor (19.5.5.3)
%ReferenceErrorPrototype% ReferenceError.prototype The initial value of the "prototype" data property of %ReferenceError%; i.e., %ReferenceError.prototype%
%Reflect% Reflect The Reflect object (26.1)
%RegExp% RegExp The RegExp constructor (21.2.3)
%RegExpPrototype% RegExp.prototype The initial value of the "prototype" data property of %RegExp%; i.e., %RegExp.prototype%
%RegExpStringIteratorPrototype% The prototype of RegExp String Iterator objects (21.2.7)
%Set% Set The Set constructor (23.2.1)
%SetIteratorPrototype% The prototype of Set iterator objects (23.2.5)
%SetPrototype% Set.prototype The initial value of the "prototype" data property of %Set%; i.e., %Set.prototype%
%SharedArrayBuffer% SharedArrayBuffer The SharedArrayBuffer constructor (24.2.2)
%SharedArrayBufferPrototype% SharedArrayBuffer.prototype The initial value of the "prototype" data property of %SharedArrayBuffer%; i.e., %SharedArrayBuffer.prototype%
%String% String The String constructor (21.1.1)
%StringIteratorPrototype% The prototype of String iterator objects (21.1.5)
%StringPrototype% String.prototype The initial value of the "prototype" data property of %String%; i.e., %String.prototype%
%Symbol% Symbol The Symbol constructor (19.4.1)
%SymbolPrototype% Symbol.prototype The initial value of the "prototype" data property of %Symbol% (19.4.3); i.e., %Symbol.prototype%
%SyntaxError% SyntaxError The SyntaxError constructor (19.5.5.4)
%SyntaxErrorPrototype% SyntaxError.prototype The initial value of the "prototype" data property of %SyntaxError%; i.e., %SyntaxError.prototype%
%ThrowTypeError% A function object that unconditionally throws a new instance of %TypeError%
%TypedArray% The super class of all typed Array constructors (22.2.1)
%TypedArrayPrototype% The initial value of the "prototype" data property of %TypedArray%; i.e., %TypedArray.prototype%
%TypeError% TypeError The TypeError constructor (19.5.5.5)
%TypeErrorPrototype% TypeError.prototype The initial value of the "prototype" data property of %TypeError%; i.e., %TypeError.prototype%
%Uint8Array% Uint8Array The Uint8Array constructor (22.2)
%Uint8ArrayPrototype% Uint8Array.prototype The initial value of the "prototype" data property of %Uint8Array%; i.e., %Uint8Array.prototype%
%Uint8ClampedArray% Uint8ClampedArray The Uint8ClampedArray constructor (22.2)
%Uint8ClampedArrayPrototype% Uint8ClampedArray.prototype The initial value of the "prototype" data property of %Uint8ClampedArray%; i.e., %Uint8ClampedArray.prototype%
%Uint16Array% Uint16Array The Uint16Array constructor (22.2)
%Uint16ArrayPrototype% Uint16Array.prototype The initial value of the "prototype" data property of %Uint16Array%; i.e., %Uint16Array.prototype%
%Uint32Array% Uint32Array The Uint32Array constructor (22.2)
%Uint32ArrayPrototype% Uint32Array.prototype The initial value of the "prototype" data property of %Uint32Array%; i.e., %Uint32Array.prototype%
%URIError% URIError The URIError constructor (19.5.5.6)
%URIErrorPrototype% URIError.prototype The initial value of the "prototype" data property of %URIError%; i.e., %URIError.prototype%
%WeakMap% WeakMap The WeakMap constructor (23.3.1)
%WeakMapPrototype% WeakMap.prototype The initial value of the "prototype" data property of %WeakMap%; i.e., %WeakMap.prototype%
%WeakSet% WeakSet The WeakSet constructor (23.4.1)
%WeakSetPrototype% WeakSet.prototype The initial value of the "prototype" data property of %WeakSet%; i.e., %WeakSet.prototype%

6.2 ECMAScript Specification Types

A specification type corresponds to meta-values that are used within algorithms to describe the semantics of ECMAScript language constructs and ECMAScript language types. The specification types include Reference, List, Completion, Property Descriptor, Lexical Environment, Environment Record, Abstract Closure, and Data Block. Specification type values are specification artefacts that do not necessarily correspond to any specific entity within an ECMAScript implementation. Specification type values may be used to describe intermediate results of ECMAScript expression evaluation but such values cannot be stored as properties of objects or values of ECMAScript language variables.

6.2.1 The List and Record Specification Types

The List type is used to explain the evaluation of argument lists (see 12.3.8) in new expressions, in function calls, and in other algorithms where a simple ordered list of values is needed. Values of the List type are simply ordered sequences of list elements containing the individual values. These sequences may be of any length. The elements of a list may be randomly accessed using 0-origin indices. For notational convenience an array-like syntax can be used to access List elements. For example, arguments[2] is shorthand for saying the 3rd element of the List arguments.

For notational convenience within this specification, a literal syntax can be used to express a new List value. For example, « 1, 2 » defines a List value that has two elements each of which is initialized to a specific value. A new empty List can be expressed as « ».

The Record type is used to describe data aggregations within the algorithms of this specification. A Record type value consists of one or more named fields. The value of each field is either an ECMAScript value or an abstract value represented by a name associated with the Record type. Field names are always enclosed in double brackets, for example [[Value]].

For notational convenience within this specification, an object literal-like syntax can be used to express a Record value. For example, { [[Field1]]: 42, [[Field2]]: false, [[Field3]]: empty } defines a Record value that has three fields, each of which is initialized to a specific value. Field name order is not significant. Any fields that are not explicitly listed are considered to be absent.

In specification text and algorithms, dot notation may be used to refer to a specific field of a Record value. For example, if R is the record shown in the previous paragraph then R.[[Field2]] is shorthand for “the field of R named [[Field2]]”.

Schema for commonly used Record field combinations may be named, and that name may be used as a prefix to a literal Record value to identify the specific kind of aggregations that is being described. For example: PropertyDescriptor { [[Value]]: 42, [[Writable]]: false, [[Configurable]]: true }.

6.2.2 The Set and Relation Specification Types

The Set type is used to explain a collection of unordered elements for use in the memory model. Values of the Set type are simple collections of elements, where no element appears more than once. Elements may be added to and removed from Sets. Sets may be unioned, intersected, or subtracted from each other.

The Relation type is used to explain constraints on Sets. Values of the Relation type are Sets of ordered pairs of values from its value domain. For example, a Relation on events is a set of ordered pairs of events. For a Relation R and two values a and b in the value domain of R, a R b is shorthand for saying the ordered pair (a, b) is a member of R. A Relation is least with respect to some conditions when it is the smallest Relation that satisfies those conditions.

A strict partial order is a Relation value R that satisfies the following.

  • For all a, b, and c in R's domain:

    • It is not the case that a R a, and
    • If a R b and b R c, then a R c.
Note 1

The two properties above are called, in order, irreflexivity and transitivity.

A strict total order is a Relation value R that satisfies the following.

  • For all a, b, and c in R's domain:

    • a is identical to b or a R b or b R a, and
    • It is not the case that a R a, and
    • If a R b and b R c, then a R c.
Note 2

The three properties above are called, in order, totality, irreflexivity, and transitivity.

6.2.3 The Completion Record Specification Type

The Completion type is a Record used to explain the runtime propagation of values and control flow such as the behaviour of statements (break, continue, return and throw) that perform nonlocal transfers of control.

Values of the Completion type are Record values whose fields are defined as by Table 9. Such values are referred to as Completion Records.

Field Name Value Meaning
[[Type]] One of normal, break, continue, return, or throw The type of completion that occurred.
[[Value]] any ECMAScript language value or empty The value that was produced.
[[Target]] any ECMAScript string or empty The target label for directed control transfers.

The term “abrupt completion” refers to any completion with a [[Type]] value other than normal.

6.2.3.1 Await

Algorithm steps that say

  1. Let completion be Await(value).

mean the same thing as:

  1. Let asyncContext be the running execution context.
  2. Let promise be ? PromiseResolve(%Promise%, value).
  3. Let stepsFulfilled be the algorithm steps defined in Await Fulfilled Functions.
  4. Let onFulfilled be ! CreateBuiltinFunction(stepsFulfilled, « [[AsyncContext]] »).
  5. Set onFulfilled.[[AsyncContext]] to asyncContext.
  6. Let stepsRejected be the algorithm steps defined in Await Rejected Functions.
  7. Let onRejected be ! CreateBuiltinFunction(stepsRejected, « [[AsyncContext]] »).
  8. Set onRejected.[[AsyncContext]] to asyncContext.
  9. Perform ! PerformPromiseThen(promise, onFulfilled, onRejected).
  10. Remove asyncContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
  11. Set the code evaluation state of asyncContext such that when evaluation is resumed with a Completion completion, the following steps of the algorithm that invoked Await will be performed, with completion available.
  12. Return.
  13. NOTE: This returns to the evaluation of the operation that had most previously resumed evaluation of asyncContext.

where all variables in the above steps, with the exception of completion, are ephemeral and visible only in the steps pertaining to Await.

Note

Await can be combined with the ? and ! prefixes, so that for example

  1. Let result be ? Await(value).

means the same thing as:

  1. Let result be Await(value).
  2. ReturnIfAbrupt(result).

6.2.3.1.1 Await Fulfilled Functions

An Await fulfilled function is an anonymous built-in function that is used as part of the Await specification device to deliver the promise fulfillment value to the caller as a normal completion. Each Await fulfilled function has an [[AsyncContext]] internal slot.

When an Await fulfilled function is called with argument value, the following steps are taken:

  1. Let F be the active function object.
  2. Let asyncContext be F.[[AsyncContext]].
  3. Let prevContext be the running execution context.
  4. Suspend prevContext.
  5. Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
  6. Resume the suspended evaluation of asyncContext using NormalCompletion(value) as the result of the operation that suspended it.
  7. Assert: When we reach this step, asyncContext has already been removed from the execution context stack and prevContext is the currently running execution context.
  8. Return undefined.

The "length" property of an Await fulfilled function is 1.

6.2.3.1.2 Await Rejected Functions

An Await rejected function is an anonymous built-in function that is used as part of the Await specification device to deliver the promise rejection reason to the caller as an abrupt throw completion. Each Await rejected function has an [[AsyncContext]] internal slot.

When an Await rejected function is called with argument reason, the following steps are taken:

  1. Let F be the active function object.
  2. Let asyncContext be F.[[AsyncContext]].
  3. Let prevContext be the running execution context.
  4. Suspend prevContext.
  5. Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
  6. Resume the suspended evaluation of asyncContext using ThrowCompletion(reason) as the result of the operation that suspended it.
  7. Assert: When we reach this step, asyncContext has already been removed from the execution context stack and prevContext is the currently running execution context.
  8. Return undefined.

The "length" property of an Await rejected function is 1.

6.2.3.2 NormalCompletion

The abstract operation NormalCompletion with a single argument, such as:

  1. Return NormalCompletion(argument).

Is a shorthand that is defined as follows:

  1. Return Completion { [[Type]]: normal, [[Value]]: argument, [[Target]]: empty }.

6.2.3.3 ThrowCompletion

The abstract operation ThrowCompletion with a single argument, such as:

  1. Return ThrowCompletion(argument).

Is a shorthand that is defined as follows:

  1. Return Completion { [[Type]]: throw, [[Value]]: argument, [[Target]]: empty }.

6.2.3.4 UpdateEmpty ( completionRecord, value )

The abstract operation UpdateEmpty with arguments completionRecord and value performs the following steps:

  1. Assert: If completionRecord.[[Type]] is either return or throw, then completionRecord.[[Value]] is not empty.
  2. If completionRecord.[[Value]] is not empty, return Completion(completionRecord).
  3. Return Completion { [[Type]]: completionRecord.[[Type]], [[Value]]: value, [[Target]]: completionRecord.[[Target]] }.

6.2.4 The Reference Specification Type

Note

The Reference type is used to explain the behaviour of such operators as delete, typeof, the assignment operators, the super keyword and other language features. For example, the left-hand operand of an assignment is expected to produce a reference.

A Reference is a resolved name or property binding. A Reference consists of three components, the base value component, the referenced name component, and the Boolean-valued strict reference flag. The base value component is either undefined, an Object, a Boolean, a String, a Symbol, a Number, a BigInt, or an Environment Record. A base value component of undefined indicates that the Reference could not be resolved to a binding. The referenced name component is a String or Symbol value.

A Super Reference is a Reference that is used to represent a name binding that was expressed using the super keyword. A Super Reference has an additional thisValue component, and its base value component will never be an Environment Record.

The following abstract operations are used in this specification to operate on references:

6.2.4.1 GetBase ( V )

  1. Assert: Type(V) is Reference.
  2. Return the base value component of V.

6.2.4.2 GetReferencedName ( V )

  1. Assert: Type(V) is Reference.
  2. Return the referenced name component of V.

6.2.4.3 IsStrictReference ( V )

  1. Assert: Type(V) is Reference.
  2. Return the strict reference flag of V.

6.2.4.4 HasPrimitiveBase ( V )

  1. Assert: Type(V) is Reference.
  2. If Type(V's base value component) is Boolean, String, Symbol, BigInt, or Number, return true; otherwise return false.

6.2.4.5 IsPropertyReference ( V )

  1. Assert: Type(V) is Reference.
  2. If either the base value component of V is an Object or HasPrimitiveBase(V) is true, return true; otherwise return false.

6.2.4.6 IsUnresolvableReference ( V )

  1. Assert: Type(V) is Reference.
  2. If the base value component of V is undefined, return true; otherwise return false.

6.2.4.7 IsSuperReference ( V )

  1. Assert: Type(V) is Reference.
  2. If V has a thisValue component, return true; otherwise return false.

6.2.4.8 GetValue ( V )

  1. ReturnIfAbrupt(V).
  2. If Type(V) is not Reference, return V.
  3. Let base be GetBase(V).
  4. If IsUnresolvableReference(V) is true, throw a ReferenceError exception.
  5. If IsPropertyReference(V) is true, then
    1. If HasPrimitiveBase(V) is true, then
      1. Assert: In this case, base will never be undefined or null.
      2. Set base to ! ToObject(base).
    2. Return ? base.[[Get]](GetReferencedName(V), GetThisValue(V)).
  6. Else,
    1. Assert: base is an Environment Record.
    2. Return ? base.GetBindingValue(GetReferencedName(V), IsStrictReference(V)) (see 8.1.1).
Note

The object that may be created in step 5.a.ii is not accessible outside of the above abstract operation and the ordinary object [[Get]] internal method. An implementation might choose to avoid the actual creation of the object.

6.2.4.9 PutValue ( V, W )

  1. ReturnIfAbrupt(V).
  2. ReturnIfAbrupt(W).
  3. If Type(V) is not Reference, throw a ReferenceError exception.
  4. Let base be GetBase(V).
  5. If IsUnresolvableReference(V) is true, then
    1. If IsStrictReference(V) is true, then
      1. Throw a ReferenceError exception.
    2. Let globalObj be GetGlobalObject().
    3. Return ? Set(globalObj, GetReferencedName(V), W, false).
  6. Else if IsPropertyReference(V) is true, then
    1. If HasPrimitiveBase(V) is true, then
      1. Assert: In this case, base will never be undefined or null.
      2. Set base to ! ToObject(base).
    2. Let succeeded be ? base.[[Set]](GetReferencedName(V), W, GetThisValue(V)).
    3. If succeeded is false and IsStrictReference(V) is true, throw a TypeError exception.
    4. Return.
  7. Else,
    1. Assert: base is an Environment Record.
    2. Return ? base.SetMutableBinding(GetReferencedName(V), W, IsStrictReference(V)) (see 8.1.1).
Note

The object that may be created in step 6.a.ii is not accessible outside of the above algorithm and the ordinary object [[Set]] internal method. An implementation might choose to avoid the actual creation of that object.

6.2.4.10 GetThisValue ( V )

  1. Assert: IsPropertyReference(V) is true.
  2. If IsSuperReference(V) is true, then
    1. Return the value of the thisValue component of the reference V.
  3. Return GetBase(V).

6.2.4.11 InitializeReferencedBinding ( V, W )

  1. ReturnIfAbrupt(V).
  2. ReturnIfAbrupt(W).
  3. Assert: Type(V) is Reference.
  4. Assert: IsUnresolvableReference(V) is false.
  5. Let base be GetBase(V).
  6. Assert: base is an Environment Record.
  7. Return base.InitializeBinding(GetReferencedName(V), W).

6.2.5 The Property Descriptor Specification Type

The Property Descriptor type is used to explain the manipulation and reification of Object property attributes. Values of the Property Descriptor type are Records. Each field's name is an attribute name and its value is a corresponding attribute value as specified in 6.1.7.1. In addition, any field may be present or absent. The schema name used within this specification to tag literal descriptions of Property Descriptor records is “PropertyDescriptor”.

Property Descriptor values may be further classified as data Property Descriptors and accessor Property Descriptors based upon the existence or use of certain fields. A data Property Descriptor is one that includes any fields named either [[Value]] or [[Writable]]. An accessor Property Descriptor is one that includes any fields named either [[Get]] or [[Set]]. Any Property Descriptor may have fields named [[Enumerable]] and [[Configurable]]. A Property Descriptor value may not be both a data Property Descriptor and an accessor Property Descriptor; however, it may be neither. A generic Property Descriptor is a Property Descriptor value that is neither a data Property Descriptor nor an accessor Property Descriptor. A fully populated Property Descriptor is one that is either an accessor Property Descriptor or a data Property Descriptor and that has all of the fields that correspond to the property attributes defined in either Table 3 or Table 4.

The following abstract operations are used in this specification to operate upon Property Descriptor values:

6.2.5.1 IsAccessorDescriptor ( Desc )

When the abstract operation IsAccessorDescriptor is called with Property Descriptor Desc, the following steps are taken:

  1. If Desc is undefined, return false.
  2. If both Desc.[[Get]] and Desc.[[Set]] are absent, return false.
  3. Return true.

6.2.5.2 IsDataDescriptor ( Desc )

When the abstract operation IsDataDescriptor is called with Property Descriptor Desc, the following steps are taken:

  1. If Desc is undefined, return false.
  2. If both Desc.[[Value]] and Desc.[[Writable]] are absent, return false.
  3. Return true.

6.2.5.3 IsGenericDescriptor ( Desc )

When the abstract operation IsGenericDescriptor is called with Property Descriptor Desc, the following steps are taken:

  1. If Desc is undefined, return false.
  2. If IsAccessorDescriptor(Desc) and IsDataDescriptor(Desc) are both false, return true.
  3. Return false.

6.2.5.4 FromPropertyDescriptor ( Desc )

When the abstract operation FromPropertyDescriptor is called with Property Descriptor Desc, the following steps are taken:

  1. If Desc is undefined, return undefined.
  2. Let obj be OrdinaryObjectCreate(%Object.prototype%).
  3. Assert: obj is an extensible ordinary object with no own properties.
  4. If Desc has a [[Value]] field, then
    1. Perform ! CreateDataPropertyOrThrow(obj, "value", Desc.[[Value]]).
  5. If Desc has a [[Writable]] field, then
    1. Perform ! CreateDataPropertyOrThrow(obj, "writable", Desc.[[Writable]]).
  6. If Desc has a [[Get]] field, then
    1. Perform ! CreateDataPropertyOrThrow(obj, "get", Desc.[[Get]]).
  7. If Desc has a [[Set]] field, then
    1. Perform ! CreateDataPropertyOrThrow(obj, "set", Desc.[[Set]]).
  8. If Desc has an [[Enumerable]] field, then
    1. Perform ! CreateDataPropertyOrThrow(obj, "enumerable", Desc.[[Enumerable]]).
  9. If Desc has a [[Configurable]] field, then
    1. Perform ! CreateDataPropertyOrThrow(obj, "configurable", Desc.[[Configurable]]).
  10. Return obj.

6.2.5.5 ToPropertyDescriptor ( Obj )

When the abstract operation ToPropertyDescriptor is called with object Obj, the following steps are taken:

  1. If Type(Obj) is not Object, throw a TypeError exception.
  2. Let desc be a new Property Descriptor that initially has no fields.
  3. Let hasEnumerable be ? HasProperty(Obj, "enumerable").
  4. If hasEnumerable is true, then
    1. Let enumerable be ! ToBoolean(? Get(Obj, "enumerable")).
    2. Set desc.[[Enumerable]] to enumerable.
  5. Let hasConfigurable be ? HasProperty(Obj, "configurable").
  6. If hasConfigurable is true, then
    1. Let configurable be ! ToBoolean(? Get(Obj, "configurable")).
    2. Set desc.[[Configurable]] to configurable.
  7. Let hasValue be ? HasProperty(Obj, "value").
  8. If hasValue is true, then
    1. Let value be ? Get(Obj, "value").
    2. Set desc.[[Value]] to value.
  9. Let hasWritable be ? HasProperty(Obj, "writable").
  10. If hasWritable is true, then
    1. Let writable be ! ToBoolean(? Get(Obj, "writable")).
    2. Set desc.[[Writable]] to writable.
  11. Let hasGet be ? HasProperty(Obj, "get").
  12. If hasGet is true, then
    1. Let getter be ? Get(Obj, "get").
    2. If IsCallable(getter) is false and getter is not undefined, throw a TypeError exception.
    3. Set desc.[[Get]] to getter.
  13. Let hasSet be ? HasProperty(Obj, "set").
  14. If hasSet is true, then
    1. Let setter be ? Get(Obj, "set").
    2. If IsCallable(setter) is false and setter is not undefined, throw a TypeError exception.
    3. Set desc.[[Set]] to setter.
  15. If desc.[[Get]] is present or desc.[[Set]] is present, then
    1. If desc.[[Value]] is present or desc.[[Writable]] is present, throw a TypeError exception.
  16. Return desc.

6.2.5.6 CompletePropertyDescriptor ( Desc )

When the abstract operation CompletePropertyDescriptor is called with Property Descriptor Desc, the following steps are taken:

  1. Assert: Desc is a Property Descriptor.
  2. Let like be the Record { [[Value]]: undefined, [[Writable]]: false, [[Get]]: undefined, [[Set]]: undefined, [[Enumerable]]: false, [[Configurable]]: false }.
  3. If IsGenericDescriptor(Desc) is true or IsDataDescriptor(Desc) is true, then
    1. If Desc does not have a [[Value]] field, set Desc.[[Value]] to like.[[Value]].
    2. If Desc does not have a [[Writable]] field, set Desc.[[Writable]] to like.[[Writable]].
  4. Else,
    1. If Desc does not have a [[Get]] field, set Desc.[[Get]] to like.[[Get]].
    2. If Desc does not have a [[Set]] field, set Desc.[[Set]] to like.[[Set]].
  5. If Desc does not have an [[Enumerable]] field, set Desc.[[Enumerable]] to like.[[Enumerable]].
  6. If Desc does not have a [[Configurable]] field, set Desc.[[Configurable]] to like.[[Configurable]].
  7. Return Desc.

6.2.6 The Lexical Environment and Environment Record Specification Types

The Lexical Environment and Environment Record types are used to explain the behaviour of name resolution in nested functions and blocks. These types and the operations upon them are defined in 8.1.

6.2.7 The Abstract Closure Specification Type

The abstract closure specification type is used to refer to algorithm steps together with a collection of values. Abstract closures are meta-values and are invoked using function application style such as closure(arg1, arg2). Like abstract operations, invocations perform the algorithm steps described by the abstract closure.

In algorithm steps that create an abstract closure, values are captured with the verb "capture" followed by a list of aliases. When an abstract closure is created, it captures the value that is associated with each alias at that time. In steps that specify the algorithm to be performed when an abstract closure is called, each captured value is referred to by the alias that was used to capture the value.

If an abstract closure returns a Completion Record, that Completion Record's [[Type]] must be either normal or throw.

Abstract closures are created inline as part of other algorithms, shown in the following example.

  1. Let addend be 41.
  2. Let closure be a new abstract closure with parameters (x) that captures addend and performs the following steps when called:
    1. Return x + addend.
  3. Let val be closure(1).
  4. Assert: val is 42.

6.2.8 Data Blocks

The Data Block specification type is used to describe a distinct and mutable sequence of byte-sized (8 bit) numeric values. A Data Block value is created with a fixed number of bytes that each have the initial value 0.

For notational convenience within this specification, an array-like syntax can be used to access the individual bytes of a Data Block value. This notation presents a Data Block value as a 0-origined integer-indexed sequence of bytes. For example, if db is a 5 byte Data Block value then db[2] can be used to access its 3rd byte.

A data block that resides in memory that can be referenced from multiple agents concurrently is designated a Shared Data Block. A Shared Data Block has an identity (for the purposes of equality testing Shared Data Block values) that is address-free: it is tied not to the virtual addresses the block is mapped to in any process, but to the set of locations in memory that the block represents. Two data blocks are equal only if the sets of the locations they contain are equal; otherwise, they are not equal and the intersection of the sets of locations they contain is empty. Finally, Shared Data Blocks can be distinguished from Data Blocks.

The semantics of Shared Data Blocks is defined using Shared Data Block events by the memory model. Abstract operations below introduce Shared Data Block events and act as the interface between evaluation semantics and the event semantics of the memory model. The events form a candidate execution, on which the memory model acts as a filter. Please consult the memory model for full semantics.

Shared Data Block events are modeled by Records, defined in the memory model.

The following abstract operations are used in this specification to operate upon Data Block values:

6.2.8.1 CreateByteDataBlock ( size )

When the abstract operation CreateByteDataBlock is called with integer argument size, the following steps are taken:

  1. Assert: size ≥ 0.
  2. Let db be a new Data Block value consisting of size bytes. If it is impossible to create such a Data Block, throw a RangeError exception.
  3. Set all of the bytes of db to 0.
  4. Return db.

6.2.8.2 CreateSharedByteDataBlock ( size )

When the abstract operation CreateSharedByteDataBlock is called with integer argument size, the following steps are taken:

  1. Assert: size ≥ 0.
  2. Let db be a new Shared Data Block value consisting of size bytes. If it is impossible to create such a Shared Data Block, throw a RangeError exception.
  3. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
  4. Let eventList be the [[EventList]] field of the element in execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
  5. Let zero be « 0 ».
  6. For each index i of db, do
    1. Append WriteSharedMemory { [[Order]]: Init, [[NoTear]]: true, [[Block]]: db, [[ByteIndex]]: i, [[ElementSize]]: 1, [[Payload]]: zero } to eventList.
  7. Return db.

6.2.8.3 CopyDataBlockBytes ( toBlock, toIndex, fromBlock, fromIndex, count )

When the abstract operation CopyDataBlockBytes is called, the following steps are taken:

  1. Assert: fromBlock and toBlock are distinct Data Block or Shared Data Block values.
  2. Assert: fromIndex, toIndex, and count are integer values ≥ 0.
  3. Let fromSize be the number of bytes in fromBlock.
  4. Assert: fromIndex + countfromSize.
  5. Let toSize be the number of bytes in toBlock.
  6. Assert: toIndex + counttoSize.
  7. Repeat, while count > 0
    1. If fromBlock is a Shared Data Block, then
      1. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
      2. Let eventList be the [[EventList]] field of the element in execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
      3. Let bytes be a List of length 1 that contains a nondeterministically chosen byte value.
      4. NOTE: In implementations, bytes is the result of a non-atomic read instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
      5. Let readEvent be ReadSharedMemory { [[Order]]: Unordered, [[NoTear]]: true, [[Block]]: fromBlock, [[ByteIndex]]: fromIndex, [[ElementSize]]: 1 }.
      6. Append readEvent to eventList.
      7. Append Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: bytes } to execution.[[ChosenValues]].
      8. If toBlock is a Shared Data Block, then
        1. Append WriteSharedMemory { [[Order]]: Unordered, [[NoTear]]: true, [[Block]]: toBlock, [[ByteIndex]]: toIndex, [[ElementSize]]: 1, [[Payload]]: bytes } to eventList.
      9. Else,
        1. Set toBlock[toIndex] to bytes[0].
    2. Else,
      1. Assert: toBlock is not a Shared Data Block.
      2. Set toBlock[toIndex] to fromBlock[fromIndex].
    3. Set toIndex to toIndex + 1.
    4. Set fromIndex to fromIndex + 1.
    5. Set count to count - 1.
  8. Return NormalCompletion(empty).