ECMAScript® 2024 Language Specification

Draft ECMA-262 / February 15, 2024

7.3 Operations on Objects

7.3.1 MakeBasicObject ( internalSlotsList )

The abstract operation MakeBasicObject takes argument internalSlotsList (a List of internal slot names) and returns an Object. It is the source of all ECMAScript objects that are created algorithmically, including both ordinary objects and exotic objects. It factors out common steps used in creating all objects, and centralizes object creation. It performs the following steps when called:

  1. Let obj be a newly created object with an internal slot for each name in internalSlotsList.
  2. Set obj's essential internal methods to the default ordinary object definitions specified in 10.1.
  3. Assert: If the caller will not be overriding both obj's [[GetPrototypeOf]] and [[SetPrototypeOf]] essential internal methods, then internalSlotsList contains [[Prototype]].
  4. Assert: If the caller will not be overriding all of obj's [[SetPrototypeOf]], [[IsExtensible]], and [[PreventExtensions]] essential internal methods, then internalSlotsList contains [[Extensible]].
  5. If internalSlotsList contains [[Extensible]], set obj.[[Extensible]] to true.
  6. Return obj.
Note

Within this specification, exotic objects are created in abstract operations such as ArrayCreate and BoundFunctionCreate by first calling MakeBasicObject to obtain a basic, foundational object, and then overriding some or all of that object's internal methods. In order to encapsulate exotic object creation, the object's essential internal methods are never modified outside those operations.

7.3.2 Get ( O, P )

The abstract operation Get takes arguments O (an Object) and P (a property key) and returns either a normal completion containing an ECMAScript language value or a throw completion. It is used to retrieve the value of a specific property of an object. It performs the following steps when called:

  1. Return ? O.[[Get]](P, O).

7.3.3 GetV ( V, P )

The abstract operation GetV takes arguments V (an ECMAScript language value) and P (a property key) and returns either a normal completion containing an ECMAScript language value or a throw completion. It is used to retrieve the value of a specific property of an ECMAScript language value. If the value is not an object, the property lookup is performed using a wrapper object appropriate for the type of the value. It performs the following steps when called:

  1. Let O be ? ToObject(V).
  2. Return ? O.[[Get]](P, V).

7.3.4 Set ( O, P, V, Throw )

The abstract operation Set takes arguments O (an Object), P (a property key), V (an ECMAScript language value), and Throw (a Boolean) and returns either a normal completion containing unused or a throw completion. It is used to set the value of a specific property of an object. V is the new value for the property. It performs the following steps when called:

  1. Let success be ? O.[[Set]](P, V, O).
  2. If success is false and Throw is true, throw a TypeError exception.
  3. Return unused.

7.3.5 CreateDataProperty ( O, P, V )

The abstract operation CreateDataProperty takes arguments O (an Object), P (a property key), and V (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. It is used to create a new own property of an object. It performs the following steps when called:

  1. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }.
  2. Return ? O.[[DefineOwnProperty]](P, newDesc).
Note

This abstract operation creates a property whose attributes are set to the same defaults used for properties created by the ECMAScript language assignment operator. Normally, the property will not already exist. If it does exist and is not configurable or if O is not extensible, [[DefineOwnProperty]] will return false.

7.3.6 CreateMethodProperty ( O, P, V )

The abstract operation CreateMethodProperty takes arguments O (an Object), P (a property key), and V (an ECMAScript language value) and returns unused. It is used to create a new own property of an ordinary object. It performs the following steps when called:

  1. Assert: O is an ordinary, extensible object with no non-configurable properties.
  2. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
  3. Perform ! DefinePropertyOrThrow(O, P, newDesc).
  4. Return unused.
Note

This abstract operation creates a property whose attributes are set to the same defaults used for built-in methods and methods defined using class declaration syntax. Normally, the property will not already exist. If it does exist, DefinePropertyOrThrow is guaranteed to complete normally.

7.3.7 CreateDataPropertyOrThrow ( O, P, V )

The abstract operation CreateDataPropertyOrThrow takes arguments O (an Object), P (a property key), and V (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. It is used to create a new own property of an object. It throws a TypeError exception if the requested property update cannot be performed. It performs the following steps when called:

  1. Let success be ? CreateDataProperty(O, P, V).
  2. If success is false, throw a TypeError exception.
  3. Return unused.
Note

This abstract operation creates a property whose attributes are set to the same defaults used for properties created by the ECMAScript language assignment operator. Normally, the property will not already exist. If it does exist and is not configurable or if O is not extensible, [[DefineOwnProperty]] will return false causing this operation to throw a TypeError exception.

7.3.8 CreateNonEnumerableDataPropertyOrThrow ( O, P, V )

The abstract operation CreateNonEnumerableDataPropertyOrThrow takes arguments O (an Object), P (a property key), and V (an ECMAScript language value) and returns unused. It is used to create a new non-enumerable own property of an ordinary object. It performs the following steps when called:

  1. Assert: O is an ordinary, extensible object with no non-configurable properties.
  2. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
  3. Perform ! DefinePropertyOrThrow(O, P, newDesc).
  4. Return unused.
Note

This abstract operation creates a property whose attributes are set to the same defaults used for properties created by the ECMAScript language assignment operator except it is not enumerable. Normally, the property will not already exist. If it does exist, DefinePropertyOrThrow is guaranteed to complete normally.

7.3.9 DefinePropertyOrThrow ( O, P, desc )

The abstract operation DefinePropertyOrThrow takes arguments O (an Object), P (a property key), and desc (a Property Descriptor) and returns either a normal completion containing unused or a throw completion. It is used to call the [[DefineOwnProperty]] internal method of an object in a manner that will throw a TypeError exception if the requested property update cannot be performed. It performs the following steps when called:

  1. Let success be ? O.[[DefineOwnProperty]](P, desc).
  2. If success is false, throw a TypeError exception.
  3. Return unused.

7.3.10 DeletePropertyOrThrow ( O, P )

The abstract operation DeletePropertyOrThrow takes arguments O (an Object) and P (a property key) and returns either a normal completion containing unused or a throw completion. It is used to remove a specific own property of an object. It throws an exception if the property is not configurable. It performs the following steps when called:

  1. Let success be ? O.[[Delete]](P).
  2. If success is false, throw a TypeError exception.
  3. Return unused.

7.3.11 GetMethod ( V, P )

The abstract operation GetMethod takes arguments V (an ECMAScript language value) and P (a property key) and returns either a normal completion containing either a function object or undefined, or a throw completion. It is used to get the value of a specific property of an ECMAScript language value when the value of the property is expected to be a function. It performs the following steps when called:

  1. Let func be ? GetV(V, P).
  2. If func is either undefined or null, return undefined.
  3. If IsCallable(func) is false, throw a TypeError exception.
  4. Return func.

7.3.12 HasProperty ( O, P )

The abstract operation HasProperty takes arguments O (an Object) and P (a property key) and returns either a normal completion containing a Boolean or a throw completion. It is used to determine whether an object has a property with the specified property key. The property may be either own or inherited. It performs the following steps when called:

  1. Return ? O.[[HasProperty]](P).

7.3.13 HasOwnProperty ( O, P )

The abstract operation HasOwnProperty takes arguments O (an Object) and P (a property key) and returns either a normal completion containing a Boolean or a throw completion. It is used to determine whether an object has an own property with the specified property key. It performs the following steps when called:

  1. Let desc be ? O.[[GetOwnProperty]](P).
  2. If desc is undefined, return false.
  3. Return true.

7.3.14 Call ( F, V [ , argumentsList ] )

The abstract operation Call takes arguments F (an ECMAScript language value) and V (an ECMAScript language value) and optional argument argumentsList (a List of ECMAScript language values) and returns either a normal completion containing an ECMAScript language value or a throw completion. It is used to call the [[Call]] internal method of a function object. F is the function object, V is an ECMAScript language value that is the this value of the [[Call]], and argumentsList is the value passed to the corresponding argument of the internal method. If argumentsList is not present, a new empty List is used as its value. It performs the following steps when called:

  1. If argumentsList is not present, set argumentsList to a new empty List.
  2. If IsCallable(F) is false, throw a TypeError exception.
  3. Return ? F.[[Call]](V, argumentsList).

7.3.15 Construct ( F [ , argumentsList [ , newTarget ] ] )

The abstract operation Construct takes argument F (a constructor) and optional arguments argumentsList (a List of ECMAScript language values) and newTarget (a constructor) and returns either a normal completion containing an Object or a throw completion. It is used to call the [[Construct]] internal method of a function object. argumentsList and newTarget are the values to be passed as the corresponding arguments of the internal method. If argumentsList is not present, a new empty List is used as its value. If newTarget is not present, F is used as its value. It performs the following steps when called:

  1. If newTarget is not present, set newTarget to F.
  2. If argumentsList is not present, set argumentsList to a new empty List.
  3. Return ? F.[[Construct]](argumentsList, newTarget).
Note

If newTarget is not present, this operation is equivalent to: new F(...argumentsList)

7.3.16 SetIntegrityLevel ( O, level )

The abstract operation SetIntegrityLevel takes arguments O (an Object) and level (sealed or frozen) and returns either a normal completion containing a Boolean or a throw completion. It is used to fix the set of own properties of an object. It performs the following steps when called:

  1. Let status be ? O.[[PreventExtensions]]().
  2. If status is false, return false.
  3. Let keys be ? O.[[OwnPropertyKeys]]().
  4. If level is sealed, then
    1. For each element k of keys, do
      1. Perform ? DefinePropertyOrThrow(O, k, PropertyDescriptor { [[Configurable]]: false }).
  5. Else,
    1. Assert: level is frozen.
    2. For each element k of keys, do
      1. Let currentDesc be ? O.[[GetOwnProperty]](k).
      2. If currentDesc is not undefined, then
        1. If IsAccessorDescriptor(currentDesc) is true, then
          1. Let desc be the PropertyDescriptor { [[Configurable]]: false }.
        2. Else,
          1. Let desc be the PropertyDescriptor { [[Configurable]]: false, [[Writable]]: false }.
        3. Perform ? DefinePropertyOrThrow(O, k, desc).
  6. Return true.

7.3.17 TestIntegrityLevel ( O, level )

The abstract operation TestIntegrityLevel takes arguments O (an Object) and level (sealed or frozen) and returns either a normal completion containing a Boolean or a throw completion. It is used to determine if the set of own properties of an object are fixed. It performs the following steps when called:

  1. Let extensible be ? IsExtensible(O).
  2. If extensible is true, return false.
  3. NOTE: If the object is extensible, none of its properties are examined.
  4. Let keys be ? O.[[OwnPropertyKeys]]().
  5. For each element k of keys, do
    1. Let currentDesc be ? O.[[GetOwnProperty]](k).
    2. If currentDesc is not undefined, then
      1. If currentDesc.[[Configurable]] is true, return false.
      2. If level is frozen and IsDataDescriptor(currentDesc) is true, then
        1. If currentDesc.[[Writable]] is true, return false.
  6. Return true.

7.3.18 CreateArrayFromList ( elements )

The abstract operation CreateArrayFromList takes argument elements (a List of ECMAScript language values) and returns an Array. It is used to create an Array whose elements are provided by elements. It performs the following steps when called:

  1. Let array be ! ArrayCreate(0).
  2. Let n be 0.
  3. For each element e of elements, do
    1. Perform ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(n)), e).
    2. Set n to n + 1.
  4. Return array.

7.3.19 LengthOfArrayLike ( obj )

The abstract operation LengthOfArrayLike takes argument obj (an Object) and returns either a normal completion containing a non-negative integer or a throw completion. It returns the value of the "length" property of an array-like object. It performs the following steps when called:

  1. Return (? ToLength(? Get(obj, "length"))).

An array-like object is any object for which this operation returns a normal completion.

Note 1
Typically, an array-like object would also have some properties with integer index names. However, that is not a requirement of this definition.
Note 2
Arrays and String objects are examples of array-like objects.

7.3.20 CreateListFromArrayLike ( obj [ , elementTypes ] )

The abstract operation CreateListFromArrayLike takes argument obj (an ECMAScript language value) and optional argument elementTypes (a List of names of ECMAScript Language Types) and returns either a normal completion containing a List of ECMAScript language values or a throw completion. It is used to create a List value whose elements are provided by the indexed properties of obj. elementTypes contains the names of ECMAScript Language Types that are allowed for element values of the List that is created. It performs the following steps when called:

  1. If elementTypes is not present, set elementTypes to « Undefined, Null, Boolean, String, Symbol, Number, BigInt, Object ».
  2. If obj is not an Object, throw a TypeError exception.
  3. Let len be ? LengthOfArrayLike(obj).
  4. Let list be a new empty List.
  5. Let index be 0.
  6. Repeat, while index < len,
    1. Let indexName be ! ToString(𝔽(index)).
    2. Let next be ? Get(obj, indexName).
    3. If elementTypes does not contain Type(next), throw a TypeError exception.
    4. Append next to list.
    5. Set index to index + 1.
  7. Return list.

7.3.21 Invoke ( V, P [ , argumentsList ] )

The abstract operation Invoke takes arguments V (an ECMAScript language value) and P (a property key) and optional argument argumentsList (a List of ECMAScript language values) and returns either a normal completion containing an ECMAScript language value or a throw completion. It is used to call a method property of an ECMAScript language value. V serves as both the lookup point for the property and the this value of the call. argumentsList is the list of arguments values passed to the method. If argumentsList is not present, a new empty List is used as its value. It performs the following steps when called:

  1. If argumentsList is not present, set argumentsList to a new empty List.
  2. Let func be ? GetV(V, P).
  3. Return ? Call(func, V, argumentsList).

7.3.22 OrdinaryHasInstance ( C, O )

The abstract operation OrdinaryHasInstance takes arguments C (an ECMAScript language value) and O (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. It implements the default algorithm for determining if O inherits from the instance object inheritance path provided by C. It performs the following steps when called:

  1. If IsCallable(C) is false, return false.
  2. If C has a [[BoundTargetFunction]] internal slot, then
    1. Let BC be C.[[BoundTargetFunction]].
    2. Return ? InstanceofOperator(O, BC).
  3. If O is not an Object, return false.
  4. Let P be ? Get(C, "prototype").
  5. If P is not an Object, throw a TypeError exception.
  6. Repeat,
    1. Set O to ? O.[[GetPrototypeOf]]().
    2. If O is null, return false.
    3. If SameValue(P, O) is true, return true.

7.3.23 SpeciesConstructor ( O, defaultConstructor )

The abstract operation SpeciesConstructor takes arguments O (an Object) and defaultConstructor (a constructor) and returns either a normal completion containing a constructor or a throw completion. It is used to retrieve the constructor that should be used to create new objects that are derived from O. defaultConstructor is the constructor to use if a constructor @@species property cannot be found starting from O. It performs the following steps when called:

  1. Let C be ? Get(O, "constructor").
  2. If C is undefined, return defaultConstructor.
  3. If C is not an Object, throw a TypeError exception.
  4. Let S be ? Get(C, @@species).
  5. If S is either undefined or null, return defaultConstructor.
  6. If IsConstructor(S) is true, return S.
  7. Throw a TypeError exception.

7.3.24 EnumerableOwnProperties ( O, kind )

The abstract operation EnumerableOwnProperties takes arguments O (an Object) and kind (key, value, or key+value) and returns either a normal completion containing a List of ECMAScript language values or a throw completion. It performs the following steps when called:

  1. Let ownKeys be ? O.[[OwnPropertyKeys]]().
  2. Let results be a new empty List.
  3. For each element key of ownKeys, do
    1. If key is a String, then
      1. Let desc be ? O.[[GetOwnProperty]](key).
      2. If desc is not undefined and desc.[[Enumerable]] is true, then
        1. If kind is key, then
          1. Append key to results.
        2. Else,
          1. Let value be ? Get(O, key).
          2. If kind is value, then
            1. Append value to results.
          3. Else,
            1. Assert: kind is key+value.
            2. Let entry be CreateArrayFromListkey, value »).
            3. Append entry to results.
  4. Return results.

7.3.25 GetFunctionRealm ( obj )

The abstract operation GetFunctionRealm takes argument obj (a function object) and returns either a normal completion containing a Realm Record or a throw completion. It performs the following steps when called:

  1. If obj has a [[Realm]] internal slot, then
    1. Return obj.[[Realm]].
  2. If obj is a bound function exotic object, then
    1. Let boundTargetFunction be obj.[[BoundTargetFunction]].
    2. Return ? GetFunctionRealm(boundTargetFunction).
  3. If obj is a Proxy exotic object, then
    1. Perform ? ValidateNonRevokedProxy(obj).
    2. Let proxyTarget be obj.[[ProxyTarget]].
    3. Return ? GetFunctionRealm(proxyTarget).
  4. Return the current Realm Record.
Note

Step 4 will only be reached if obj is a non-standard function exotic object that does not have a [[Realm]] internal slot.

7.3.26 CopyDataProperties ( target, source, excludedItems )

The abstract operation CopyDataProperties takes arguments target (an Object), source (an ECMAScript language value), and excludedItems (a List of property keys) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. If source is either undefined or null, return unused.
  2. Let from be ! ToObject(source).
  3. Let keys be ? from.[[OwnPropertyKeys]]().
  4. For each element nextKey of keys, do
    1. Let excluded be false.
    2. For each element e of excludedItems, do
      1. If SameValue(e, nextKey) is true, then
        1. Set excluded to true.
    3. If excluded is false, then
      1. Let desc be ? from.[[GetOwnProperty]](nextKey).
      2. If desc is not undefined and desc.[[Enumerable]] is true, then
        1. Let propValue be ? Get(from, nextKey).
        2. Perform ! CreateDataPropertyOrThrow(target, nextKey, propValue).
  5. Return unused.
Note

The target passed in here is always a newly created object which is not directly accessible in case of an error being thrown.

7.3.27 PrivateElementFind ( O, P )

The abstract operation PrivateElementFind takes arguments O (an Object) and P (a Private Name) and returns a PrivateElement or empty. It performs the following steps when called:

  1. If O.[[PrivateElements]] contains a PrivateElement pe such that pe.[[Key]] is P, then
    1. Return pe.
  2. Return empty.

7.3.28 PrivateFieldAdd ( O, P, value )

The abstract operation PrivateFieldAdd takes arguments O (an Object), P (a Private Name), and value (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. If the host is a web browser, then
    1. Perform ? HostEnsureCanAddPrivateElement(O).
  2. Let entry be PrivateElementFind(O, P).
  3. If entry is not empty, throw a TypeError exception.
  4. Append PrivateElement { [[Key]]: P, [[Kind]]: field, [[Value]]: value } to O.[[PrivateElements]].
  5. Return unused.

7.3.29 PrivateMethodOrAccessorAdd ( O, method )

The abstract operation PrivateMethodOrAccessorAdd takes arguments O (an Object) and method (a PrivateElement) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Assert: method.[[Kind]] is either method or accessor.
  2. If the host is a web browser, then
    1. Perform ? HostEnsureCanAddPrivateElement(O).
  3. Let entry be PrivateElementFind(O, method.[[Key]]).
  4. If entry is not empty, throw a TypeError exception.
  5. Append method to O.[[PrivateElements]].
  6. Return unused.
Note

The values for private methods and accessors are shared across instances. This operation does not create a new copy of the method or accessor.

7.3.30 HostEnsureCanAddPrivateElement ( O )

The host-defined abstract operation HostEnsureCanAddPrivateElement takes argument O (an Object) and returns either a normal completion containing unused or a throw completion. It allows host environments to prevent the addition of private elements to particular host-defined exotic objects.

An implementation of HostEnsureCanAddPrivateElement must conform to the following requirements:

The default implementation of HostEnsureCanAddPrivateElement is to return NormalCompletion(unused).

This abstract operation is only invoked by ECMAScript hosts that are web browsers.

7.3.31 PrivateGet ( O, P )

The abstract operation PrivateGet takes arguments O (an Object) and P (a Private Name) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let entry be PrivateElementFind(O, P).
  2. If entry is empty, throw a TypeError exception.
  3. If entry.[[Kind]] is either field or method, then
    1. Return entry.[[Value]].
  4. Assert: entry.[[Kind]] is accessor.
  5. If entry.[[Get]] is undefined, throw a TypeError exception.
  6. Let getter be entry.[[Get]].
  7. Return ? Call(getter, O).

7.3.32 PrivateSet ( O, P, value )

The abstract operation PrivateSet takes arguments O (an Object), P (a Private Name), and value (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let entry be PrivateElementFind(O, P).
  2. If entry is empty, throw a TypeError exception.
  3. If entry.[[Kind]] is field, then
    1. Set entry.[[Value]] to value.
  4. Else if entry.[[Kind]] is method, then
    1. Throw a TypeError exception.
  5. Else,
    1. Assert: entry.[[Kind]] is accessor.
    2. If entry.[[Set]] is undefined, throw a TypeError exception.
    3. Let setter be entry.[[Set]].
    4. Perform ? Call(setter, O, « value »).
  6. Return unused.

7.3.33 DefineField ( receiver, fieldRecord )

The abstract operation DefineField takes arguments receiver (an Object) and fieldRecord (a ClassFieldDefinition Record) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let fieldName be fieldRecord.[[Name]].
  2. Let initializer be fieldRecord.[[Initializer]].
  3. If initializer is not empty, then
    1. Let initValue be ? Call(initializer, receiver).
  4. Else,
    1. Let initValue be undefined.
  5. If fieldName is a Private Name, then
    1. Perform ? PrivateFieldAdd(receiver, fieldName, initValue).
  6. Else,
    1. Assert: IsPropertyKey(fieldName) is true.
    2. Perform ? CreateDataPropertyOrThrow(receiver, fieldName, initValue).
  7. Return unused.

7.3.34 InitializeInstanceElements ( O, constructor )

The abstract operation InitializeInstanceElements takes arguments O (an Object) and constructor (an ECMAScript function object) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let methods be the value of constructor.[[PrivateMethods]].
  2. For each PrivateElement method of methods, do
    1. Perform ? PrivateMethodOrAccessorAdd(O, method).
  3. Let fields be the value of constructor.[[Fields]].
  4. For each element fieldRecord of fields, do
    1. Perform ? DefineField(O, fieldRecord).
  5. Return unused.

7.3.35 AddValueToKeyedGroup ( groups, key, value )

The abstract operation AddValueToKeyedGroup takes arguments groups (a List of Records with fields [[Key]] (an ECMAScript language value) and [[Elements]] (a List of ECMAScript language values)), key (an ECMAScript language value), and value (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. For each Record { [[Key]], [[Elements]] } g of groups, do
    1. If SameValue(g.[[Key]], key) is true, then
      1. Assert: Exactly one element of groups meets this criterion.
      2. Append value to g.[[Elements]].
      3. Return unused.
  2. Let group be the Record { [[Key]]: key, [[Elements]]: « value » }.
  3. Append group to groups.
  4. Return unused.

7.3.36 GroupBy ( items, callbackfn, keyCoercion )

The abstract operation GroupBy takes arguments items (an ECMAScript language value), callbackfn (an ECMAScript language value), and keyCoercion (property or zero) and returns either a normal completion containing a List of Records with fields [[Key]] (an ECMAScript language value) and [[Elements]] (a List of ECMAScript language values), or a throw completion. It performs the following steps when called:

  1. Perform ? RequireObjectCoercible(items).
  2. If IsCallable(callbackfn) is false, throw a TypeError exception.
  3. Let groups be a new empty List.
  4. Let iteratorRecord be ? GetIterator(items, sync).
  5. Let k be 0.
  6. Repeat,
    1. If k ≥ 253 - 1, then
      1. Let error be ThrowCompletion(a newly created TypeError object).
      2. Return ? IteratorClose(iteratorRecord, error).
    2. Let next be ? IteratorStepValue(iteratorRecord).
    3. If next is done, then
      1. Return groups.
    4. Let value be next.
    5. Let key be Completion(Call(callbackfn, undefined, « value, 𝔽(k) »)).
    6. IfAbruptCloseIterator(key, iteratorRecord).
    7. If keyCoercion is property, then
      1. Set key to Completion(ToPropertyKey(key)).
      2. IfAbruptCloseIterator(key, iteratorRecord).
    8. Else,
      1. Assert: keyCoercion is zero.
      2. If key is -0𝔽, set key to +0𝔽.
    9. Perform AddValueToKeyedGroup(groups, key, value).
    10. Set k to k + 1.