Stage 2 Draft / September 7, 2021

Record & Tuple

1 Overview

1.1 ECMAScript Overview

ECMAScript is object-based: basic language and host facilities are provided by objects, and an ECMAScript program is a cluster of communicating objects. In ECMAScript, an object is a collection of zero or more properties each with attributes that determine how each property can be used—for example, when the Writable attribute for a property is set to false, any attempt by executed ECMAScript code to assign a different value to the property fails. Properties are containers that hold other objects, primitive values, or functions. A primitive value is a member of one of the following built-in types: Undefined, Null, Boolean, Number, BigInt, String, and Symbol;, Record, Tuple and Box; an object is a member of the built-in type Object; and a function is a callable object. A function that is associated with an object via a property is called a method.

ECMAScript defines a collection of built-in objects that round out the definition of ECMAScript entities. These built-in objects include the global object; objects that are fundamental to the runtime semantics of the language including Object, Function, Boolean, Symbol, Record, Tuple, Box and various Error objects; objects that represent and manipulate numeric values including Math, Number, and Date; the text processing objects String and RegExp; objects that are indexed collections of values including Array and nine different kinds of Typed Arrays whose elements all have a specific numeric data representation; keyed collections including Map and Set objects; objects supporting structured data including the JSON object, ArrayBuffer, SharedArrayBuffer, and DataView; objects supporting control abstractions including generator functions and Promise objects; and reflection objects including Proxy and Reflect.

1.2 Terms and Definitions

1.2.1 Record value

primitive value which is a mapping from Strings to ECMAScript primitive values

Note

a record value is completely immutable and will not change over time

1.2.2 Record type

set of all Record values

1.2.3 Record object

member of the Object type that is an instance of the standard built-in Record constructor

Note

A Record object is created by using the Object function in a call expression, supplying an Record value as an argument. The resulting object has an internal slot whose value is the Record value. A Record object can be coerced to a Record value by calling the Record constructor as a function (8.1.1.1).

1.2.4 Tuple value

primitive value which is an ordered sequence of ECMAScript primitive values

Note

a tuple value is completely immutable and will not change over time

1.2.5 Tuple type

set of all Tuple values

1.2.6 Tuple object

member of the Object type that is an instance of the standard built-in Tuple constructor

Note

A Tuple object is created by using the Object function in a call expression, supplying an Tuple value as an argument. The resulting object has an internal slot whose value is the Tuple value.

1.2.7 Box value

primitive value which contains an ECMAScript value

Note

A box is immutable and it will always contain the same reference over time. However, it does not guarantee that mutable referenced values will not be mutated.

1.2.8 Box type

set of all Box values

1.2.9 Box object

member of the Object type that is an instance of the standard built-in Box constructor

Note

A Box object is created by using the Object function in a call expression, supplying an Box value as an argument. The resulting object has an internal slot whose value is the Box value.

2 ECMAScript Data Types and Values

2.1 ECMAScript Language Types

2.1.1 The Record Type

The Record type is the set of all finite mappings from Strings to ECMAScript primitive values including Record and Tuple. Each record value holds an associated [[Fields]] List value which is a list of pairs of the form { [[Key]], [[Value]] } where the [[Key]] is a String and [[Value]] is any primitive value. Entries of [[Fields]] are sorted by [[Key]] in code unit order. The [[Fields]] List and its entries are never modified.

2.1.1.1 RecordToString ( argument )

The abstract operation RecordToString takes argument argument (a Record). It convertes argument to a String. It performs the following steps when called:

  1. Return "[object Record]".

2.1.1.2 RecordEqual ( x, y, elementEqual )

The abstract operation RecordEqual takes arguments x (a Record), y (a Record), and elementEqual (an Abstract Closure). It performs the following steps when called:

  1. Let xList be x.[[Fields]].
  2. Let yList be y.[[Fields]].
  3. Let xLen be the length of List xList.
  4. Let yLen be the length of List yList.
  5. If xLenyLen, return false.
  6. Let k be 0.
  7. Repeat, while k < xLen,
    1. Let xField be xList[k].
    2. Let yField be yList[k].
    3. Let xKey be xField.[[Key]].
    4. Let yKey be yField.[[Key]].
    5. Let xValue be xField.[[Value]].
    6. Let yValue be yField.[[Value]].
    7. If ! SameValueNonGeneric(xKey, yKey) is false, Return false.
    8. If ! elementEqual(xValue, yValue) is false, Return false.
    9. Set k to k + 1.
  8. Return true.

2.1.1.3 RecordSameValue ( x, y )

The abstract operation RecordSameValue takes arguments x (a Record) and y (a Record). It performs the following steps when called:

  1. Let elementEqual be a new Abstract Closure with parameters (elementX, elementY) that captures no values and performs the following steps when called:
    1. Return ! SameValue(elementX, elementY).
  2. Return ! RecordEqual(x, y, elementEqual).

2.1.1.4 RecordSameValueZero ( x, y )

The abstract operation RecordSameValueZero takes arguments x (a Record) and y (a Record). It performs the following steps when called:

  1. Let elementEqual be a new Abstract Closure with parameters (elementX, elementY) that captures no values and performs the following steps when called:
    1. Return ! SameValueZero(elementX, elementY).
  2. Return ! RecordEqual(x, y, elementEqual).

2.1.2 The Tuple Type

The Tuple type is the set of all finite and ordered sequences of ECMAScript primitive values including Record and Tuple. Each tuple value holds an associated [[Sequence]] List which is a list of primitive values. The [[Sequence]] List is integer-indexed. The [[Sequence]] List and its values are never modified.

2.1.2.1 TupleToString ( argument )

The abstract operation TupleToString takes argument argument (a Tuple). It performs the following steps when called:

  1. Return ? Call(%Array.prototype.join%, argument, « »).

2.1.2.2 TupleEqual ( x, y, elementEqual )

The abstract operation TupleEqual takes arguments x (a Tuple), y (a Tuple), and elementEqual (an Abstract Closure). It performs the following steps when called:

  1. Let xList be x.[[Sequence]].
  2. Let yList be y.[[Sequence]].
  3. Let xLen be the length of List xList.
  4. Let yLen be the length of List yList.
  5. If xLenyLen, Return false.
  6. Let k be 0.
  7. Repeat, while k < xLen,
    1. Let xItem be xList[k].
    2. Let yItem be yList[k].
    3. If ! elementEqual(xValue, yValue) is false, Return false.
    4. Set k to k + 1.
  8. Return true.

2.1.2.3 TupleSameValue ( x, y )

The abstract operation TupleSameValue takes arguments x (a Tuple) and y (a Tuple). It performs the following steps when called:

  1. Let elementEqual be a new Abstract Closure with parameters (elementX, elementY) that captures no values and performs the following steps when called:
    1. Return ! SameValue(elementX, elementY).
  2. Return ! TupleEqual(x, y, elementEqual).

2.1.2.4 TupleSameValueZero ( x, y )

The abstract operation TupleSameValueZero takes arguments x (a Tuple) and y (a Tuple). It performs the following steps when called:

  1. Let elementEqual be a new Abstract Closure with parameters (elementX, elementY) that captures no values and performs the following steps when called:
    1. Return ! SameValueZero(elementX, elementY).
  2. Return ! TupleEqual(x, y, elementEqual).

2.1.3 The Box Type

The Box type is the set of all the possible singleton primitive wrappers around any ECMAScript value. Each box value holds an associated [[Value]] containing an ECMAScript value. The [[Value]] internal slot is never modified.

2.1.3.1 BoxToString ( argument )

The abstract operation BoxToString takes argument argument (a Box). It performs the following steps when called:

  1. Let valueString be ? ToString(argument.[[Value]]).
  2. Return the string-concatenation of "Box(", valueString, and ")".

2.1.3.2 BoxSameValue ( x, y )

The abstract operation BoxSameValue takes arguments x (a Box) and y (a Box). It performs the following steps when called:

  1. Let xValue be x.[[Value]].
  2. Let yValue be y.[[Value]].
  3. Return ! SameValue(xValue, yValue.)

2.1.3.3 BoxSameValueZero ( x, y )

The abstract operation BoxSameValueZero takes arguments x (a Box) and y (a Box). It performs the following steps when called:

  1. Let xValue be x.[[Value]].
  2. Let yValue be y.[[Value]].
  3. Return ! SameValueZero(xValue, yValue.)

3 Abstract Operations

3.1 Type Conversion

The ECMAScript language implicitly performs automatic type conversion as needed. To clarify the semantics of certain constructs it is useful to define a set of conversion abstract operations. The conversion abstract operations are polymorphic; they can accept a value of any ECMAScript language type. But no other specification types are used with these operations.

The BigInt , Record, Tuple, and Box types hashave no implicit conversions in the ECMAScript language; programmers must call BigInt , Record, Tuple, or Box explicitly to convert values from other types.

3.1.1 ToBoolean ( argument )

The abstract operation ToBoolean takes argument argument. It converts argument to a value of type Boolean according to Table 1:

Table 1: ToBoolean Conversions
Argument Type Result
Undefined Return false.
Null Return false.
Boolean Return argument.
Number If argument is +0, -0, or NaN, return false; otherwise return true.
String If argument is the empty String (its length is zero), return false; otherwise return true.
Symbol Return true.
BigInt If argument is 0n, return false; otherwise return true.
Record Return true.
Tuple Return true.
Box Return true.
Object Return true.

3.1.2 ToNumber ( argument )

The abstract operation ToNumber takes argument argument. It converts argument to a value of type Number according to Table 2:

Table 2: ToNumber Conversions
Argument Type Result
Undefined Return NaN.
Null Return +0.
Boolean If argument is true, return 1. If argument is false, return +0.
Number Return argument (no conversion).
String See grammar and conversion algorithm below.
Symbol Throw a TypeError exception.
BigInt Throw a TypeError exception.
Record Throw a TypeError exception.
Tuple Throw a TypeError exception.
Box Throw a TypeError exception.
Object

Apply the following steps:

  1. Let primValue be ? ToPrimitive(argument, hint Number).
  2. Return ? ToNumber(primValue).

3.1.3 ToBigInt ( argument )

The abstract operation ToBigInt takes argument argument. It converts argument to a BigInt value, or throws if an implicit conversion from Number would be required. It performs the following steps when called:

  1. Let prim be ? ToPrimitive(argument, hint Number).
  2. Return the value that prim corresponds to in Table 3.
Table 3: BigInt Conversions
Argument Type Result
Undefined Throw a TypeError exception.
Null Throw a TypeError exception.
Boolean Return 1n if prim is true and 0n if prim is false.
BigInt Return prim.
Number Throw a TypeError exception.
String
  1. Let n be ! StringToBigInt(prim).
  2. If n is NaN, throw a SyntaxError exception.
  3. Return n.
Symbol Throw a TypeError exception.
Record Throw a TypeError exception.
Tuple Throw a TypeError exception.
Box Throw a TypeError exception.

3.1.4 ToString ( argument )

The abstract operation ToString takes argument argument. It converts argument to a value of type String according to Table 4:

Table 4: ToString Conversions
Argument Type Result
Undefined Return "undefined".
Null Return "null".
Boolean

If argument is true, return "true".

If argument is false, return "false".

Number Return ! Number::toString(argument).
String Return argument.
Symbol Throw a TypeError exception.
BigInt Return ! BigInt::toString(argument).
Record Return ! RecordToString(argument).
Tuple Return ? TupleToString(argument).
Box Return ? BoxToString(argument).
Object

Apply the following steps:

  1. Let primValue be ? ToPrimitive(argument, hint String).
  2. Return ? ToString(primValue).

3.1.5 ToObject ( argument )

The abstract operation ToObject takes argument argument. It converts argument to a value of type Object according to Table 5:

Table 5: ToObject Conversions
Argument Type Result
Undefined Throw a TypeError exception.
Null Throw a TypeError exception.
Boolean Return a new Boolean object whose [[BooleanData]] internal slot is set to argument. See 19.3 for a description of Boolean objects.
Box Return a new Box object whose [[BoxData]] internal slot is set to argument. See 8.3 for a description of Box objects.
Number Return a new Number object whose [[NumberData]] internal slot is set to argument. See 20.1 for a description of Number objects.
String Return a new String object whose [[StringData]] internal slot is set to argument. See 21.1 for a description of String objects.
Symbol Return a new Symbol object whose [[SymbolData]] internal slot is set to argument. See 19.4 for a description of Symbol objects.
BigInt Return a new BigInt object whose [[BigIntData]] internal slot is set to argument. See 20.2 for a description of BigInt objects.
Record Return a new Record object whose [[RecordData]] internal slot is set to argument. See 8.1 for a description of Record objects.
Tuple Return a new Tuple object whose [[TupleData]] internal slot is set to argument. See 8.2 for a description of Tuple objects.
Box Return a new Box object whose [[BoxData]] internal slot is set to argument. See 8.3 for a description of Box objects.
Object Return argument.

3.2 Testing and Comparison Operations

3.2.1 RequireObjectCoercible ( argument )

The abstract operation RequireObjectCoercible takes argument argument. It throws an error if argument is a value that cannot be converted to an Object using ToObject. It is defined by Table 6:

Table 6: RequireObjectCoercible Results
Argument Type Result
Undefined Throw a TypeError exception.
Null Throw a TypeError exception.
Boolean Return argument.
Number Return argument.
String Return argument.
Symbol Return argument.
BigInt Return argument.
Record Return argument.
Tuple Return argument.
Box Return argument.
Object Return argument.

3.2.2 SameValue ( x, y )

The abstract operation SameValue takes arguments x (an ECMAScript language value) and y (an ECMAScript language value). It returns a completion record whose [[Type]] is normal and whose [[Value]] is a Boolean. It performs the following steps when called:

  1. If Type(x) is different from Type(y), return false.
  2. If Type(x) is Number or BigInt, then return ! Type(x)::sameValue(x, y).
  3. If Type(x) is Record, then return ! RecordSameValue(x, y).
  4. If Type(x) is Tuple, then return ! TupleSameValue(x, y).
  5. If Type(x) is Box, then return ! BoxSameValue(x, y).
  6. Return ! SameValueNonNumeric(x, y).
  7. Return ! SameValueNonGeneric(x, y).
Note

This algorithm differs from the Strict Equality Comparison Algorithm in its treatment of signed zeroes and NaNs.

3.2.3 SameValueZero ( x, y )

The abstract operation SameValueZero takes arguments x (an ECMAScript language value) and y (an ECMAScript language value). It returns a completion record whose [[Type]] is normal and whose [[Value]] is a Boolean. It performs the following steps when called:

  1. If Type(x) is different from Type(y), return false.
  2. If Type(x) is Number or BigInt, then return ! Type(x)::sameValueZero(x, y).
  3. If Type(x) is Record, then return ! RecordSameValueZero(x, y).
  4. If Type(x) is Tuple, then return ! TupleSameValueZero(x, y).
  5. If Type(x) is Box, then return ! BoxSameValueZero(x, y).
  6. Return ! SameValueNonNumeric(x, y).
  7. Return ! SameValueNonGeneric(x, y).
Note

SameValueZero differs from SameValue only in its treatment of +0 and -0, and the treatment of those values inside a Record or Tuple.

3.2.4 SameValueNonNumericSameValueNonGeneric ( x, y )

The abstract operation SameValueNonNumericSameValueNonGeneric takes arguments x (an ECMAScript language value, but not a Number or a BigInt) and y (an ECMAScript language value, but not a Number or a BigInt). It returns a completion record whose [[Type]] is normal and whose [[Value]] is a Boolean. It performs the following steps when called:

  1. Assert: Type(x) is not Number or BigInt.
  2. Assert: Type(x) is the same as Type(y).
  3. If Type(x) is Undefined, return true.
  4. If Type(x) is Null, return true.
  5. If Type(x) is String, then
    1. If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.
  6. If Type(x) is Boolean, then
    1. If x and y are both true or both false, return true; otherwise, return false.
  7. If Type(x) is Symbol, then
    1. If x and y are both the same Symbol value, return true; otherwise, return false.
  8. If x and y are the same Object value, return true. Otherwise, return false.

3.2.5 IsLooselyEqual ( x, y )

The abstract operation IsLooselyEqual takes arguments x (an ECMAScript language value) and y (an ECMAScript language value). It provides the semantics for the comparison x == y, returning true or false. It performs the following steps when called:

  1. If Type(x) is the same as Type(y), then
    1. Return IsStrictlyEqual(x, y).
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.
  4. NOTE: This step is replaced in section B.3.7.2.
  5. If Type(x) is Number and Type(y) is String, return IsLooselyEqual(x, ! ToNumber(y)).
  6. If Type(x) is String and Type(y) is Number, return IsLooselyEqual(! ToNumber(x), y).
  7. If Type(x) is BigInt and Type(y) is String, then
    1. Let n be ! StringToBigInt(y).
    2. If n is NaN, return false.
    3. Return IsLooselyEqual(x, n).
  8. If Type(x) is String and Type(y) is BigInt, return IsLooselyEqual(y, x).
  9. If Type(x) is Boolean, return IsLooselyEqual(! ToNumber(x), y).
  10. If Type(y) is Boolean, return IsLooselyEqual(x, ! ToNumber(y)).
  11. If Type(x) is either String, Number, BigInt, Record, Tuple, Box, or Symbol and Type(y) is Object, return IsLooselyEqual(x, ? ToPrimitive(y)).
  12. If Type(x) is Object and Type(y) is either String, Number, BigInt, Record, Tuple, Box, or Symbol, return IsLooselyEqual(? ToPrimitive(x), y).
  13. If Type(x) is BigInt and Type(y) is Number, or if Type(x) is Number and Type(y) is BigInt, then
    1. If x or y are any of NaN, +∞𝔽, or -∞𝔽, return false.
    2. If (x) = (y), return true; otherwise return false.
  14. Return false.

3.2.6 IsStrictlyEqual ( x, y )

The abstract operation IsStrictlyEqual takes arguments x (an ECMAScript language value) and y (an ECMAScript language value). It provides the semantics for the comparison x === y, returning true or false. It performs the following steps when called:

  1. If Type(x) is different from Type(y), return false.
  2. If Type(x) is Number or BigInt, then
    1. Return ! Type(x)::equal(x, y).
  3. If Type(x) is Record, Tuple or Box, then
    1. Return ! Type(x)::sameValueZero(x, y).
  4. Return ! SameValueNonNumeric(x, y).
  5. Return ! SameValueNonGeneric(x, y).
Note

This algorithm differs from the SameValue Algorithm in its treatment of signed zeroes and NaNs.

3.3 Operations on Records

3.3.1 CreateRecord ( entries )

The abstract operation CreateRecord takes argument entries (a List of { [[Key]], [[Value]] } records). It is used to create a Record value ensuring that its fields are sorted. It performs the following steps when called:

  1. Let sortedEntries be a new List containing the values of entries sorted such that, for any entry two entries a and b, a will be placed before b if the result of performing Abstract Relational Comparison a.[[Key]] < b.[[Key]] is true.
  2. Return a new Record value whose [[Fields]] is sortedEntries.

3.3.2 AddPropertyIntoRecordEntriesList ( entries, propName, value )

The abstract operation AddPropertyIntoRecordEntriesList takes arguments entries (a List of { [[Key]], [[Value]] } records), propName (a property key), and value (an ECMAScript language value). It is used during a single assignment into a Record literal expression. It performs the following steps when called:

  1. If Type(propName) is Symbol, throw a TypeError exception.
  2. If Type(value) is Object, throw a TypeError exception.
  3. Add { [[Key]]: propType, [[Value]]: value } to entries.
  4. Return entries.

3.4 Operations on Tuples

3.4.1 AddValueToTupleSequenceList ( sequence, value )

The abstract operation AddValueToTupleSequenceList takes arguments sequence (a List of ECMAScript language values) and value (an ECMAScript language value). It is used during a single addition in a Tuple literal expression. It performs the following steps when called:

  1. If Type(value) is Object, throw a TypeError exception.
  2. Add value to sequence.
  3. Return sequence.

3.5 IsTuple ( O )

The abstract operation IsTuple takes argument O (an ECMAScript language value). It performs the following steps when called:

  1. If Type(O) is Tuple or Type(O) is Object and O has a [[TupleData]] internal slot, return true.
  2. Return false.

3.6 IsConcatSpreadable ( O )

The abstract operation IsConcatSpreadable takes argument O. It performs the following steps when called:

  1. If Type(O) is not Object or Tuple, return false
  2. Let spreadable be ? GetV(O, @@isConcatSpreadable).
  3. If spreadable is not undefined, return ! ToBoolean(spreadable).
  4. If ! IsTuple(O), return true
  5. If ? IsArray(O).

4 Ordinary and Exotic Objects Behaviours

4.1 Built-in Exotic Object Internal Methods and Slots

4.1.1 Record Exotic Objects

A Record object is an exotic object that encapsuates a Record value and exposes virtual string-indexed data properties corresponding to the individual keys set on the underlying Record value. All keys properties are non-writable and non-configurable.

An object is a Record exotic object (or simply, a Record object) if its following internal methods use the following implementations and is an Immutable Prototype Exotic Object. These methods are installed in RecordCreate.

Record exotic objects have the same internal slots as ordinary objects. They also have a [[RecordData]] internal slot.

4.1.1.1 [[IsExtensible]] ()

The [[IsExtensible]] internal method of a Record exotic object takes no arguments. It performs the following steps when called:

  1. Return false.

4.1.1.2 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of a Record exotic object takes argument P. It performs the following steps when called:

  1. Assert: IsPropertyKey(P) is true.
  2. If Type(P) is a Symbol, return undefined.
  3. Let getResult be ! RecordGet(R, P).
  4. If getResult is empty, return undefined.
  5. Return the PropertyDescriptor { [[Value]]: getResult, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }.

4.1.1.3 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of a Record exotic object takes arguments P and Desc. It performs the following steps when called:

  1. Assert: IsPropertyKey(P) is true.
  2. If Type(P) is a Symbol, return false.
  3. If Desc.[[Writable]] is present and has value true, return false.
  4. If Desc.[[Enumerable]] is present and has value false, return false.
  5. If Desc.[[Configurable]] is present and has value true, return false.
  6. If IsAccessorDescriptor(Desc) is true, return false.
  7. Let current be ! RecordGet(R, P).
  8. If current is empty return false.
  9. If Desc.[[Value]] is present, return ! SameValue(Desc.[[Value]], current).
  10. Return false.

4.1.1.4 [[HasProperty]] ( P )

The [[HasProperty]] internal method of a Record exotic object takes argument P. It performs the following steps when called:

  1. Assert: IsPropertyKey(P) is true.
  2. Return ! RecordHasProperty(R, P).

4.1.1.5 [[Get]] ( P, Receiver )

  1. Assert: IsPropertyKey(P) is true.
  2. If Type(P) is a Symbol, return undefined.
  3. Let value be ! RecordGet( R, P ).
  4. If value is empty, return undefined.
  5. Return value

4.1.1.6 [[Set]] ( P, Receiver )

The [[Set]] internal method of a Record exotic object takes arguments P and Receiver. It performs the following steps when called:

  1. Return false.

4.1.1.7 [[Delete]] ( P )

The [[Delete]] internal method of a Record exotic object takes argument P. It performs the following steps when called:

  1. Assert: IsPropertyKey(P) is true.
  2. Let hasPropertyRecordHasProperty( R, P ).
  3. If hasProperty is false, return true.
  4. Return false.

4.1.1.8 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of a Record exotic object takes no arguments. It performs the following steps when called:

  1. Let keys be a new empty List.
  2. Let rec be R.[[RecordData]].
  3. Assert: Type(rec) is Record.
  4. For each entry of rec.[[Fields]], do
    1. Let key be entry.[[Key]]
    2. Assert: Type(key) is String
    3. Append key to keys.
  5. Return keys

4.1.1.9 RecordCreate ( value )

The abstract operation RecordCreate takes argument value (a Record). It is used to specify the creation of new Record exotic objects. It performs the following steps when called:

  1. Let R be ! MakeBasicObject(« [[RecordData]], [[Prototype]] »).
  2. Set R's essential internal methods to the definitions specified in 4.1.1.
  3. Set R.[[Prototype]] to null.
  4. Set R.[[RecordData]] to value.
  5. Return R.

4.1.1.10 RecordHasProperty ( R, P )

The abstract operation RecordHasProperty takes arguments R (a Record) and P (a PropertyKey). It performs the following steps when called:

  1. If Type(P) is a Symbol, return false.
  2. Let rec be R.[[RecordData]].
  3. Assert Type(rec) is a Record.
  4. For each entry of rec.[[Fields]], do
    1. Let key be entry.[[Key]]
    2. If ! SameValue(key, P) is true, return true.
  5. Return false.

4.1.1.11 RecordGet ( R, P )

The abstract operation RecordGet takes arguments R (a Record) and P (a PropertyKey). It performs the following steps when called:

  1. Assert: R is an Object that has [[RecordData]] internal slot.
  2. Assert: Type(P) is String.
  3. Let rec be R.[[RecordData]].
  4. Assert Type(rec) is Record.
  5. Let len be the length of rec.
  6. For each entry of rec.[[Fields]], do:
    1. Let key be entry.[[Key]].
    2. Let val be entry.[[Value]].
    3. Assert: Type(key) is String.
    4. Assert: Type(val) is not Object.
    5. If key is P, return val.
  7. Return empty.

4.1.2 Tuple Exotic Objects

A Tuple object is an exotic object that encapsulates a Tuple value and exposes virtual integer-indexed data properties corresponding to the individual entries set on the underlying Tuple value. All keys properties are non-writable and non-configurable.

An object is a Tuple exotic object (or simply, a Tuple object) if its following internal methods use the following implementations and is an Immutable Prototype Exotic Object.

Tuple exotic objects have the same internal slots as ordinary objects. They also have a [[TupleData]] internal slot.

4.1.2.1 [[IsExtensible]] ()

When the [[IsExtensible]] internal method of a Tuple exotic object T is called, the following steps are taken:

  1. Return false.

4.1.2.2 [[GetOwnProperty]] ( P )

When the [[GetOwnProperty]] internal method of a Tuple exotic object T is called with property key P, the following steps are taken:

  1. Assert: IsPropertyKey(P) is true.
  2. If Type(P) is a Symbol, return false.
  3. Let numericIndex be ! CanonicalNumericIndexString(P).
  4. If numericIndex is undefined, return undefined.
  5. Let value be ? TupleGet(T, numericIndex)
  6. If value is empty, return undefined.
  7. Return the PropertyDescriptor { [[Value]]: value, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }.

4.1.2.3 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of a Tuple exotic object takes arguments P and Desc. It performs the following steps when called:

  1. Assert: IsPropertyKey(P) is true.
  2. If Type(P) is a Symbol, return false.
  3. If Desc.[[Writable]] is present and has value true, return false.
  4. If Desc.[[Enumerable]] is present and has value false, return false.
  5. If Desc.[[Configurable]] is present and has value true, return false.
  6. Let numericIndex be ! CanonicalNumericIndexString(P).
  7. If numericIndex is undefined, return false.
  8. Let current be ? TupleGet(T, numericIndex)
  9. If current is empty return false.
  10. If IsAccessorDescriptor(Desc) is true, return false.
  11. If Desc.[[Value]] is present, return ! SameValue(Desc.[[Value]], current).
  12. Return false.

4.1.2.4 [[HasProperty]] ( P )

The [[HasProperty]] internal method of a Tuple exotic object takes argument P. It performs the following steps when called:

  1. Assert: IsPropertyKey(P) is true.
  2. If Type(P) is not Symbol, then
    1. Let numericIndex be ! CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, return ? IsValidTupleIndex(T, numericIndex)
  3. Let parent be ? T.[[GetPrototypeOf]]().
  4. Return ? parent.[[HasProperty]](P).

4.1.2.5 [[Get]] ( P, Receiver )

The [[Get]] internal method of a Tuple exotic object takes arguments P and Receiver. It performs the following steps when called:

  1. Assert: IsPropertyKey(P) is true.
  2. If Type(P) is not Symbol, then
    1. Let numericIndex be ! CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, then
      1. Let value be ? TupleGet(T, numericIndex).
      2. If value is empty, return undefined.
      3. Return value.
  3. Let parent be ? T.[[GetPrototypeOf]]().
  4. Return ? parent.[[Get]](P, Receiver).

4.1.2.6 [[Set]] ( P, Receiver )

The [[Set]] internal method of a Tuple exotic object takes arguments P and Receiver. It performs the following steps when called:

  1. Assert: IsPropertyKey(P) is true.
  2. Return false.

4.1.2.7 [[Delete]] ( P )

The [[Delete]] internal method of a Tuple exotic object takes argument P. It performs the following steps when called:

  1. Assert: IsPropertyKey(P) is true.
  2. If Type(P) is a Symbol, return true.
  3. Let numericIndex be ! CanonicalNumericIndexString(P).
  4. If numericIndex is undefined, return true.
  5. Let isValidIndexIsValidTupleIndex( T, numericIndex ).
  6. If isValidIndex is false, return true.
  7. Return false.

4.1.2.8 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of a Tuple exotic object takes no arguments. It performs the following steps when called:

  1. Let keys be a new empty List.
  2. Let tup be T.[[TupleData]].
  3. Assert: Type(tup) is Tuple.
  4. Let len be the length of tup.[[Sequence]].
  5. Let index be 0.
  6. Repeat, while index < len,
    1. Add ! ToString(index) to keys.
    2. Set index to index + 1.
  7. Return keys

4.1.2.9 TupleCreate ( value )

The abstract operation TupleCreate takes argument value (a Tuple). It is used to specify the creation of new Tuple exotic objects. It performs the following steps when called:

  1. Let T be ! MakeBasicObject(« [[TupleData]], [[Prototype]] »).
  2. Set T's essential internal methods to the definitions specified in 4.1.2.
  3. Set T.[[Prototype]] to %Tuple.prototype%.
  4. Set T.[[TupleData]] to value.
  5. Return T.

4.1.2.10 IsValidTupleIndex ( T, numericIndex )

The abstract operation IsValidTupleIndex takes arguments T (a Tuple object) and numericIndex (an integer). It performs the following steps when called:

  1. If numericIndex is -0, return false.
  2. If numericIndex < 0 or numericIndex ≥ the length of T.[[TupleData]].[[Sequence]], return false.
  3. Return true.

4.1.2.11 TupleGet ( T, numericIndex )

The abstract operation TupleGet takes arguments T (a Tuple object) and numericIndex (an integer). It performs the following steps when called:

  1. Let tup be T.[[TupleData]].
  2. If ! IsValidTupleIndex(numericIndex) is false, return empty.
  3. Let value be the element with index numericIndex in tup.[[Sequence]].
  4. Return value.

4.1.3 Box Exotic Objects

A Box object is an exotic object that encapsuates a Box value and exposes virtual integer-indexed data properties corresponding to the individual entries set on the underlying Box value. All keys properties are non-writable and non-configurable.

An object is a Box exotic object (or simply, a Box object) if its following internal methods use the following implementations and it is an Immutable Prototype Exotic Object.

Box exotic objects have the same internal slots as ordinary objects. They also have a [[BoxData]] internal slot.

4.1.3.1 [[IsExtensible]] ()

The [[IsExtensible]] internal method of a Box exotic object takes no arguments. It performs the following steps when called:

  1. Return false.

4.1.3.2 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of a Box exotic object takes argument P. It performs the following steps when called:

  1. Return false.

4.1.3.3 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of a Box exotic object takes arguments P and Desc. It performs the following steps when called:

  1. Return false.

4.1.3.4 [[HasProperty]] ( P )

The [[HasProperty]] internal method of a Box exotic object takes argument P. It performs the following steps when called:

  1. Assert: IsPropertyKey(P) is true.
  2. Let parent be %Box.prototype%.
  3. Return ? parent.[[HasProperty]](P).

4.1.3.5 [[Get]] ( P, Receiver )

The [[Get]] internal method of a Box exotic object takes arguments P and Receiver. It performs the following steps when called:

  1. Assert: IsPropertyKey(P) is true.
  2. Let parent be ? %Box.prototype%.
  3. Return ? parent.[[Get]](P, Receiver).

4.1.3.6 [[Set]] ( P, Receiver )

The [[Set]] internal method of a Box exotic object takes arguments P and Receiver. It performs the following steps when called:

  1. Return false.

4.1.3.7 [[Delete]] ( P )

The [[Delete]] internal method of a Box exotic object takes argument P. It performs the following steps when called:

  1. Return true.

4.1.3.8 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of a Box exotic object takes no arguments. It performs the following steps when called:

  1. Return a new empty List.

5 ECMAScript Language: Lexical Grammar

5.1 Punctuators

Punctuator :: OptionalChainingPunctuator OtherPunctuator OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit] OtherPunctuator :: one of { ( ) [ ] #{ #[ . ... ; , < > <= >= == != === !== + - * % ** ++ -- << >> >>> & | ^ ! ~ && || ?? ? : = += -= *= %= **= <<= >>= >>>= &= |= ^= => DivPunctuator :: / /= RightBracePunctuator :: }

6 ECMAScript Language: Expressions

6.1 Primary Expression

Syntax

PrimaryExpression[Yield, Await] : this IdentifierReference[?Yield, ?Await] Literal ArrayLiteral[?Yield, ?Await] ObjectLiteral[?Yield, ?Await] RecordLiteral[?Yield, ?Await] TupleLiteral[?Yield, ?Await] FunctionExpression ClassExpression[?Yield, ?Await] GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral[?Yield, ?Await, ~Tagged] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]

6.1.1 Record Initializer

Syntax

RecordLiteral[Yield, Await] : #{ } #{ RecordPropertyDefinitionList[?Yield, ?Await] } #{ RecordPropertyDefinitionList[?Yield, ?Await] , } RecordPropertyDefinitionList[Yield, Await] : RecordPropertyDefinition[?Yield, ?Await] RecordPropertyDefinitionList[?Yield, ?Await] , RecordPropertyDefinition[?Yield, ?Await] RecordPropertyDefinition[Yield, Await] : IdentifierReference[?Yield, ?Await] PropertyName[?Yield, ?Await] : AssignmentExpression[+In, ?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await]

6.1.1.1 Runtime Semantics: Evaluation

RecordLiteral : #{ }
  1. Return a new Record value whose [[Fields]] value is an empty List.
RecordLiteral : #{ RecordPropertyDefinitionList } #{ RecordPropertyDefinitionList , }
  1. Let entries be an empty List.
  2. Perform ? RecordPropertyDefinitionEvaluation of RecordPropertyDefinitionList with argument entries.
  3. Let reversedEntries be entries in reverse.
  4. Let uniqueEntries be an empty List.
  5. For each kv in reversedEntries:
    1. Assert: Type(kv.[[Key]]) is String.
    2. Assert: Type(kv.[[Value]]) is not Object.
    3. If there is no entry existing in uniqueEntries such that existing.[[Key]] is kv.[[Key]], append kv to uniqueEntries.
  6. Return ! CreateRecord(uniqueEntries).

6.1.1.2 Runtime Semantics: RecordPropertyDefinitionEvaluation

With parameter entries.

RecordPropertyDefinitionList : RecordPropertyDefinitionList , RecordPropertyDefinition
  1. Perform ? RecordPropertyDefinition of RecordPropertyDefinitionList with argument entries.
  2. Return the result of performing RecordPropertyDefinitionEvaluation of RecordPropertyDefinition with argument entries.
RecordPropertyDefinition : ... AssignmentExpression
  1. Let exprValue be the result of evaluating AssignmentExpression.
  2. Let source be ? GetValue(exprValue).
  3. If source is undefined or null, return entries.
  4. Let from be ! ToObject(source).
  5. Let keys be ? from.[[OwnPropertyKeys]]().
  6. For each element nextKey of keys in List order, do
    1. Let value be from.[[Get]](nextKey).
    2. Perform ? AddPropertyIntoRecordEntriesList(entries, nextKey, value).
  7. Return entries.
RecordPropertyDefinition : IdentifierReference
  1. Let propName be StringValue of IdentifierReference.
  2. Let exprValue be the result of evaluating IdentifierReference.
  3. Let propValue be ? GetValue(exprValue).
  4. Return ? AddPropertyIntoRecordEntriesList(record, propName, propValue).
RecordPropertyDefinition : PropertyName : AssignmentExpression
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let propValue be NamedEvaluation of AssignmentExpression with argument propKey.
  4. Else,
    1. Let exprValueRef be the result of evaluating AssignmentExpression.
    2. Let propValue be ? GetValue(exprValueRef).
  5. Return ? AddPropertyIntoRecordEntriesList(record, propKey, propValue).

6.1.2 Tuple Initializer

Syntax

TupleLiteral[Yield, Await] : #[ ] #[ TupleElementList[?Yield, ?Await] ] #[ TupleElementList[?Yield, ?Await] , ] TupleElementList[Yield, Await] : AssignmentExpression[+In, ?Yield, ?Await] SpreadElement[?Yield, ?Await] TupleElementList[?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] TupleElementList[?Yield, ?Await] , SpreadElement[?Yield, ?Await]

6.1.2.1 Runtime Semantics: TupleSequenceAccumulation

With parameter sequence.

TupleElementList : AssignmentExpression
  1. Let initResult be the result of evaluating AssignmentExpression.
  2. Let initValue be ? GetValue(initResult).
  3. Return ? AddValueToTupleSequenceList(sequence, value).
TupleElementList : SpreadElement
  1. Return the Result of performing TupleSequenceAccumulation for SpreadElement with argument sequence.
TupleElementList : TupleElementList , AssignmentExpression
  1. Perform TupleSequenceAccumulation for TupleElementList with argument sequence.
  2. Let initResult be the result of evaluating AssignmentExpression.
  3. Let initValue be ? GetValue(initResult).
  4. Return ? AddValueToTupleSequenceList(sequence, value).
TupleElementList : TupleElementList , SpreadElement
  1. Perform TupleSequenceAccumulation for TupleElementList with argument sequence.
  2. Return the Result of performing TupleSequenceAccumulation for SpreadElement with argument sequence.
SpreadElement : ... AssignmentExpression
  1. Let spreadRef be the result of evaluating AssignmentExpression.
  2. Let spreadObj be ? GetValue(spreadRef).
  3. Let iteratorRecord be ? GetIterator(spreadObj).
  4. Repeat,
    1. Let next be ? IteratorStep(iteratorRecord).
    2. If next is false, return sequence.
    3. Let nextValue be ? IteratorValue(next).
    4. Let completion be AddValueToTupleSequenceList(sequence, nextValue).
    5. If completion is an abrupt completion, then
      1. Return IteratorClose(iteratorRecord, completion).

6.1.2.2 Runtime Semantics: Evaluation

TupleLiteral : #[ ]
  1. Let sequence be an empty List.
  2. Let tup be a Tuple value whose [[Sequence]] value is sequence.
  3. Return tup.
TupleLiteral : #[ TupleElementList ] #[ TupleElementList , ]
  1. Let sequence be an empty List.
  2. Perform ? TupleSequenceAccumulation for TupleElementList with argument sequence.
  3. For each value in sequence,
    1. Assert: Type(value) is not Object.
  4. Let tup be a Tuple value whose [[Sequence]] value is sequence.
  5. Return tup.

7 Unary Operators

7.1 The typeof Operator

7.1.1 Runtime Semantics: Evaluation

UnaryExpression : typeof UnaryExpression
  1. Let val be the result of evaluating UnaryExpression.
  2. If Type(val) is Reference, then
    1. If IsUnresolvableReference(val) is true, return "undefined".
  3. Set val to ? GetValue(val).
  4. Return a String according to Table 7.
Table 7: typeof Operator Results
Type of val Result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol "symbol"
BigInt "bigint"
Record "record"
Tuple "tuple"
Box "box"
Object (does not implement [[Call]]) "object"
Object (implements [[Call]]) "function"

8 Immutable Data Structures

8.1 Record Objects

8.1.1 The Record Constructor

The Record constructor:

  • is the intrinsic object %Record%.
  • is the initial value of the "Record" property of the global object.
  • creates and initializes a new Record value when called as a function.
  • is not intended to be used with the new operator or to be subclassed. It may be used as the value of an extends clause of a class definition but a super call to the Record constructor will cause an exception.

8.1.1.1 Record ( arg )

When the Record function is called, the following steps are taken:

  1. If NewTarget is not undefined, throw a TypeError exception.
  2. Let obj be ? ToObject(arg).
  3. Let keys be ? obj.[[OwnPropertyKeys]]().
  4. Let fields be a new empty List.
  5. For each element key of keys,
    1. Let desc be ? obj.[[GetOwnProperty]](key).
    2. If desc is not undefined and desc.[[Enumerable]] is true, then
      1. If Type(key) is Symbol, throw a TypeError exception.
      2. Let value be ? Get(obj, key).
      3. If Type(value) is Object, throw a TypeError exception.
      4. Let field be the Record { [[Key]]: key, [[Value]]: value }.
      5. Append field to the end of list fields.
  6. Return ! CreateRecord(fields).

8.1.2 Properties of the Record Constructor

The Record constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

8.1.2.1 Record.fromEntries ( iterable )

The fromEntries function takes one argument iterable, and performs the following steps:

  1. Perform ? RequireObjectCoercible(iterable).
  2. Let fields be a new empty List.
  3. Let adder be a new Abstract Closure with parameters (key, value) that captures fields and performs the following steps when called:
    1. If Type(value) is Object, throw a TypeError exception.
    2. Let field be { [[Key]]: key, [[Value]]: value }.
    3. Append field to the end of list fields.
  4. Perform ! AddEntriesFromIterable(undefined, iterable, adder).
  5. Return ! CreateRecord(fields).
Note

The parameter iterable is expected to be an object that implements an @@iterator method that returns an iterator object that produces a two element array-like object whose first element is a value that will be used as a Map key and whose second element is the value to associate with that key.

8.1.2.2 Record.isRecord ( arg )

The isRecord function takes one argument arg, and performs the following steps:

  1. If Type(arg) is Record, return true.
  2. If Type(arg) is Object and arg has a [[RecordData]] internal slot, return true.
  3. Return false.

8.1.2.3 Record.prototype

The initial value of Record.prototype is the value null.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

8.2 Tuple Objects

8.2.1 The Tuple Constructor

The Tuple constructor:

  • is the intrinsic object %Tuple%.
  • is the initial value of the "Tuple" property of the global object.
  • creates and initializes a new Tuple object when called as a function.
  • is not intended to be used with the new operator or to be subclassed. It may be used as the value of an extends clause of a class definition but a super call to the Tuple constructor will cause an exception.

8.2.1.1 Tuple ( ...items )

When the Tuple function is called with zero or more arguments, the following steps are taken:

  1. If NewTarget is not undefined, throw a TypeError exception.
  2. Let items be the List of arguments passed to this function.
  3. For each element e of items,
    1. If Type(e) is Object, throw a TypeError exception.
  4. Let tuple be a new Tuple value whose [[Sequence]] is items.
  5. Return tuple.

8.2.2 Properties of the Tuple Constructor

The Tuple constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

8.2.2.1 Tuple.isTuple ( arg )

The isTuple function takes one argument arg, and performs the following steps:

  1. Return ! IsTuple(arg).

8.2.2.2 Tuple.from ( items [ , mapFn [, thisArg ] ] )

When the from method is called with argument items and optional arguments mapfn and thisArg, the following steps are taken:

  1. If mapfn is undefined, let mapping be false.
  2. Else,
    1. If IsCallable(mapfn) is false, throw a TypeError exception.
    2. Let mapping be true.
  3. Let list be a new empty List.
  4. Let k be 0.
  5. Let usingIterator be ? GetMethod(items, @@iterator).
  6. If usingIterator is not undefined, then
    1. Let adder be a new Abstract Closure with parameters (key, value) that captures (list, mapFn, thisArg, mapping, k) and performs the following steps when called:
      1. If mapping is true, then
        1. Let mappedValue be ? Call(mapfn, thisArg, « value, k »).
      2. Else, let mappedValue be value.
      3. If Type(mappedValue) is Object, throw a TypeError exception.
      4. Append mappedValue to list.
      5. Set k to k + 1.
    2. Perform ! AddEntriesFromIterable(undefined, iterable, adder).
    3. Return a new Tuple value whose [[Sequence]] is list.
  7. NOTE: items is not an Iterable so assume it is an array-like object.
  8. Let arrayLike be ! ToObject(items).
  9. Let len be ? LengthOfArrayLike(arrayLike).
  10. Repeat, while k < len,
    1. Let Pk be ! ToString(k).
    2. Let kValue be ? Get(arrayLike, Pk).
    3. If mapping is true, then
      1. Let mappedValue be ? Call(mapfn, thisArg, « kValue, k »).
    4. Else, let mappedValue be kValue.
    5. If Type(mappedValue) is Object, throw a TypeError exception.
    6. Append mappedValue to list.
    7. Set k to k + 1.
  11. Return a new Tuple value whose [[Sequence]] is list.

8.2.2.3 Tuple.of ( ...items )

The of method takes any number of arguments, and performs the following steps:

  1. Let items be the List of arguments passed to this function.
  2. For each element e of items,
    1. If Type(e) is Object, throw a TypeError exception.
  3. Let tuple be a new Tuple value whose [[Sequence]] is items.
  4. Return tuple.

8.2.2.4 Tuple.prototype

The initial value of Tuple.prototype is %Tuple.prototype%

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

8.2.3 Properties of the Tuple Prototype Object

The Tuple prototype object:

  • is an ordinary object.
  • is not a Tuple object; it does not have a [[TupleData]] internal slot.
  • has a [[Prototype]] internal slot whose value is null.

The abstract operation thisTupleValue takes argument value. It performs the following steps when called:

  1. If Type(value) is Tuple, return value.
  2. If Type(value) is Object and value has a [[TupleData]] internal slot, then
    1. Let t be value.[[TupleValue]].
    2. Assert: Type(t) is Tuple.
    3. Return t.
  3. Throw a TypeError exception.

8.2.3.1 Tuple.prototype.constructor

The initial value of Tuple.prototype.constructor is the intrinsic object %Tuple%

8.2.3.2 get Tuple.prototype.length

Tuple.prototype.length is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let T be ? thisTupleValue(this value).
  2. Let size be the length of T.[[Sequence]].
  3. Return size.

8.2.3.3 Tuple.prototype.valueOf ( )

When the valueOf function is called, the following steps are taken:

  1. Return ? thisTupleValue(this value).

8.2.3.4 Tuple.prototype [ @@toStringTag ]

The initial value of Tuple.prototype[@@toStringTag] is the String value "Tuple".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

8.2.3.5 Tuple.prototype.popped ()

When the popped method is called, it returns a Tuple containing the elements of the Tuple, except for the last value.

The following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let list be a new List containing the elements of T.[[Sequence]].
  3. Let length be the number of elements in list.
  4. If length is 0,
    1. Return T.
  5. Remove the last element of list.
  6. Return a new Tuple value whose [[Sequence]] is list.

8.2.3.6 Tuple.prototype.pushed ( ...args )

When the pushed method is called, it returns a Tuple containing the elements of the Tuple, followed by the arguments in order.

The following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let list be a new List containing the elements of T.[[Sequence]].
  3. Let argsList be a List containing the arguments passed to this function invocation.
  4. Let n be the number of elements in list.
  5. Repeat, while argsList is not empty,
    1. Remove the first element from argsList, and let E be the value of the element.
    2. If n + 1 > 253 - 1, throw a TypeError exception.
    3. If Type(E) is Object, throw a TypeError exception.
    4. Append E to the end of List list.
    5. Set n to n + 1.
  6. Return a new Tuple value whose [[Sequence]] is list.

8.2.3.7 Tuple.prototype.reversed ()

When the reversed method is called, it returns a Tuple containing the elements of the Tuple, in reverse order.

The following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let oldList be a new List containing the elements of T.[[Sequence]].
  3. Let newList be a new empty List.
  4. Repeat, while oldList is not empty,
    1. Remove the last element from oldList, and let E be the value of the element.
    2. Append E to the end of List newList.
  5. Return a new Tuple value whose [[Sequence]] is newList.

8.2.3.8 Tuple.prototype.shifted ()

When the shifted method is called, it returns a Tuple containing the elements of the Tuple, except for the first value.

The following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let list be a new List containing the elements of T.[[Sequence]].
  3. Let length be the number of elements in list.
  4. If length is 0,
    1. Return T.
  5. Remove the first element of list.
  6. Return a new Tuple value whose [[Sequence]] is list.

8.2.3.9 Tuple.prototype.slice ( start, end )

When the slice method is called with two arguments, start and end, and returns a Tuple containing the elements of the Tuple from element start up to, but not including, element end (or through the end of the tuple if end is undefined). If start is negative, it is treated as length + start where length is the length of the tuple. If end is negative, it is treated as length + end where length is the length of the tuple.

The following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let list be T.[[Sequence]].
  3. Let len be the number of elements in list.
  4. Let relativeStart be ? ToInteger(start).
  5. If relativeStart < 0, let k be max((len + relativeStart), 0); else let k be min(relativeStart, len).
  6. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToInteger(end).
  7. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let final be min(relativeEnd, len).
  8. Let newList be a new empty List.
  9. Let n be 0.
  10. Repeat, while k < final,
    1. Let kValue be list[k].
    2. Assert: Type(kValue) is not Object.
    3. Append kValue to the end of newList.
    4. Set k to k + 1.
    5. Set n to n + 1.
  11. Return a new Tuple value whose [[Sequence]] is newList.

8.2.3.10 Tuple.prototype.sorted ( comparefn )

sorted is a distinct function that, except as described below, implements the same requirements as those of Array.prototype.sort as defined in 22.1.3.27. The implementation may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse.

Upon entry, the following steps are performed to initialize evaluation of the sorted function. These steps are used instead of the entry steps in 22.1.3.27:

  1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
  2. Let T be ? thisTupleValue(this value).
  3. Let list be a new List containing the elements of T.[[Sequence]].
  4. Let len be the length of list.

A new Tuple containing the elements from the original Tuple is returned, where the elements are sorted. The sort order is the ordering, after completion of this function, of the elements of list. The sort order of the result of sorted is the same order as if the elements of list were sorted in an Array via %Array.prototype.sort% with comparefn as the first argument.

8.2.3.11 Tuple.prototype.spliced ( start, deleteCount, ...items )

When the spliced method is called with two or more arguments start, deleteCount and zero or more items, a new Tuple is returned where the deleteCount elements of the Tuple starting at integer index start are replaced by the arguments items.

The following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let list be T.[[Sequence]].
  3. Let len be the number of elements in list.
  4. Let relativeStart be ? ToInteger(start).
  5. If relativeStart < 0, let actualStart be max((len + relativeStart), 0); else let actualStart be min(relativeStart, len).
  6. If the number of actual arguments is 0, then
    1. Let insertCount be 0.
    2. Let actualDeleteCount be 0.
  7. Else if the number of actual arguments is 1, then
    1. Let insertCount be 0.
    2. Let actualDeleteCount be len - actualStart.
  8. Else,
    1. Let insertCount be the number of actual arguments minus 2.
    2. Let dc be ? ToInteger(deleteCount).
    3. Let actualDeleteCount be min(max(dc, 0), len - actualStart).
  9. If len + insertCount - actualDeleteCount > 253 - 1, throw a TypeError exception.
  10. Let k be 0.
  11. Let items be a List whose elements are, in left to right order, the portion of the actual argument list starting with the third argument. The list is empty if fewer than three arguments were passed.
  12. Let itemCount be the number of elements in items.
  13. Let newList be a new empty List.
  14. Repeat, while k < actualStart,
    1. Let E be list[k].
    2. Append E to the end of list newList.
    3. Set k to k + 1.
  15. Let itemK be 0.
  16. Repeat, while itemK < itemCount.
    1. Let E be items[itemK].
    2. If Type(E) is Object, throw a TypeError exception.
    3. Append E to the end of newList.
    4. Set itemK to itemK + 1.
  17. Set k to actualStart + actualDeleteCount.
  18. Repeat, while k < len,
    1. Let E be list[k].
    2. Append E to the end of newList.
    3. Set k to k + 1.
  19. Return a new Tuple value whose [[Sequence]] is newList.

8.2.3.12 Tuple.prototype.concat ( ...args )

When the concat method is called with zero or more arguments, it returns a Tuple containing the elements of the Tuple followed by the elements of each argument in order.

The following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let list be a new empty List.
  3. Let n be 0.
  4. Let items be a List whose first element is T and whose subsequent element are, in left to right order, the arguments that were passed to this function invocation.
  5. Repeat, while items is not empty,
    1. Remove the first element from items and let E be the value of the element.
    2. Let spreadable be ? IsConcatSpreadable(E).
    3. If spreadable is true, then
      1. Let k be 0.
      2. Let len be ? LengthOfArrayLike(E).
      3. If n + len > 253 - 1, throw a TypeError exception.
      4. Repeat, while k < len,
        1. Let P be ! ToString(k).
        2. Let exists be ? HasProperty(E, P).
        3. If exists is true, then
          1. Let subElement be ? Get(E, P).
          2. If Type(subElement) is Object, throw a TypeError exception.
          3. Append subElement to the end of list list.
        4. Set n to n + 1.
        5. Set k to k + 1.
    4. Else,
      1. NOTE: E is added as a single item rather than spread.
      2. If n ≥ 253 - 1, throw a TypeError exception.
      3. If Type(E) is Object, throw a TypeError exception.
      4. Append E to the end of list list.
      5. Set n to n + 1.
  6. Return a new Tuple value whose [[Sequence]] is list.

8.2.3.13 Tuple.prototype.includes ( searchElement [ , fromIndex ] )

Tuple.prototype.includes is a distinct function that implements the same algorithm as Array.prototype.includes as defined in 22.1.3.13 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.14 Tuple.prototype.indexOf ( searchElement [ , fromIndex ] )

Tuple.prototype.indexOf is a distinct function that implements the same algorithm as Array.prototype.indexOf as defined in 22.1.3.14 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.15 Tuple.prototype.join ( separator )

Tuple.prototype.join is a distinct function that implements the same algorithm as Array.prototype.join as defined in 22.1.3.15 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.16 Tuple.prototype.lastIndexOf ( searchElement [ , fromIndex ] )

Tuple.prototype.lastIndexOf is a distinct function that implements the same algorithm as Array.prototype.lastIndexOf as defined in 22.1.3.17 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.17 Tuple.prototype.entries ( )

When the entries method is called, it returns an iterator over the entries of the Tuple.

The following steps are taken:

  1. Let tuple be ? thisTupleValue(this value).
  2. Let O be ! ToObject(tuple).
  3. Return CreateArrayIterator(O, key+value).

8.2.3.18 Tuple.prototype.every ( callbackfn [ , thisArg ] )

Tuple.prototype.every is a distinct function that implements the same algorithm as Array.prototype.every as defined in 22.1.3.5 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.19 Tuple.prototype.filter ( callbackfn [ , thisArg ] )

Note

callbackfn should be a function that accepts three arguments and returns a value that is coercible to the Boolean value true or false. filter calls callbackfn once for each element in the tuple, in ascending order, and constructs a new tuple of all the values for which callbackfn returns true.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the Tuple being traversed.

When the filter method is called with one or two arguments, the following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let list be T.[[Sequence]].
  3. Let len be the number of elements in list.
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. Let newList be a new empty List.
  6. Let k be 0.
  7. Repeat, while k < len,
    1. Let kValue be list[k].
    2. Let selected be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, k, T »)).
    3. If selected is true, then
      1. Append kValue to the end of list newList.
    4. Set k to k + 1.
  8. Return a new Tuple value whose [[Sequence]] is newList.

8.2.3.20 Tuple.prototype.find ( predicate [ , thisArg ] )

Tuple.prototype.find is a distinct function that implements the same algorithm as Array.prototype.find as defined in 22.1.3.8 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.21 Tuple.prototype.findIndex ( predicate [ , thisArg ] )

Tuple.prototype.findIndex is a distinct function that implements the same algorithm as Array.prototype.findIndex as defined in 22.1.3.9 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.22 Tuple.prototype.flat ( [ depth ] )

When the flat method is called with zero or one arguments, the following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let list be T.[[Sequence]].
  3. Let depthNum be 1.
  4. If depth is not undefined, then
    1. Set depthNum to ? ToInteger(depth).
  5. Let flat be a new empty List.
  6. Perform ? FlattenIntoTuple(flat, list, depthNum).
  7. Return a new Tuple value whose [[Sequence]] is flat.

8.2.3.22.1 FlattenIntoTuple ( target, source, depth [ , mapperFunction, thisArg ] )

The abstract operation FlattenIntoTuple takes arguments target, source, and depth and optional arguments mapperFunction and thisArg. It performs the following steps when called:

  1. Assert: target is a List.
  2. Assert: source is a List.
  3. Assert: ! IsInteger(depth) is true, or depth is either +∞ or -∞.
  4. Assert: If mapperFunction is present, then ! IsCallable(mapperFunction) is true, thisArg is present, and depth is 1.
  5. Let sourceIndex be 0.
  6. For each element of source,
    1. If mapperFunction is present, then
      1. Set element to ? Call(mapperFunction, thisArg, « element, sourceIndex, source »).
      2. If Type(element) is Object, throw a TypeError exception.
    2. If depth > 0 and Type(element) is Tuple, then
      1. Perform ? FlattenIntoTuple(target, element, depth - 1).
    3. Else,
      1. Let len be the length of target.
      2. If len ≥ 253 - 1, throw a TypeError exception.
      3. Append element to target.
    4. Set sourceIndex to sourceIndex + 1.

8.2.3.23 Tuple.prototype.flatMap ( mapperFunction [ , thisArg ] )

When the flatMap method is called with one or two arguments, the following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let list be T.[[Sequence]].
  3. If ! IsCallable(mapperFunction) is false, throw a TypeError exception.
  4. Let flat be a new empty List.
  5. Perform ? FlattenIntoTuple(flat, list, 1, mapperFunction, thisArg).
  6. Return a new Tuple value whose [[Sequence]] is flat.

8.2.3.24 Tuple.prototype.forEach ( callbackfn [ , thisArg ] )

Tuple.prototype.forEach is a distinct function that implements the same algorithm as Array.prototype.forEach as defined in 22.1.3.12 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.25 Tuple.prototype.keys ( )

When the keys method is called, it returns an iterator over the keys of the Tuple.

The following steps are taken:

  1. Let tuple be ? thisTupleValue(this value).
  2. Let O be ! ToObject(tuple).
  3. Return CreateArrayIterator(O, key).

8.2.3.26 Tuple.prototype.map ( callbackfn [ , thisArg ] )

Note

callbackfn should be a function that accepts three arguments. map calls callbackfn once for each element in the Tuple, in ascending order, and constructs a new tuple from the results.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the Tuple being traversed.

When the map method is called with one or two arguments, the following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let list be T.[[Sequence]].
  3. Let len be the number of elements in list.
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. Let newList be a new empty List.
  6. Let k be 0.
  7. Repeat, while k < len,
    1. Let kValue be list[k].
    2. Let mappedValue be ? Call(callbackfn, thisArg, « kValue, k, T »).
    3. If Type(mappedValue) is Object, throw a TypeError exception.
    4. Append mappedValue to the end of list newList.
    5. Set k to k + 1.
  8. Return a new Tuple value whose [[Sequence]] is newList.

8.2.3.27 Tuple.prototype.reduce ( callbackfn [ , thisArg ] )

Tuple.prototype.reduce is a distinct function that implements the same algorithm as Array.prototype.reduce as defined in 22.1.3.21 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.28 Tuple.prototype.reduceRight ( callbackfn [ , thisArg ] )

Tuple.prototype.reduceRight is a distinct function that implements the same algorithm as Array.prototype.reduceRight as defined in 22.1.3.22 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.29 Tuple.prototype.some ( callbackfn [ , thisArg ] )

Tuple.prototype.some is a distinct function that implements the same algorithm as Array.prototype.some as defined in 22.1.3.26 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.30 Tuple.prototype.unshifted ( ...args )

When the unshifted method is called, it returns a Tuple containing the elements of the Tuple, with the arguments to the function invocation prepended.

The following steps are taken:

  1. Let T be ? thisTupleValue(this value).
  2. Let argsList be a List containing the arguments passed to this function invocation.
  3. Let tupleList be a new List containing the elements of T.[[Sequence]].
  4. Let list be a new empty List.
  5. Let n be 0.
  6. Repeat, while argsList is not empty,
    1. If n + 1 > 253 - 1, throw a TypeError exception.
    2. Remove the first element from argsList, and let E be the value of the element.
    3. If Type(E) is Object, throw a TypeError exception.
    4. Append E to the end of list list.
    5. Set n to n + 1.
  7. Repeat, while tupleList is not empty,
    1. If n + 1 > 253 - 1, throw a TypeError exception.
    2. Remove the first element from tupleList, and let E be the value of the element.
    3. Append E to the end of list list.
    4. Set n to n + 1.
  8. Return a new Tuple value whose [[Sequence]] is list.

8.2.3.31 Tuple.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

Tuple.prototype.toLocaleString is a distinct function that implements the same algorithm as Array.prototype.toLocaleString as defined in 8.2.3.31 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.32 Tuple.prototype.toString ()

Tuple.prototype.toString is a distinct function that implements the same algorithm as Array.prototype.toString as defined in 22.1.3.30 except that ? thisTupleValue(this value) is used instead of directly accessing the this value. The implementation of the algorithm may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse, do not change, and their access is not observable. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This function is not generic, since thisTupleValue(this value) can return an abrupt completion: in that case, that exception is thrown instead of evaluating the algorithm.

8.2.3.33 Tuple.prototype.values ()

When the values method is called, it returns an iterator over the values of the Tuple.

The following steps are taken:

  1. Let tuple be ? thisTupleValue(this value).
  2. Let O be ! ToObject(tuple).
  3. Return CreateArrayIterator(O, value).

8.2.3.34 Tuple.prototype [ @@iterator ] ()

The initial value of the @@iterator property is %Tuple.prototype.values%.

8.2.3.35 Tuple.prototype.with ( index, value )

When the with method is called with two arguments, it returns a new Tuple with the element at index index replaced with value value.

  1. Let T be ? thisTupleValue(this value).
  2. Let list be a new List containing the elements of T.[[Sequence]].
  3. Let length be the length of list list.
  4. Let I be ? ToIndex(index).
  5. If Ilength, throw a RangeError exception.
  6. If Type(value) is Object, throw a TypeError exception.
  7. Set list[I] to value.
  8. Return a new Tuple value whose [[Sequence]] is list.

8.3 Box Objects

8.3.1 The Box Constructor

The Box constructor:

  • is the intrinsic object %Box%.
  • is the initial value of the "Box" property of the global object.
  • creates and initializes a new Box value when called as a function.
  • is not intended to be used with the new operator or to be subclassed. It may be used as the value of an extends clause of a class definition but a super call to the Box constructor will cause an exception.

8.3.1.1 Box ( arg )

When the Box function is called, the following steps are taken:

  1. If NewTarget is not undefined, throw a TypeError exception.
  2. Return a new Box value whose [[Value]] is arg.

8.3.2 Properties of the Box Constructor

The Box constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

8.3.2.1 Box.containsBoxes ( arg )

The containsBoxes function takes one argument arg, and performs the following steps:

  1. If Type(arg) is not Record, Tuple or Box, throw a TypeError exception.
  2. Return ! RecursiveContainsBoxes(arg).

8.3.2.1.1 RecursiveContainsBoxes ( value )

The abstract operation RecursiveContainsBoxes takes the argument value. It performs the following steps when called:

  1. Assert: Type(value) is not Object.
  2. If Type(value) is Box, return true.
  3. If Type(value) is Record, then
    1. For each field of value.[[Fields]], do
      1. If ! RecursiveContainsBoxes(field.[[Value]]) is true, return true.
  4. If Type(value) is Tuple,
    1. For each item of value.[[Sequence]], do
      1. If ! RecursiveContainsBoxes(item) is true, return true.
  5. Return false.

8.3.2.2 Box.prototype

The initial value of Box.prototype is %Box.prototype%

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

8.3.3 Properties of the Box Prototype Object

The Box prototype object:

  • is an ordinary object.
  • is not a Box object; it does not have a [[BoxData]] internal slot.
  • has a [[Prototype]] internal slot whose value is null.

The abstract operation thisBoxValue takes argument value. It performs the following steps when called:

  1. If Type(value) is Box, return value.
  2. If Type(value) is Object and value has a [[BoxData]] internal slot, then
    1. Let box be value.[[BoxValue]].
    2. Assert: Type(box) is Box.
    3. Return box.
  3. Throw a TypeError exception.

8.3.3.1 Box.prototype.constructor

The initial value of Box.prototype.constructor is the intrinsic object %Box%

8.3.3.2 Box.prototype.valueOf ( )

When the valueOf function is called, the following steps are taken:

  1. Return ? thisBoxValue(this value).

8.3.3.3 Box.prototype [ @@toStringTag ]

The initial value of Box.prototype[@@toStringTag] is the String value "Box".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

8.3.3.4 Box.prototype.unbox ( )

When the unbox function is called, the following steps are taken:

  1. Let box be ? thisBoxValue(this value).
  2. Return box.[[Value]]

9 Fundamental Objects

9.1 Object Objects

9.1.1 Properties of the Object Prototype Object

9.1.1.1 Object.prototype.toString ( )

When the toString method is called, the following steps are taken:

  1. If the this value is undefined, return "[object Undefined]".
  2. If the this value is null, return "[object Null]".
  3. Let O be ! ToObject(this value).
  4. Let isArray be ? IsArray(O).
  5. If isArray is true, let builtinTag be "Array".
  6. Else if O has a [[ParameterMap]] internal slot, let builtinTag be "Arguments".
  7. Else if O has a [[Call]] internal method, let builtinTag be "Function".
  8. Else if O has an [[ErrorData]] internal slot, let builtinTag be "Error".
  9. Else if O has a [[BooleanData]] internal slot, let builtinTag be "Boolean".
  10. Else if O has a [[NumberData]] internal slot, let builtinTag be "Number".
  11. Else if O has a [[StringData]] internal slot, let builtinTag be "String".
  12. Else if O has a [[DateValue]] internal slot, let builtinTag be "Date".
  13. Else if O has a [[RegExpMatcher]] internal slot, let builtinTag be "RegExp".
  14. Else if O has a [[RecordData]] internal slot, let builtinTag be "Record".
  15. Else if O has a [[TupleData]] internal slot, let builtinTag be "Tuple".
  16. Else if O has a [[BoxData]] internal slot, let builtinTag be "Box".
  17. Else, let builtinTag be "Object".
  18. Let tag be ? Get(O, @@toStringTag).
  19. If Type(tag) is not String, set tag to builtinTag.
  20. Return the string-concatenation of "[object ", tag, and "]".

This function is the %ObjProto_toString% intrinsic object.

Note

Historically, this function was occasionally used to access the String value of the [[Class]] internal slot that was used in previous editions of this specification as a nominal type tag for various built-in objects. The above definition of toString preserves compatibility for legacy code that uses toString as a test for those specific kinds of built-in objects. It does not provide a reliable type testing mechanism for other kinds of built-in or program defined objects. In addition, programs can use @@toStringTag in ways that will invalidate the reliability of such legacy type tests.

10 Structured Data

10.1 The JSON Object

10.1.1 JSON.parse ( text [ , reviver ] )

The parse function parses a JSON text (a JSON-formatted String) and produces an ECMAScript value. The JSON format represents literals, arrays, and objects with a syntax similar to the syntax for ECMAScript literals, Array Initializers, and Object Initializers. After parsing, JSON objects are realized as ECMAScript objects. JSON arrays are realized as ECMAScript Array instances. JSON strings, numbers, booleans, and null are realized as ECMAScript Strings, Numbers, Booleans, and null.

The optional reviver parameter is a function that takes two parameters, key and value. It can filter and transform the results. It is called with each of the key/value pairs produced by the parse, and its return value is used instead of the original value. If it returns what it received, the structure is not modified. If it returns undefined then the property is deleted from the result.

  1. Let jsonString be ? ToString(text).
  2. Parse ! UTF16DecodeString(jsonString) as a JSON text as specified in ECMA-404. Throw a SyntaxError exception if it is not a valid JSON text as defined in that specification.
  3. Let scriptString be the string-concatenation of "(", jsonString, and ");".
  4. Let completion be the result of parsing and evaluating ! UTF16DecodeString(scriptString) as if it was the source text of an ECMAScript Script. The extended PropertyDefinitionEvaluation semantics defined in must not be used during the evaluation.
  5. Let unfiltered be completion.[[Value]].
  6. Assert: unfiltered is either a String, Number, Boolean, Null, or an Object that is defined by either an ArrayLiteral or an ObjectLiteral.
  7. Let unfiltered be ? ParseJSONText(text).
  8. If IsCallable(reviver) is true, then
    1. Let root be OrdinaryObjectCreate(%Object.prototype%).
    2. Let rootName be the empty String.
    3. Perform ! CreateDataPropertyOrThrow(root, rootName, unfiltered).
    4. Return ? InternalizeJSONProperty(root, rootName, reviver).
  9. Else,
    1. Return unfiltered.

This function is the %JSONParse% intrinsic object.

The "length" property of the parse function is 2.

10.1.1.1 ParseJSONText ( text )

The abstract operation ParseJSONText takes argument text (an ECMAScript language value). It parses a JSON text (a JSON-formatted String) and produces an ECMAScript value. It performs the following steps when called:

  1. Let jsonString be ? ToString(text).
  2. Parse ! UTF16DecodeString(jsonString) as a JSON text as specified in ECMA-404. Throw a SyntaxError exception if it is not a valid JSON text as defined in that specification.
  3. Let scriptString be the string-concatenation of "(", jsonString, and ");".
  4. Let completion be the result of parsing and evaluating ! UTF16DecodeString(scriptString) as if it was the source text of an ECMAScript Script. The extended PropertyDefinitionEvaluation semantics defined in must not be used during the evaluation.
  5. Let unfiltered be completion.[[Value]].
  6. Assert: unfiltered is either a String, Number, Boolean, Null, or an Object that is defined by either an ArrayLiteral or an ObjectLiteral.
  7. Return unfiltered.

10.1.2 JSON.parseImmutable ( text [ , reviver ] )

The parseImmutable function parses a JSON text (a JSON-formatted String) and produces an ECMAScript value. The JSON format represents literals, arrays, and objects with a syntax similar to the syntax for ECMAScript literals, Array Initializers, and Object Initializers. After parsing, JSON objects are realized as ECMAScript records. JSON arrays are realized as ECMAScript tuples. JSON strings, numbers, booleans, and null are realized as ECMAScript Strings, Numbers, Booleans, and null.

The optional reviver parameter is a function that takes two parameters, key and value. It can filter and transform the results. It is called with each of the key/value pairs produced by the parse, and its return value is used instead of the original value. If it returns what it received, the structure is not modified. If it returns undefined then the property is deleted from the result.

  1. Let unfiltered be ? ParseJSONText(text).
  2. Return ? BuildImmutableProperty(unfiltered, "", reviver).

This function is the %JSONParseImmutable% intrinsic object.

The "length" property of the parseImmutable function is 2.

10.1.2.1 BuildImmutableProperty ( value, name, reviver )

The abstract operation BuildImmutableProperty takes arguments value (an ECMAScript language value), name (a String), and reviver (a function object or Undefined). It performs the following steps when called:

  1. If Type(value) is Object, then
    1. Let isArray be ? IsArray(val).
    2. If isArray is true, then
      1. Let items be a new empty List.
      2. Let I be 0.
      3. Let len be ? LengthOfArrayLike(val).
      4. Repeat, while I < len,
        1. Let childName be ! ToString(I).
        2. Let childValue be ? Get(value, ! childName).
        3. Let newElement be ? BuildImmutableProperty(childValue, childName, reviver).
        4. Assert: Type(newElement) is not Object.
        5. Append newElement to items.
        6. Set I to I + 1.
      5. Let immutable be a new Tuple value whose [[Sequence]] is items.
    3. Else,
      1. Let props be ? EnumerableOwnPropertyNames(obj, key+value).
      2. Let fields be a new empty List.
      3. For each element prop of props,
        1. Let childName be ! GetV(prop, "0").
        2. Let childValue be ! GetV(prop, "1").
        3. Let newElement be ? BuildImmutableProperty(childValue, childName, reviver).
        4. Assert: Type(newElement) is not Object.
        5. If newElement is not undefined, then:
          1. Let field be the Record { [[Key]]: childName, [[Value]]: newElement }.
          2. Append field to fields.
      4. Let immutable be ! CreateRecord(fields).
  2. Else,
    1. Let immutable be value.
  3. If IsCallable(reviver) is true, then
    1. Let immutable be ? Call(reviver, undefined, « name, immutable »).
    2. If Type(immutable) is Object, throw a TypeError exception.
  4. Return immutable.

It is not permitted for a conforming implementation of JSON.parseImmutable to extend the JSON grammars. If an implementation wishes to support a modified or extended JSON interchange format it must do so by defining a different parse function.

Note

In the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten.

Note

There are two differences in the behavior of the reviver parameter of the JSON.parse and JSON.parseImmutable functions:

  • JSON.parse passes the parent object as the this object, while JSON.parseImmutable passes undefined.
  • When reviver returns undefined for an array element, it introduced an hole. When reviver returns undefined for a tuple element, undefined is used as the resulting value.

10.1.3 JSON.stringify ( value [ , replacer [ , space ] ] )

10.1.3.1 SerializeJSONProperty ( state, key, holder )

The abstract operation SerializeJSONProperty takes arguments state, key, and holder. It performs the following steps when called:

  1. Let value be ? Get(holder, key).
  2. Let toJSONCalled be false.
  3. If Type(value) is Object or BigInt, then
    1. Let toJSON be ? GetV(value, "toJSON").
    2. If IsCallable(toJSON) is true, then
      1. Set value to ? Call(toJSON, value, « key »).
      2. Set toJSONCalled to true.
  4. If state.[[ReplacerFunction]] is not undefined, then
    1. Set value to ? Call(state.[[ReplacerFunction]], holder, « key, value »).
    2. Set value to ! MaybeUnwrapBox(value).
  5. Else,
    1. Set value to ! MaybeUnwrapBox(value).
    2. If toJSONCalled is false, then
      1. If Type(value) is Object or BigInt, then
      2. Let toJSON be ? GetV(value, "toJSON").
      3. If IsCallable(toJSON) is true, then
        1. Set value to ? Call(toJSON, value, « key »).
        2. Set value to ! MaybeUnwrapBox(value).
  6. If Type(value) is Object, then
    1. If value has a [[NumberData]] internal slot, then
      1. Set value to ? ToNumber(value).
    2. Else if value has a [[StringData]] internal slot, then
      1. Set value to ? ToString(value).
    3. Else if value has a [[BooleanData]] internal slot, then
      1. Set value to value.[[BooleanData]].
    4. Else if value has a [[BigIntData]] internal slot, then
      1. Set value to value.[[BigIntData]].
  7. If value is null, return "null".
  8. If value is true, return "true".
  9. If value is false, return "false".
  10. If Type(value) is Record or Type(value) is Tuple, set value to ! ToObject(value).
  11. If Type(value) is String, return QuoteJSONString(value).
  12. If Type(value) is Number, then
    1. If value is finite, return ! ToString(value).
    2. Return "null".
  13. If Type(value) is BigInt, throw a TypeError exception.
  14. If Type(value) is Object and IsCallable(value) is false, then
    1. Let isArray be ? IsArray(value).
    2. If ! IsTuple(value) is true, then
      1. Let isArrayLike be true.
    3. Else,
      1. Let isArrayLike be ? IsArray(value).
    4. If isArrayisArrayLike is true, return ? SerializeJSONArray(state, value).
    5. Return ? SerializeJSONObject(state, value).
  15. Return undefined.

10.1.3.2 MaybeUnwrapBox ( value )

The abstract operation MaybeUnwrapBox takes argument value (an ECMAScript language value). It performs the following steps when called:

  1. If Type(value) is Object and value has a [[BoxData]] internal slot,
    1. Set value to value.[[BoxData]].
  2. If Type(value) is Box, return ! MaybeUnwrapBox(value.[[Value]]).
  3. Return value.

A Copyright & Software License

Copyright Notice

© 2021 Robin Ricard, Rick Button

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.