Stage 2 Draft / December 13, 2023

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, and Tuple; 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, 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 a 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 (14.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 a Tuple value as an argument. The resulting object has an internal slot whose value is the Tuple value.

6 ECMAScript Data Types and Values

6.1 ECMAScript Language Types

6.1.8 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 ascending code unit order. The [[Fields]] List and its entries are never modified.

6.1.8.1 RecordToString ( argument )

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

  1. Let list be argument.[[Fields]].
  2. Let strings be a new empty List.
  3. For each Record { [[Key]], [[Value]] } kv of list, do
    1. Let key be kv.[[Key]].
    2. Let kvString be QuoteJSONString(key).
    3. Set kvString to be the string-concatenation of kvString and ": ".
    4. Let value be kv.[[Value]].
    5. Set kvString to be the string-concatenation of kvString and StringifyRecordValue(value).
    6. Append kvString to the end of strings.
  4. Return the string-concatenation of "#{ ", ListJoin(strings), and " }".

6.1.8.2 StringifyRecordValue ( value )

The abstract operation StringifyRecordValue takes argument value (a primitive value) and returns a String. It performs the following steps when called:

  1. If value is a Symbol, Return SymbolDescriptiveString(value).
  2. Else if value is a String, Return QuoteJSONString(value).
  3. Else, return ! ToString(value).

6.1.8.3 RecordEqual ( x, y, elementEqual )

The abstract operation RecordEqual takes arguments x (a Record), y (a Record), and elementEqual (an Abstract Closure) and returns a Boolean. 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 xLen β‰  yLen, 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. If SameValueNonGeneric(xField.[[Key]], yField.[[Key]]) is false, Return false.
    4. If elementEqual(xField.[[Value]], yField.[[Value]]) is false, Return false.
    5. Set k to k + 1.
  8. Return true.

6.1.8.4 RecordSameValue ( x, y )

The abstract operation RecordSameValue takes arguments x (a Record) and y (a Record) and returns a Boolean. 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).

6.1.8.5 RecordSameValueZero ( x, y )

The abstract operation RecordSameValueZero takes arguments x (a Record) and y (a Record) and returns a Boolean. 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).

6.1.9 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.

6.1.9.1 TupleToString ( argument )

The abstract operation TupleToString takes argument argument (a Tuple) and returns a String. It converts argument to a String. It performs the following steps when called:

  1. Let list be argument.[[Sequence]].
  2. Assert: list is a List of ECMAScript language values.
  3. Let strings be a new empty List.
  4. For each element value of list, do
    1. Let valueString be StringifyRecordValue(value).
    2. Append valueString to the end of strings.
  5. Return the string-concatenation of "#[", ListJoin(strings), and "]".

6.1.9.2 TupleEqual ( x, y, elementEqual )

The abstract operation TupleEqual takes arguments x (a Tuple), y (a Tuple), and elementEqual (an Abstract Closure) and returns a Boolean. 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 xLen β‰  yLen, 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(xItem, yItem) is false, Return false.
    4. Set k to k + 1.
  8. Return true.

6.1.9.3 TupleSameValue ( x, y )

The abstract operation TupleSameValue takes arguments x (a Tuple) and y (a Tuple) and returns a Boolean. 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).

6.1.9.4 TupleSameValueZero ( x, y )

The abstract operation TupleSameValueZero takes arguments x (a Tuple) and y (a Tuple) and returns a Boolean. 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).

7 Abstract Operations

7.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, and Tuple types hashave no implicit conversions in the ECMAScript language; programmers must call BigInt , Record, or Tuple explicitly to convert values from other types.

7.1.1 ToPrimitive ( input [ , preferredType ] )

The abstract operation ToPrimitive takes argument input (an ECMAScript language value) and optional argument preferredType (string or number) and returns either a normal completion containing an ECMAScript language value, or a throw completion. It converts its input argument to a non-Object type. If an object is capable of converting to more than one primitive type, it may use the optional hint preferredType to favour that type. It performs the following steps when called:

  1. If Type(input) is Object, then
    1. If input has a [[RecordData]] internal slot, return input.[[RecordData]].
    2. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
    3. If exoticToPrim is not undefined, then
      1. If preferredType is not present, let hint be "default".
      2. Else if preferredType is string, let hint be "string".
      3. Else,
        1. Assert: preferredType is number.
        2. Let hint be "number".
      4. Let result be ? Call(exoticToPrim, input, Β« hint Β»).
      5. If Type(result) is not Object, return result.
      6. Throw a TypeError exception.
    4. If preferredType is not present, let preferredType be number.
    5. Return ? OrdinaryToPrimitive(input, preferredType).
  2. Return input.
Note

There is explicit handling of [[RecordData]] in ToPrimitive because, unlike the other primitives, there is no prototype to lookup the appropriate methods on.

7.1.2 ToBoolean ( argument )

The abstract operation ToBoolean takes argument argument and returns a Boolean. 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.
Object Return true.

7.1.3 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.
Object

Apply the following steps:

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

7.1.4 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.

7.1.5 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).
Object

Apply the following steps:

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

7.1.6 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 20.3 for a description of Boolean objects.
Number Return a new Number object whose [[NumberData]] internal slot is set to argument. See 21.1 for a description of Number objects.
String Return a new String object whose [[StringData]] internal slot is set to argument. See 22.1 for a description of String objects.
Symbol Return a new Symbol object whose [[SymbolData]] internal slot is set to argument. See 20.4 for a description of Symbol objects.
BigInt Return a new BigInt object whose [[BigIntData]] internal slot is set to argument. See 21.2 for a description of BigInt objects.
Record Return RecordToObject(argument).
Tuple Return a new Tuple object whose [[TupleData]] internal slot is set to argument. See 14.2 for a description of Tuple objects.
Object Return argument.

7.2 ToPropertyKey ( argument )

The abstract operation ToPropertyKey takes argument argument and returns either a normal completion containing a property key or a throw completion. It converts argument to a value that can be used as a property key. It performs the following steps when called:

  1. Let key be ? ToPrimitive(argument, string).
  2. If key is a Symbol, then
    1. Return key.
  3. If key is a Record or key is a Tuple, then
    1. Throw a TypeError exception.
  4. Return ! ToString(key).

7.3 Testing and Comparison Operations

7.3.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.
Object Return argument.

7.3.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, then
    1. Return Number::sameValue(x, y).
  3. If Type(x) is BigInt, then
    1. Return BigInt::sameValue(x, y).
  4. If Type(x) is Record, return RecordSameValue(x, y).
  5. If Type(x) is Tuple, return TupleSameValue(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.

7.3.3 SameValueZero ( x, y )

The abstract operation SameValueZero takes arguments x (an ECMAScript language value) and y (an ECMAScript language value) and returns a Boolean. 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, then
    1. Return Number::sameValueZero(x, y).
  3. If Type(x) is BigInt, then
    1. Return BigInt::sameValueZero(x, y).
  4. If Type(x) is Record, return RecordSameValueZero(x, y).
  5. If Type(x) is Tuple, return TupleSameValueZero(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.

7.3.4 SameValueNonNumeric ( x, y )

The abstract operation SameValueNonNumeric 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) and returns a Boolean.

7.3.5 SameValueNonGeneric ( x, y )

The abstract operation SameValueNonGeneric takes arguments x (an ECMAScript language value, but not one of Number, BigInt, Record or Tuple) and y (an ECMAScript language value, but not one of Number, BigInt, Record or Tuple) and returns a Boolean. SameValueNonGeneric replaces SameValueNonNumeric. It performs the following steps when called:

  1. Assert: Type(x) is not Number or BigInt or Record or Tuple,.
  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.

7.3.6 IsLooselyEqual ( x, y )

The abstract operation IsLooselyEqual takes arguments x (an ECMAScript language value) and y (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. 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.6.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, 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, 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.

7.3.7 IsStrictlyEqual ( x, y )

The abstract operation IsStrictlyEqual takes arguments x (an ECMAScript language value) and y (an ECMAScript language value) and returns a Boolean. 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, then
    1. Return Number::equal(x, y).
  3. If Type(x) is BigInt, then
    1. Return BigInt::equal(x, y).
  4. If Type(x) is Record, then
    1. Return RecordSameValueZero(x, y).
  5. If Type(x) is Tuple, then
    1. Return TupleSameValueZero(x, y).
  6. Return SameValueNonNumeric(x, y).
  7. Return SameValueNonGeneric(x, y).
Note

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

7.5 Operations on Records

7.5.1 RecordToObject ( value )

The abstract operation RecordToObject takes argument value (a Record) and returns an Object. It is used to specify the creation of objects based on the contents of a record. It performs the following steps when called:

  1. Let obj be OrdinaryObjectCreate(null, Β« [[RecordData]] Β»).
  2. Set obj.[[RecordData]] to value.
  3. For each element entry of value.[[Fields]], do
    1. Let key be entry.[[Key]].
    2. Let val be entry.[[Value]].
    3. Assert: key is a property key.
    4. Assert: val is an ECMAScript language value.
    5. Perform ! CreateDataProperty(obj, key, val).
  4. Perform ! SetIntegrityLevel(obj, frozen).
  5. Return obj.

7.5.2 CreateRecord ( entries )

The abstract operation CreateRecord takes argument entries (a List of Records with fields [[Key]] (a String) and [[Value]] (an ECMAScript language value)) and returns a new Record value. 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.

7.5.3 DeduplicateRecordEntries ( entries )

The abstract operation DeduplicateRecordEntries takes argument entries (a List of Records with fields [[Key]] (a String) and [[Value]] (an ECMAScript language value)) and returns a List of Records with fields [[Key]] (a String) and [[Value]] (an ECMAScript language value). It is used to creates a copy of entries where only the last entry for each unique key is retained. It performs the following steps when called:

  1. Let reversedEntries be entries in reverse.
  2. Let uniqueEntries be an empty List.
  3. For each element kv in reversedEntries, do
    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.
  4. Return uniqueEntries.

7.5.4 AddPropertyIntoRecordEntriesList ( entries, propName, value )

The abstract operation AddPropertyIntoRecordEntriesList takes arguments entries (a List of Records with fields [[Key]] (a String) and [[Value]] (an ECMAScript language value)), propName (a property key), and value (an ECMAScript language value) and returns either a normal completion containing a List of Records with fields [[Key]] (a String) and [[Value]] (an ECMAScript language value), or a throw completion. 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]]: propName, [[Value]]: value } to entries.
  4. Return entries.

7.6 Operations on Tuples

7.6.1 AddValueToTupleSequenceList ( sequence, value )

The abstract operation AddValueToTupleSequenceList takes arguments sequence (a List of ECMAScript language values) and value (an ECMAScript language value) and returns either a normal completion containing a List of ECMAScript language values, or a throw completion. 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.

7.6.2 IsTuple ( O )

The abstract operation IsTuple takes argument O (an ECMAScript language value) and returns a Boolean. 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.

7.7 ListJoin ( list )

The abstract operation ListJoin takes argument list (a List of Strings) and returns a String. It performs the following steps when called:

  1. Let ret be "".
  2. Let len be the length of list.
  3. Let k be 0.
  4. Repeat, while k < len,
    1. Let s be list[k].
    2. Set ret to be the string-concatenation of ret and s.
    3. Set k to k + 1.
    4. If k < len, set ret to be the string-concatenation of ret and ", ".
  5. Return ret.

7.8 IsArrayOrTuple ( O )

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

  1. If IsTuple(O), return true.
  2. Return ? IsArray(O).

10 Ordinary and Exotic Objects Behaviours

10.4 Built-in Exotic Object Internal Methods and Slots

10.4.8 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. Tuple exotic objects always have a data property named "length" whose value is the number of entries in 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.

10.4.8.1 [[IsExtensible]] ( )

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

  1. Return false.

10.4.8.2 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of a Tuple exotic object T 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. If P is "length", then
    1. Let length be the length of T.[[Sequence]].
    2. Return the PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
  4. Let numericIndex be CanonicalNumericIndexString(P).
  5. If numericIndex is undefined, return undefined.
  6. Let value be TupleGet(T, numericIndex).
  7. If value is empty, return undefined.
  8. Return the PropertyDescriptor { [[Value]]: value, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }.

10.4.8.3 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of a Tuple exotic object T 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 P is "length", then
    1. Let lengthDesc be ! T.[[GetOwnProperty]](P).
    2. Return IsCompatiblePropertyDescriptor(false, Desc, lengthDesc).
  4. If Desc.[[Writable]] is present and has value true, return false.
  5. If Desc.[[Enumerable]] is present and has value false, return false.
  6. If Desc.[[Configurable]] is present and has value true, return false.
  7. Let numericIndex be CanonicalNumericIndexString(P).
  8. If numericIndex is undefined, return false.
  9. Let current be TupleGet(T, numericIndex).
  10. If current is empty return false.
  11. If IsAccessorDescriptor(Desc) is true, return false.
  12. If Desc.[[Value]] is present, return SameValue(Desc.[[Value]], current).
  13. Return true.

10.4.8.4 [[HasProperty]] ( P )

The [[HasProperty]] internal method of a Tuple exotic object T 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. If P is "length", return true.
    2. Let numericIndex be CanonicalNumericIndexString(P).
    3. If numericIndex is not undefined, return IsValidTupleIndex(T, numericIndex).
  3. Let parent be ? T.[[GetPrototypeOf]]().
  4. Return ? parent.[[HasProperty]](P).

10.4.8.5 [[Get]] ( P, Receiver )

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

  1. Assert: IsPropertyKey(P) is true.
  2. If P is "length", then
    1. Let length be the length of T.[[Sequence]].
    2. Return 𝔽(length).
  3. 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.
  4. Let parent be ? T.[[GetPrototypeOf]]().
  5. Return ? parent.[[Get]](P, Receiver).

10.4.8.6 [[Set]] ( P, Receiver )

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

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

10.4.8.7 [[Delete]] ( P )

The [[Delete]] internal method of a Tuple exotic object T 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. If P is "length", return false.
  4. Let numericIndex be CanonicalNumericIndexString(P).
  5. If numericIndex is undefined, return true.
  6. If IsValidTupleIndex( T, numericIndex ) is false, return true.
  7. Return false.

10.4.8.8 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of a Tuple exotic object T 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. Add "length" to keys.
  8. Return keys.

10.4.8.9 TupleCreate ( value )

The abstract operation TupleCreate takes argument value (a Tuple) and returns a Tuple exotic object. 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 10.4.8.
  3. Set T.[[Prototype]] to %Tuple.prototype%.
  4. Set T.[[TupleData]] to value.
  5. Return T.

10.4.8.10 IsValidTupleIndex ( T, index )

The abstract operation IsValidTupleIndex takes arguments T (a Tuple object) and index (a Number) and returns a Boolean. It performs the following steps when called:

  1. If IsIntegralNumber(index) is false, return false.
  2. If index is -0𝔽, return false.
  3. If ℝ(index) < 0 or ℝ(index) β‰₯ the length of T.[[TupleData]].[[Sequence]], return false.
  4. Return true.

10.4.8.11 TupleGet ( T, index )

The abstract operation TupleGet takes arguments T (a Tuple object) and index (a Number) and returns an ECMAScript language value. It performs the following steps when called:

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

12 ECMAScript Language: Lexical Grammar

12.7 Punctuators

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

13 ECMAScript Language: Expressions

13.2 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]

13.2.10 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]

13.2.10.1 Static Semantics: Early Errors

RecordPropertyDefinition : PropertyName : AssignmentExpression

13.2.10.2 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 uniqueEntries be DeduplicateRecordEntries(entries).
  4. Return CreateRecord(uniqueEntries).

13.2.10.3 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 desc be ? from.[[GetOwnProperty]](nextKey).
    2. If desc is not undefined and desc.[[Enumerable]] is true, then
      1. Let value be ? Get(from, 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(entries, 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(entries, propKey, propValue).

13.2.11 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]

13.2.11.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 Completion(AddValueToTupleSequenceList(sequence, nextValue)).
    5. If completion is an abrupt completion, then
      1. Return ? IteratorClose(iteratorRecord, completion).

13.2.11.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 element value in sequence, do
    1. Assert: Type(value) is not Object.
  4. Let tup be a Tuple value whose [[Sequence]] value is sequence.
  5. Return tup.

13.5 Unary Operators

13.5.3 The typeof Operator

13.5.3.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"
Object (does not implement [[Call]]) "object"
Object (implements [[Call]]) "function"

13.10 Relational Operators

13.10.1 Runtime Semantics: Evaluation

RelationalExpression : RelationalExpression in ShiftExpression
  1. Let lref be ? Evaluation of RelationalExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be ? Evaluation of ShiftExpression.
  4. Let rval be ? GetValue(rref).
  5. If Type(rval) is Record, set rval to ! ToObject(rval).
  6. If Type(rval) is Tuple, set rval to ! ToObject(rval).
  7. If Type(rval) is not Object, throw a TypeError exception.
  8. Return ? HasProperty(rval, ? ToPropertyKey(lval)).
RelationalExpression : PrivateIdentifier in ShiftExpression
  1. Let privateIdentifier be the StringValue of PrivateIdentifier.
  2. Let rref be ? Evaluation of ShiftExpression.
  3. Let rval be ? GetValue(rref).
  4. If Type(rval) is Record, return false.
  5. If Type(rval) is Tuple, return false.
  6. If Type(rval) is not Object, throw a TypeError exception.
  7. Let privateEnv be the running execution context's PrivateEnvironment.
  8. Let privateName be ResolvePrivateIdentifier(privateEnv, privateIdentifier).
  9. If PrivateElementFind(rval, privateName) is not empty, return true.
  10. Return false.

14 Immutable Data Structures

14.1 Record Objects

14.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.

14.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, do
    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).

14.1.2 Properties of the Record Constructor

The Record constructor:

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

14.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. Let keyString be ? ToString(key).
    2. If Type(value) is Object, throw a TypeError exception.
    3. Let field be { [[Key]]: keyString, [[Value]]: value }.
    4. Append field to the end of list fields.
  4. Perform ? AddEntriesFromIterable(undefined, iterable, adder).
  5. Let uniqueEntries be DeduplicateRecordEntries(fields).
  6. Return CreateRecord(uniqueEntries).
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.

14.1.2.2 Record [ @@hasInstance ] ( V )

This method performs the following steps when called:

  1. If V is an Object and V has a [[RecordData]] internal slot, return true. Otherwise, return false.
Note

The Record constructor overrides the @@hasInstance because unlike the other primitives its prototype is null.

For example,

Object(#{}) instanceof Record

will return true instead of throwing a TypeError.

The method checks for the [[RecordData]] internal slot instead of checking for a null [[prototype]] because all prototype chains that terminate end with null. So,

Object.create(null) instanceof Record

will return false.

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

The value of the "name" property of this method is "[Symbol.hasInstance]".

14.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 }.

14.1.3 Properties of Record Objects

Record objects are ordinary objects with a null prototype. Record objects have a [[RecordData]] internal slot. The [[RecordData]] internal slot is the Record value represented by this Record object.

14.2 Tuple Objects

14.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.

14.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, do
    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.

14.2.2 Properties of the Tuple Constructor

The Tuple constructor:

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

14.2.2.1 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 closure be a new Abstract Closure with parameter (value) that captures (list, mapFn, thisArg, mapping, k) and performs the following steps when called:
      1. If k β‰₯ 253 - 1, throw a TypeError exception.
      2. If mapping is true, then
        1. Let mappedValue be ? Call(mapfn, thisArg, Β« value, 𝔽(k) Β»).
      3. Else, let mappedValue be value.
      4. If Type(mappedValue) is Object, throw a TypeError exception.
      5. Append mappedValue to list.
      6. Set k to k + 1.
    2. Let adder be CreateBuiltinFunction(closure, 1, "", Β« Β»).
    3. Perform ? AddValuesFromIterable(undefined, items, adder, usingIterator).
    4. 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.

14.2.2.2 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, do
    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.

14.2.2.3 Tuple.prototype

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

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

14.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.

14.2.3.1 thisTupleValue ( value )

The abstract operation thisTupleValue takes argument value and returns either a normal completion containing a Tuple or a throw completion. It throws an exception unless O is an Object and has the given internal slot. 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.[[TupleData]].
    2. Assert: Type(t) is Tuple.
    3. Return t.
  3. Throw a TypeError exception.

14.2.3.2 Tuple.prototype.constructor

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

14.2.3.3 Tuple.prototype.at ( index )

The interpretation and use of the arguments of this method are the same as for Array.prototype.at as defined in 23.1.3.1.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the length of elements.
  4. Let relativeIndex be ? ToIntegerOrInfinity(index).
  5. If relativeIndex β‰₯ 0, then
    1. Let k be relativeIndex.
  6. Else,
    1. Let k be len + relativeIndex.
  7. If k < 0 or k β‰₯ len, return undefined.
  8. Return elements[k].

14.2.3.4 Tuple.prototype.valueOf ( )

This method performs the following steps when called:

  1. Return ? thisTupleValue(this value).

14.2.3.5 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 }.

14.2.3.6 Tuple.prototype.slice ( start, end )

The interpretation and use of the arguments of this method are the same as for Array.prototype.slice as defined in 23.1.3.28.

This method performs the following steps when called:

  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 ? ToIntegerOrInfinity(start).
  5. If relativeStart is -∞, let k be 0.
  6. Else if relativeStart < 0, let k be max((len + relativeStart), 0); else let k be min(relativeStart, len).
  7. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  8. If relativeEnd is -∞, let final be 0.
  9. Else if relativeEnd < 0, let final be max((len + relativeEnd), 0); else let final be min(relativeEnd, len).
  10. Let newList be a new empty List.
  11. 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.
  12. Return a new Tuple value whose [[Sequence]] is newList.

14.2.3.7 Tuple.prototype.concat ( ...args )

The interpretation and use of the arguments of this method are the same as for Array.prototype.concat as defined in 23.1.3.2.

This method performs the following steps when called:

  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 ? IsArrayOrTuple(E).
    3. If spreadable is true, then
      1. Set E to ! ToObject(E).
      2. Let k be 0.
      3. Let len be ? LengthOfArrayLike(E).
      4. If n + len > 253 - 1, throw a TypeError exception.
      5. 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.

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.includes as defined in 23.1.3.16.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the length of elements.
  4. If len is 0, return false.
  5. Let n be ? ToIntegerOrInfinity(fromIndex).
  6. Assert: If fromIndex is undefined, then n is 0.
  7. If n is +∞, return false.
  8. Else if n is -∞, set n to 0.
  9. If n β‰₯ 0, then
    1. Let k be n.
  10. Else,
    1. Let k be len + n.
    2. If k < 0, set k to 0.
  11. Repeat, while k < len,
    1. Let elementK be elements[k].
    2. If SameValueZero(searchElement, elementK) is true, return true.
    3. Set k to k + 1.
  12. Return false.

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.indexOf as defined in 23.1.3.17.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the length of elements.
  4. If len is 0, return -1𝔽.
  5. Let n be ? ToIntegerOrInfinity(fromIndex).
  6. Assert: If fromIndex is undefined, then n is 0.
  7. If n is +∞, return -1𝔽.
  8. Else if n is -∞, set n to 0.
  9. If n β‰₯ 0, then
    1. Let k be n.
  10. Else,
    1. Let k be len + n.
    2. If k < 0, set k to 0.
  11. Repeat, while k < len,
    1. Let elementK be elements[k].
    2. Let same be IsStrictlyEqual(searchElement, elementK).
    3. If same is true, return 𝔽(k).
    4. Set k to k + 1.
  12. Return -1𝔽.

14.2.3.10 Tuple.prototype.join ( separator )

The interpretation and use of the arguments of this method are the same as for Array.prototype.join as defined in 23.1.3.18.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the length of elements.
  4. If separator is undefined, let sep be ",".
  5. Else, let sep be ? ToString(separator).
  6. Let R be the empty String.
  7. Let k be 0.
  8. Repeat, while k < len,
    1. If k > 0, set R to the string-concatenation of R and sep.
    2. Let elementK be elements[k].
    3. If elementK is undefined or null, let next be the empty String; otherwise, let next be ? ToString(elementK).
    4. Set R to the string-concatenation of R and next.
    5. Set k to k + 1.
  9. Return R.

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.lastIndexOf as defined in 23.1.3.20.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the length of elements.
  4. If len is 0, return -1𝔽.
  5. If fromIndex is present, let n be ? ToIntegerOrInfinity(fromIndex); else let n be len - 1.
  6. If n is -∞, return -1𝔽.
  7. If n β‰₯ 0, then
    1. Let k be min(n, len - 1).
  8. Else,
    1. Let k be len + n.
  9. Repeat, while k β‰₯ 0,
    1. Let elementK be elements[k].
    2. Let same be IsStrictlyEqual(searchElement, elementK).
    3. If same is true, return 𝔽(k).
    4. Set k to k - 1.
  10. Return -1𝔽.

14.2.3.12 Tuple.prototype.entries ( )

This method performs the following steps when called:

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

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.every as defined in 23.1.3.6.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the length of elements.
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let kValue be elements[k].
    2. Let testResult be ToBoolean(? Call(callbackfn, thisArg, Β« kValue, 𝔽(k), T Β»)).
    3. If testResult is false, return false.
    4. Set k to k + 1.
  7. Return true.

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.filter as defined in 23.1.3.8.

This method performs the following steps when called:

  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.

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.find as defined in 23.1.3.9.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the number of elements in elements.
  4. If IsCallable(predicate) is false, throw a TypeError exception.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let kValue be ? elements[k].
    2. Let testResult be ToBoolean(? Call(predicate, thisArg, Β« kValue, 𝔽(k), T Β»)).
    3. If testResult is true, return kValue.
    4. Set k to k + 1.
  7. Return undefined.

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.findIndex as defined in 23.1.3.10.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the number of elements in elements.
  4. If IsCallable(predicate) is false, throw a TypeError exception.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let kValue be ? elements[k].
    2. Let testResult be ToBoolean(? Call(predicate, thisArg, Β« kValue, 𝔽(k), T Β»)).
    3. If testResult is true, return 𝔽(k).
    4. Set k to k + 1.
  7. Return -1𝔽.

14.2.3.17 Tuple.prototype.findLast ( predicate [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.findLast as defined in 23.1.3.11.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the number of elements in elements.
  4. If IsCallable(predicate) is false, throw a TypeError exception.
  5. Let k be len - 1.
  6. Repeat, while k β‰₯ 0,
    1. Let kValue be elements[k].
    2. Let testResult be ToBoolean(? Call(predicate, thisArg, Β« kValue, 𝔽(k), T Β»)).
    3. If testResult is true, return kValue.
    4. Set k to k - 1.
  7. Return undefined.

14.2.3.18 Tuple.prototype.findLastIndex ( predicate [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.findLsatIndex as defined in 23.1.3.12.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the number of elements in elements.
  4. If IsCallable(predicate) is false, throw a TypeError exception.
  5. Let k be len - 1.
  6. Repeat, while k β‰₯ 0,
    1. Let kValue be elements[k].
    2. Let testResult be ToBoolean(? Call(predicate, thisArg, Β« kValue, 𝔽(k), T Β»)).
    3. If testResult is true, return 𝔽(k).
    4. Set k to k - 1.
  7. Return -1𝔽.

14.2.3.19 Tuple.prototype.flat ( [ depth ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.flat as defined in 23.1.3.13.

This method performs the following steps when called:

  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 ? ToIntegerOrInfinity(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.

14.2.3.19.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: IsIntegralNumber(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 element of source, do
    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.

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.flatMap as defined in 23.1.3.14.

This method performs the following steps when called:

  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.

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.forEach as defined in 23.1.3.15.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the number of elements in elements.
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let kValue be elements[k].
    2. Perform ? Call(callbackfn, thisArg, Β« kValue, 𝔽(k), T Β»).
    3. Set k to k + 1.
  7. Return undefined.

14.2.3.22 Tuple.prototype.keys ( )

This method performs the following steps when called:

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

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.map as defined in 23.1.3.21.

This method performs the following steps when called:

  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.

14.2.3.24 Tuple.prototype.reduce ( callbackfn [ , initialValue ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.reduce as defined in 23.1.3.24.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the number of elements in elements.
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. If len = 0 and initialValue is not present, throw a TypeError exception.
  6. Let k be 0.
  7. Let accumulator be undefined.
  8. If initialValue is present, then
    1. Set accumulator to initialValue.
  9. Else,
    1. Set accumulator to the first element of elements.
    2. Set k to 1.
  10. Repeat, while k < len,
    1. Let kValue be elements[k].
    2. Set accumulator to ? Call(callbackfn, undefined, Β« accumulator, kValue, 𝔽(k), T Β»).
    3. Set k to k + 1.
  11. Return accumulator.

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.reduceRight as defined in 23.1.3.25.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the number of elements in elements.
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. If len is 0 and initialValue is not present, throw a TypeError exception.
  6. Let k be len - 1.
  7. Let accumulator be undefined.
  8. If initialValue is present, then
    1. Set accumulator to initialValue.
  9. Else,
    1. Set accumulator to the last element of elements.
    2. Set k to k - 1.
  10. Repeat, while k β‰₯ 0,
    1. Let kValue be elements[k].
    2. Set accumulator to ? Call(callbackfn, undefined, Β« accumulator, kValue, 𝔽(k), T Β»).
    3. Set k to k - 1.
  11. Return accumulator.

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.some as defined in 23.1.3.29.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the number of elements in elements.
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let kValue be elements[k].
    2. Let testResult be ToBoolean(? Call(callbackfn, thisArg, Β« kValue, 𝔽(k), T Β»)).
    3. If testResult is true, return true.
    4. Set k to k + 1.
  7. Return false.

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

The interpretation and use of the arguments of this method are the same as for Array.prototype.toLocaleString as defined in 23.1.3.32.

This method performs the following steps when called:

  1. Let T be ? thisTupleValue(this value).
  2. Let elements be T.[[Sequence]].
  3. Let len be the number of elements in elements.
  4. Let separator be the implementation-defined list-separator String value appropriate for the host environment's current locale (such as ", ").
  5. Let R be the empty String.
  6. Let k be 0.
  7. Repeat, while k < len,
    1. If k > 0, then
      1. Set R to the string-concatenation of R and separator.
    2. Let nextElement be elements[k].
    3. If nextElement is not undefined or null, then
      1. Let S be ? ToString(? Invoke(nextElement, "toLocaleString")).
      2. Set R to the string-concatenation of R and S.
    4. Set k to k + 1.
  8. Return R.

14.2.3.28 Tuple.prototype.toString ( )

This method performs the following steps when called:

  1. Let tuple be ? thisTupleValue(this value).
  2. Return TupleToString(tuple).

14.2.3.29 Tuple.prototype.values ( )

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

It performs the following steps when called:

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

14.2.3.30 Tuple.prototype [ @@iterator ] ( )

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

14.2.3.31 Tuple.prototype.toReversed ( )

The interpretation and use of the arguments of this method are the same as for Array.prototype.reverse as defined in 23.1.3.26, but it creates a new tuple rather than mutating its receiver.

Editor's Note
Once the Change Array by Copy proposal reaches stage 4, the above paragraph will be updated to reference Array.prototype.toReversed.

This method performs the following steps when called:

  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.

14.2.3.32 Tuple.prototype.toSorted ( comparefn )

The interpretation and use of the arguments of this method are the same as for Array.prototype.sort as defined in 23.1.3.30, but it creates a new tuple rather than mutating its receiver.

Editor's Note
Once the Change Array by Copy proposal reaches stage 4, the above paragraph will be updated to reference Array.prototype.toSorted.

This method performs the following steps when called:

  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. Sort list using an implementation-defined sequence of calls to SortCompare. If any such call returns an abrupt completion, stop before performing any further calls to SortCompare or steps in this algorithm and return that completion.
  5. Return a new Tuple value whose [[Sequence]] is list.

The elements of list are sorted in the same order as if they were sorted in an Array via %Array.prototype.sort% with comparefn as the first argument.

14.2.3.33 Tuple.prototype.toSpliced ( start, deleteCount, ...items )

The interpretation and use of the arguments of this method are the same as for Array.prototype.splice as defined in 23.1.3.31, but it creates a new tuple rather than mutating its receiver.

Editor's Note
Once the Change Array by Copy proposal reaches stage 4, the above paragraph will be updated to reference Array.prototype.toSpliced.

This method performs the following steps when called:

  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 ? ToIntegerOrInfinity(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 ? ToIntegerOrInfinity(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.

14.2.3.34 Tuple.prototype.with ( index, value )

Editor's Note
Once the Change Array by Copy proposal reaches stage 4, this method will have the same introduction used for all the other methods and it will reference Array.prototype.with.

This method performs the following steps when called:

  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 relativeIndex be ? ToIntegerOrInfinity(index).
  5. If index β‰₯ 0, let actualIndex be relativeIndex.
  6. Else, let actualIndex be len + relativeIndex.
  7. If actualIndex β‰₯ len or actualIndex < 0, throw a RangeError exception.
  8. If Type(value) is Object, throw a TypeError exception.
  9. Set list[actualIndex] to value.
  10. Return a new Tuple value whose [[Sequence]] is list.

20 Fundamental Objects

20.1 Object Objects

20.1.3 Properties of the Object Prototype Object

20.1.3.6 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, let builtinTag be "Object".
  17. Let tag be ? Get(O, @@toStringTag).
  18. If Type(tag) is not String, set tag to builtinTag.
  19. 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.

999 Purely editorial changes

These changes to unrelated parts of the ecma262 specification are editorial and don't affect the behaviour of the modified algorithms. They are refactorings used to share existing algorithm steps with the new algorithms introduced by this proposal.

999.1 Set Objects

999.1.1 The Set Constructor

999.1.1.1 Set ( [ iterable ] )

When the Set function is called with optional argument iterable, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%Set.prototype%", Β« [[SetData]] Β»).
  3. Set set.[[SetData]] to a new empty List.
  4. If iterable is either undefined or null, return set.
  5. Let adder be ? Get(set, "add").
  6. If IsCallable(adder) is false, throw a TypeError exception.
  7. Let iteratorRecord be ? GetIterator(iterable).
  8. Repeat, while true,
    1. Let next be ? IteratorStep(iteratorRecord).
    2. If next is false, return set.
    3. Let nextValue be ? IteratorValue(next).
    4. Let status be Completion(Call(adder, set, Β« nextValue Β»)).
    5. IfAbruptCloseIterator(status, iteratorRecord).
  9. Return ? AddValuesFromIterable(set, iterable, adder).

999.1.1.1.1 AddValuesFromIterable ( target, iterable, adder [ , iteratorMethod ] )

The abstract operation AddValuesFromIterable takes arguments target, iterable (an ECMAScript language value, but not undefined or null), and adder (a function object) and optional argument iteratorMethod (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value, or a throw completion. adder will be invoked, with target as the receiver. It performs the following steps when called:

  1. If IsCallable(adder) is false, throw a TypeError exception.
  2. If iteratorMethod is present, let iteratorRecord be ? GetIterator(iterable, sync, iteratorMethod).
  3. Else, let iteratorRecord be ? GetIterator(iterable).
  4. Repeat,
    1. Let next be ? IteratorStep(iteratorRecord).
    2. If next is false, return target.
    3. Let nextValue be ? IteratorValue(next).
    4. Let status be Completion(Call(adder, target, Β« nextValue Β»)).
    5. IfAbruptCloseIterator(status, iteratorRecord).
Note

The parameter iterable is expected to be an object that implements an @@iterator method that returns an iterator object. If iteratorMethod is defined, it should have been obtained by getting the @@iterator method of iterable.

999.2 WeakSet Objects

999.2.1 The WeakSet Constructor

999.2.1.1 WeakSet ( [ iterable ] )

When the WeakSet function is called with optional argument iterable, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakSet.prototype%", Β« [[WeakSetData]] Β»).
  3. Set set.[[WeakSetData]] to a new empty List.
  4. If iterable is either undefined or null, return set.
  5. Let adder be ? Get(set, "add").
  6. If IsCallable(adder) is false, throw a TypeError exception.
  7. Let iteratorRecord be ? GetIterator(iterable).
  8. Repeat, while true,
    1. Let next be ? IteratorStep(iteratorRecord).
    2. If next is false, return set.
    3. Let nextValue be ? IteratorValue(next).
    4. Let status be Completion(Call(adder, set, Β« nextValue Β»)).
    5. IfAbruptCloseIterator(status, iteratorRecord).
  9. Return ? AddValuesFromIterable(set, iterable, adder).

A Copyright & Software License

Copyright Notice

Β© 2023 Robin Ricard, Rick Button, Ashley Claymore, NicolΓ² Ribaudo

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.