ECMAScript® 2024 Language Specification

Draft ECMA-262 / February 15, 2024

10.4 Built-in Exotic Object Internal Methods and Slots

This specification defines several kinds of built-in exotic objects. These objects generally behave similar to ordinary objects except for a few specific situations. The following exotic objects use the ordinary object internal methods except where it is explicitly specified otherwise below:

10.4.1 Bound Function Exotic Objects

A bound function exotic object is an exotic object that wraps another function object. A bound function exotic object is callable (it has a [[Call]] internal method and may have a [[Construct]] internal method). Calling a bound function exotic object generally results in a call of its wrapped function.

An object is a bound function exotic object if its [[Call]] and (if applicable) [[Construct]] internal methods use the following implementations, and its other essential internal methods use the definitions found in 10.1. These methods are installed in BoundFunctionCreate.

Bound function exotic objects do not have the internal slots of ECMAScript function objects listed in Table 30. Instead they have the internal slots listed in Table 31, in addition to [[Prototype]] and [[Extensible]].

Table 31: Internal Slots of Bound Function Exotic Objects
Internal Slot Type Description
[[BoundTargetFunction]] a callable Object The wrapped function object.
[[BoundThis]] an ECMAScript language value The value that is always passed as the this value when calling the wrapped function.
[[BoundArguments]] a List of ECMAScript language values A list of values whose elements are used as the first arguments to any call to the wrapped function.

10.4.1.1 [[Call]] ( thisArgument, argumentsList )

The [[Call]] internal method of a bound function exotic object F takes arguments thisArgument (an ECMAScript language value) and argumentsList (a List of ECMAScript language values) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let target be F.[[BoundTargetFunction]].
  2. Let boundThis be F.[[BoundThis]].
  3. Let boundArgs be F.[[BoundArguments]].
  4. Let args be the list-concatenation of boundArgs and argumentsList.
  5. Return ? Call(target, boundThis, args).

10.4.1.2 [[Construct]] ( argumentsList, newTarget )

The [[Construct]] internal method of a bound function exotic object F takes 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 performs the following steps when called:

  1. Let target be F.[[BoundTargetFunction]].
  2. Assert: IsConstructor(target) is true.
  3. Let boundArgs be F.[[BoundArguments]].
  4. Let args be the list-concatenation of boundArgs and argumentsList.
  5. If SameValue(F, newTarget) is true, set newTarget to target.
  6. Return ? Construct(target, args, newTarget).

10.4.1.3 BoundFunctionCreate ( targetFunction, boundThis, boundArgs )

The abstract operation BoundFunctionCreate takes arguments targetFunction (a function object), boundThis (an ECMAScript language value), and boundArgs (a List of ECMAScript language values) and returns either a normal completion containing a function object or a throw completion. It is used to specify the creation of new bound function exotic objects. It performs the following steps when called:

  1. Let proto be ? targetFunction.[[GetPrototypeOf]]().
  2. Let internalSlotsList be the list-concatenation of « [[Prototype]], [[Extensible]] » and the internal slots listed in Table 31.
  3. Let obj be MakeBasicObject(internalSlotsList).
  4. Set obj.[[Prototype]] to proto.
  5. Set obj.[[Call]] as described in 10.4.1.1.
  6. If IsConstructor(targetFunction) is true, then
    1. Set obj.[[Construct]] as described in 10.4.1.2.
  7. Set obj.[[BoundTargetFunction]] to targetFunction.
  8. Set obj.[[BoundThis]] to boundThis.
  9. Set obj.[[BoundArguments]] to boundArgs.
  10. Return obj.

10.4.2 Array Exotic Objects

An Array is an exotic object that gives special treatment to array index property keys (see 6.1.7). A property whose property name is an array index is also called an element. Every Array has a non-configurable "length" property whose value is always a non-negative integral Number whose mathematical value is strictly less than 232. The value of the "length" property is numerically greater than the name of every own property whose name is an array index; whenever an own property of an Array is created or changed, other properties are adjusted as necessary to maintain this invariant. Specifically, whenever an own property is added whose name is an array index, the value of the "length" property is changed, if necessary, to be one more than the numeric value of that array index; and whenever the value of the "length" property is changed, every own property whose name is an array index whose value is not smaller than the new length is deleted. This constraint applies only to own properties of an Array and is unaffected by "length" or array index properties that may be inherited from its prototypes.

An object is an Array exotic object (or simply, an Array) if its [[DefineOwnProperty]] internal method uses the following implementation, and its other essential internal methods use the definitions found in 10.1. These methods are installed in ArrayCreate.

10.4.2.1 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of an Array exotic object A takes arguments P (a property key) and Desc (a Property Descriptor) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. If P is "length", then
    1. Return ? ArraySetLength(A, Desc).
  2. Else if P is an array index, then
    1. Let lengthDesc be OrdinaryGetOwnProperty(A, "length").
    2. Assert: IsDataDescriptor(lengthDesc) is true.
    3. Assert: lengthDesc.[[Configurable]] is false.
    4. Let length be lengthDesc.[[Value]].
    5. Assert: length is a non-negative integral Number.
    6. Let index be ! ToUint32(P).
    7. If indexlength and lengthDesc.[[Writable]] is false, return false.
    8. Let succeeded be ! OrdinaryDefineOwnProperty(A, P, Desc).
    9. If succeeded is false, return false.
    10. If indexlength, then
      1. Set lengthDesc.[[Value]] to index + 1𝔽.
      2. Set succeeded to ! OrdinaryDefineOwnProperty(A, "length", lengthDesc).
      3. Assert: succeeded is true.
    11. Return true.
  3. Return ? OrdinaryDefineOwnProperty(A, P, Desc).

10.4.2.2 ArrayCreate ( length [ , proto ] )

The abstract operation ArrayCreate takes argument length (a non-negative integer) and optional argument proto (an Object) and returns either a normal completion containing an Array exotic object or a throw completion. It is used to specify the creation of new Arrays. It performs the following steps when called:

  1. If length > 232 - 1, throw a RangeError exception.
  2. If proto is not present, set proto to %Array.prototype%.
  3. Let A be MakeBasicObject[[Prototype]], [[Extensible]] »).
  4. Set A.[[Prototype]] to proto.
  5. Set A.[[DefineOwnProperty]] as specified in 10.4.2.1.
  6. Perform ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  7. Return A.

10.4.2.3 ArraySpeciesCreate ( originalArray, length )

The abstract operation ArraySpeciesCreate takes arguments originalArray (an Object) and length (a non-negative integer) and returns either a normal completion containing an Object or a throw completion. It is used to specify the creation of a new Array or similar object using a constructor function that is derived from originalArray. It does not enforce that the constructor function returns an Array. It performs the following steps when called:

  1. Let isArray be ? IsArray(originalArray).
  2. If isArray is false, return ? ArrayCreate(length).
  3. Let C be ? Get(originalArray, "constructor").
  4. If IsConstructor(C) is true, then
    1. Let thisRealm be the current Realm Record.
    2. Let realmC be ? GetFunctionRealm(C).
    3. If thisRealm and realmC are not the same Realm Record, then
      1. If SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) is true, set C to undefined.
  5. If C is an Object, then
    1. Set C to ? Get(C, @@species).
    2. If C is null, set C to undefined.
  6. If C is undefined, return ? ArrayCreate(length).
  7. If IsConstructor(C) is false, throw a TypeError exception.
  8. Return ? Construct(C, « 𝔽(length) »).
Note

If originalArray was created using the standard built-in Array constructor for a realm that is not the realm of the running execution context, then a new Array is created using the realm of the running execution context. This maintains compatibility with Web browsers that have historically had that behaviour for the Array.prototype methods that now are defined using ArraySpeciesCreate.

10.4.2.4 ArraySetLength ( A, Desc )

The abstract operation ArraySetLength takes arguments A (an Array) and Desc (a Property Descriptor) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. If Desc does not have a [[Value]] field, then
    1. Return ! OrdinaryDefineOwnProperty(A, "length", Desc).
  2. Let newLenDesc be a copy of Desc.
  3. Let newLen be ? ToUint32(Desc.[[Value]]).
  4. Let numberLen be ? ToNumber(Desc.[[Value]]).
  5. If SameValueZero(newLen, numberLen) is false, throw a RangeError exception.
  6. Set newLenDesc.[[Value]] to newLen.
  7. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
  8. Assert: IsDataDescriptor(oldLenDesc) is true.
  9. Assert: oldLenDesc.[[Configurable]] is false.
  10. Let oldLen be oldLenDesc.[[Value]].
  11. If newLenoldLen, then
    1. Return ! OrdinaryDefineOwnProperty(A, "length", newLenDesc).
  12. If oldLenDesc.[[Writable]] is false, return false.
  13. If newLenDesc does not have a [[Writable]] field or newLenDesc.[[Writable]] is true, then
    1. Let newWritable be true.
  14. Else,
    1. NOTE: Setting the [[Writable]] attribute to false is deferred in case any elements cannot be deleted.
    2. Let newWritable be false.
    3. Set newLenDesc.[[Writable]] to true.
  15. Let succeeded be ! OrdinaryDefineOwnProperty(A, "length", newLenDesc).
  16. If succeeded is false, return false.
  17. For each own property key P of A such that P is an array index and ! ToUint32(P) ≥ newLen, in descending numeric index order, do
    1. Let deleteSucceeded be ! A.[[Delete]](P).
    2. If deleteSucceeded is false, then
      1. Set newLenDesc.[[Value]] to ! ToUint32(P) + 1𝔽.
      2. If newWritable is false, set newLenDesc.[[Writable]] to false.
      3. Perform ! OrdinaryDefineOwnProperty(A, "length", newLenDesc).
      4. Return false.
  18. If newWritable is false, then
    1. Set succeeded to ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Writable]]: false }).
    2. Assert: succeeded is true.
  19. Return true.
Note

In steps 3 and 4, if Desc.[[Value]] is an object then its valueOf method is called twice. This is legacy behaviour that was specified with this effect starting with the 2nd Edition of this specification.

10.4.3 String Exotic Objects

A String object is an exotic object that encapsulates a String value and exposes virtual integer-indexed data properties corresponding to the individual code unit elements of the String value. String exotic objects always have a data property named "length" whose value is the length of the encapsulated String value. Both the code unit data properties and the "length" property are non-writable and non-configurable.

An object is a String exotic object (or simply, a String object) if its [[GetOwnProperty]], [[DefineOwnProperty]], and [[OwnPropertyKeys]] internal methods use the following implementations, and its other essential internal methods use the definitions found in 10.1. These methods are installed in StringCreate.

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

10.4.3.1 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of a String exotic object S takes argument P (a property key) and returns a normal completion containing either a Property Descriptor or undefined. It performs the following steps when called:

  1. Let desc be OrdinaryGetOwnProperty(S, P).
  2. If desc is not undefined, return desc.
  3. Return StringGetOwnProperty(S, P).

10.4.3.2 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of a String exotic object S takes arguments P (a property key) and Desc (a Property Descriptor) and returns a normal completion containing a Boolean. It performs the following steps when called:

  1. Let stringDesc be StringGetOwnProperty(S, P).
  2. If stringDesc is not undefined, then
    1. Let extensible be S.[[Extensible]].
    2. Return IsCompatiblePropertyDescriptor(extensible, Desc, stringDesc).
  3. Return ! OrdinaryDefineOwnProperty(S, P, Desc).

10.4.3.3 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of a String exotic object O takes no arguments and returns a normal completion containing a List of property keys. It performs the following steps when called:

  1. Let keys be a new empty List.
  2. Let str be O.[[StringData]].
  3. Assert: str is a String.
  4. Let len be the length of str.
  5. For each integer i such that 0 ≤ i < len, in ascending order, do
    1. Append ! ToString(𝔽(i)) to keys.
  6. For each own property key P of O such that P is an array index and ! ToIntegerOrInfinity(P) ≥ len, in ascending numeric index order, do
    1. Append P to keys.
  7. For each own property key P of O such that P is a String and P is not an array index, in ascending chronological order of property creation, do
    1. Append P to keys.
  8. For each own property key P of O such that P is a Symbol, in ascending chronological order of property creation, do
    1. Append P to keys.
  9. Return keys.

10.4.3.4 StringCreate ( value, prototype )

The abstract operation StringCreate takes arguments value (a String) and prototype (an Object) and returns a String exotic object. It is used to specify the creation of new String exotic objects. It performs the following steps when called:

  1. Let S be MakeBasicObject[[Prototype]], [[Extensible]], [[StringData]] »).
  2. Set S.[[Prototype]] to prototype.
  3. Set S.[[StringData]] to value.
  4. Set S.[[GetOwnProperty]] as specified in 10.4.3.1.
  5. Set S.[[DefineOwnProperty]] as specified in 10.4.3.2.
  6. Set S.[[OwnPropertyKeys]] as specified in 10.4.3.3.
  7. Let length be the length of value.
  8. Perform ! DefinePropertyOrThrow(S, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }).
  9. Return S.

10.4.3.5 StringGetOwnProperty ( S, P )

The abstract operation StringGetOwnProperty takes arguments S (an Object that has a [[StringData]] internal slot) and P (a property key) and returns a Property Descriptor or undefined. It performs the following steps when called:

  1. If P is not a String, return undefined.
  2. Let index be CanonicalNumericIndexString(P).
  3. If index is undefined, return undefined.
  4. If IsIntegralNumber(index) is false, return undefined.
  5. If index is -0𝔽, return undefined.
  6. Let str be S.[[StringData]].
  7. Assert: str is a String.
  8. Let len be the length of str.
  9. If (index) < 0 or len(index), return undefined.
  10. Let resultStr be the substring of str from (index) to (index) + 1.
  11. Return the PropertyDescriptor { [[Value]]: resultStr, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }.

10.4.4 Arguments Exotic Objects

Most ECMAScript functions make an arguments object available to their code. Depending upon the characteristics of the function definition, its arguments object is either an ordinary object or an arguments exotic object. An arguments exotic object is an exotic object whose array index properties map to the formal parameters bindings of an invocation of its associated ECMAScript function.

An object is an arguments exotic object if its internal methods use the following implementations, with the ones not specified here using those found in 10.1. These methods are installed in CreateMappedArgumentsObject.

Note 1

While CreateUnmappedArgumentsObject is grouped into this clause, it creates an ordinary object, not an arguments exotic object.

Arguments exotic objects have the same internal slots as ordinary objects. They also have a [[ParameterMap]] internal slot. Ordinary arguments objects also have a [[ParameterMap]] internal slot whose value is always undefined. For ordinary argument objects the [[ParameterMap]] internal slot is only used by Object.prototype.toString (20.1.3.6) to identify them as such.

Note 2

The integer-indexed data properties of an arguments exotic object whose numeric name values are less than the number of formal parameters of the corresponding function object initially share their values with the corresponding argument bindings in the function's execution context. This means that changing the property changes the corresponding value of the argument binding and vice-versa. This correspondence is broken if such a property is deleted and then redefined or if the property is changed into an accessor property. If the arguments object is an ordinary object, the values of its properties are simply a copy of the arguments passed to the function and there is no dynamic linkage between the property values and the formal parameter values.

Note 3

The ParameterMap object and its property values are used as a device for specifying the arguments object correspondence to argument bindings. The ParameterMap object and the objects that are the values of its properties are not directly observable from ECMAScript code. An ECMAScript implementation does not need to actually create or use such objects to implement the specified semantics.

Note 4

Ordinary arguments objects define a non-configurable accessor property named "callee" which throws a TypeError exception on access. The "callee" property has a more specific meaning for arguments exotic objects, which are created only for some class of non-strict functions. The definition of this property in the ordinary variant exists to ensure that it is not defined in any other manner by conforming ECMAScript implementations.

Note 5

ECMAScript implementations of arguments exotic objects have historically contained an accessor property named "caller". Prior to ECMAScript 2017, this specification included the definition of a throwing "caller" property on ordinary arguments objects. Since implementations do not contain this extension any longer, ECMAScript 2017 dropped the requirement for a throwing "caller" accessor.

10.4.4.1 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of an arguments exotic object args takes argument P (a property key) and returns a normal completion containing either a Property Descriptor or undefined. It performs the following steps when called:

  1. Let desc be OrdinaryGetOwnProperty(args, P).
  2. If desc is undefined, return undefined.
  3. Let map be args.[[ParameterMap]].
  4. Let isMapped be ! HasOwnProperty(map, P).
  5. If isMapped is true, then
    1. Set desc.[[Value]] to ! Get(map, P).
  6. Return desc.

10.4.4.2 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of an arguments exotic object args takes arguments P (a property key) and Desc (a Property Descriptor) and returns a normal completion containing a Boolean. It performs the following steps when called:

  1. Let map be args.[[ParameterMap]].
  2. Let isMapped be ! HasOwnProperty(map, P).
  3. Let newArgDesc be Desc.
  4. If isMapped is true and IsDataDescriptor(Desc) is true, then
    1. If Desc does not have a [[Value]] field, Desc has a [[Writable]] field, and Desc.[[Writable]] is false, then
      1. Set newArgDesc to a copy of Desc.
      2. Set newArgDesc.[[Value]] to ! Get(map, P).
  5. Let allowed be ! OrdinaryDefineOwnProperty(args, P, newArgDesc).
  6. If allowed is false, return false.
  7. If isMapped is true, then
    1. If IsAccessorDescriptor(Desc) is true, then
      1. Perform ! map.[[Delete]](P).
    2. Else,
      1. If Desc has a [[Value]] field, then
        1. Assert: The following Set will succeed, since formal parameters mapped by arguments objects are always writable.
        2. Perform ! Set(map, P, Desc.[[Value]], false).
      2. If Desc has a [[Writable]] field and Desc.[[Writable]] is false, then
        1. Perform ! map.[[Delete]](P).
  8. Return true.

10.4.4.3 [[Get]] ( P, Receiver )

The [[Get]] internal method of an arguments exotic object args takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let map be args.[[ParameterMap]].
  2. Let isMapped be ! HasOwnProperty(map, P).
  3. If isMapped is false, then
    1. Return ? OrdinaryGet(args, P, Receiver).
  4. Else,
    1. Assert: map contains a formal parameter mapping for P.
    2. Return ! Get(map, P).

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

The [[Set]] internal method of an arguments exotic object args takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. If SameValue(args, Receiver) is false, then
    1. Let isMapped be false.
  2. Else,
    1. Let map be args.[[ParameterMap]].
    2. Let isMapped be ! HasOwnProperty(map, P).
  3. If isMapped is true, then
    1. Assert: The following Set will succeed, since formal parameters mapped by arguments objects are always writable.
    2. Perform ! Set(map, P, V, false).
  4. Return ? OrdinarySet(args, P, V, Receiver).

10.4.4.5 [[Delete]] ( P )

The [[Delete]] internal method of an arguments exotic object args takes argument P (a property key) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. Let map be args.[[ParameterMap]].
  2. Let isMapped be ! HasOwnProperty(map, P).
  3. Let result be ? OrdinaryDelete(args, P).
  4. If result is true and isMapped is true, then
    1. Perform ! map.[[Delete]](P).
  5. Return result.

10.4.4.6 CreateUnmappedArgumentsObject ( argumentsList )

The abstract operation CreateUnmappedArgumentsObject takes argument argumentsList (a List of ECMAScript language values) and returns an ordinary object. It performs the following steps when called:

  1. Let len be the number of elements in argumentsList.
  2. Let obj be OrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »).
  3. Set obj.[[ParameterMap]] to undefined.
  4. Perform ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  5. Let index be 0.
  6. Repeat, while index < len,
    1. Let val be argumentsList[index].
    2. Perform ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val).
    3. Set index to index + 1.
  7. Perform ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  8. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false }).
  9. Return obj.

10.4.4.7 CreateMappedArgumentsObject ( func, formals, argumentsList, env )

The abstract operation CreateMappedArgumentsObject takes arguments func (an Object), formals (a Parse Node), argumentsList (a List of ECMAScript language values), and env (an Environment Record) and returns an arguments exotic object. It performs the following steps when called:

  1. Assert: formals does not contain a rest parameter, any binding patterns, or any initializers. It may contain duplicate identifiers.
  2. Let len be the number of elements in argumentsList.
  3. Let obj be MakeBasicObject[[Prototype]], [[Extensible]], [[ParameterMap]] »).
  4. Set obj.[[GetOwnProperty]] as specified in 10.4.4.1.
  5. Set obj.[[DefineOwnProperty]] as specified in 10.4.4.2.
  6. Set obj.[[Get]] as specified in 10.4.4.3.
  7. Set obj.[[Set]] as specified in 10.4.4.4.
  8. Set obj.[[Delete]] as specified in 10.4.4.5.
  9. Set obj.[[Prototype]] to %Object.prototype%.
  10. Let map be OrdinaryObjectCreate(null).
  11. Set obj.[[ParameterMap]] to map.
  12. Let parameterNames be the BoundNames of formals.
  13. Let numberOfParameters be the number of elements in parameterNames.
  14. Let index be 0.
  15. Repeat, while index < len,
    1. Let val be argumentsList[index].
    2. Perform ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val).
    3. Set index to index + 1.
  16. Perform ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  17. Let mappedNames be a new empty List.
  18. Set index to numberOfParameters - 1.
  19. Repeat, while index ≥ 0,
    1. Let name be parameterNames[index].
    2. If mappedNames does not contain name, then
      1. Append name to mappedNames.
      2. If index < len, then
        1. Let g be MakeArgGetter(name, env).
        2. Let p be MakeArgSetter(name, env).
        3. Perform ! map.[[DefineOwnProperty]](! ToString(𝔽(index)), PropertyDescriptor { [[Set]]: p, [[Get]]: g, [[Enumerable]]: false, [[Configurable]]: true }).
    3. Set index to index - 1.
  20. Perform ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  21. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  22. Return obj.

10.4.4.7.1 MakeArgGetter ( name, env )

The abstract operation MakeArgGetter takes arguments name (a String) and env (an Environment Record) and returns a function object. It creates a built-in function object that when executed returns the value bound for name in env. It performs the following steps when called:

  1. Let getterClosure be a new Abstract Closure with no parameters that captures name and env and performs the following steps when called:
    1. Return env.GetBindingValue(name, false).
  2. Let getter be CreateBuiltinFunction(getterClosure, 0, "", « »).
  3. NOTE: getter is never directly accessible to ECMAScript code.
  4. Return getter.

10.4.4.7.2 MakeArgSetter ( name, env )

The abstract operation MakeArgSetter takes arguments name (a String) and env (an Environment Record) and returns a function object. It creates a built-in function object that when executed sets the value bound for name in env. It performs the following steps when called:

  1. Let setterClosure be a new Abstract Closure with parameters (value) that captures name and env and performs the following steps when called:
    1. Return ! env.SetMutableBinding(name, value, false).
  2. Let setter be CreateBuiltinFunction(setterClosure, 1, "", « »).
  3. NOTE: setter is never directly accessible to ECMAScript code.
  4. Return setter.

10.4.5 TypedArray Exotic Objects

A TypedArray is an exotic object that performs special handling of integer index property keys.

TypedArrays have the same internal slots as ordinary objects and additionally [[ViewedArrayBuffer]], [[ArrayLength]], [[ByteOffset]], [[ContentType]], and [[TypedArrayName]] internal slots.

An object is a TypedArray if its [[GetOwnProperty]], [[HasProperty]], [[DefineOwnProperty]], [[Get]], [[Set]], [[Delete]], and [[OwnPropertyKeys]] internal methods use the definitions in this section, and its other essential internal methods use the definitions found in 10.1. These methods are installed by TypedArrayCreate.

10.4.5.1 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of a TypedArray O takes argument P (a property key) and returns a normal completion containing either a Property Descriptor or undefined. It performs the following steps when called:

  1. If P is a String, then
    1. Let numericIndex be CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, then
      1. Let value be TypedArrayGetElement(O, numericIndex).
      2. If value is undefined, return undefined.
      3. Return the PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }.
  2. Return OrdinaryGetOwnProperty(O, P).

10.4.5.2 [[HasProperty]] ( P )

The [[HasProperty]] internal method of a TypedArray O takes argument P (a property key) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. If P is a String, then
    1. Let numericIndex be CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, return IsValidIntegerIndex(O, numericIndex).
  2. Return ? OrdinaryHasProperty(O, P).

10.4.5.3 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of a TypedArray O takes arguments P (a property key) and Desc (a Property Descriptor) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. If P is a String, then
    1. Let numericIndex be CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, then
      1. If IsValidIntegerIndex(O, numericIndex) is false, return false.
      2. If Desc has a [[Configurable]] field and Desc.[[Configurable]] is false, return false.
      3. If Desc has an [[Enumerable]] field and Desc.[[Enumerable]] is false, return false.
      4. If IsAccessorDescriptor(Desc) is true, return false.
      5. If Desc has a [[Writable]] field and Desc.[[Writable]] is false, return false.
      6. If Desc has a [[Value]] field, perform ? TypedArraySetElement(O, numericIndex, Desc.[[Value]]).
      7. Return true.
  2. Return ! OrdinaryDefineOwnProperty(O, P, Desc).

10.4.5.4 [[Get]] ( P, Receiver )

The [[Get]] internal method of a TypedArray O takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. If P is a String, then
    1. Let numericIndex be CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, then
      1. Return TypedArrayGetElement(O, numericIndex).
  2. Return ? OrdinaryGet(O, P, Receiver).

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

The [[Set]] internal method of a TypedArray O takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. If P is a String, then
    1. Let numericIndex be CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, then
      1. If SameValue(O, Receiver) is true, then
        1. Perform ? TypedArraySetElement(O, numericIndex, V).
        2. Return true.
      2. If IsValidIntegerIndex(O, numericIndex) is false, return true.
  2. Return ? OrdinarySet(O, P, V, Receiver).

10.4.5.6 [[Delete]] ( P )

The [[Delete]] internal method of a TypedArray O takes argument P (a property key) and returns a normal completion containing a Boolean. It performs the following steps when called:

  1. If P is a String, then
    1. Let numericIndex be CanonicalNumericIndexString(P).
    2. If numericIndex is not undefined, then
      1. If IsValidIntegerIndex(O, numericIndex) is false, return true; else return false.
  2. Return ! OrdinaryDelete(O, P).

10.4.5.7 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of a TypedArray O takes no arguments and returns a normal completion containing a List of property keys. It performs the following steps when called:

  1. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  2. Let keys be a new empty List.
  3. If IsTypedArrayOutOfBounds(taRecord) is false, then
    1. Let length be TypedArrayLength(taRecord).
    2. For each integer i such that 0 ≤ i < length, in ascending order, do
      1. Append ! ToString(𝔽(i)) to keys.
  4. For each own property key P of O such that P is a String and P is not an integer index, in ascending chronological order of property creation, do
    1. Append P to keys.
  5. For each own property key P of O such that P is a Symbol, in ascending chronological order of property creation, do
    1. Append P to keys.
  6. Return keys.

10.4.5.8 TypedArray With Buffer Witness Records

An TypedArray With Buffer Witness Record is a Record value used to encapsulate a TypedArray along with a cached byte length of the viewed buffer. It is used to help ensure there is a single shared memory read event of the byte length data block when the viewed buffer is a growable SharedArrayBuffer.

TypedArray With Buffer Witness Records have the fields listed in Table 32.

Table 32: TypedArray With Buffer Witness Record Fields
Field Name Value Meaning
[[Object]] a TypedArray The TypedArray whose buffer's byte length is loaded.
[[CachedBufferByteLength]] a non-negative integer or detached The byte length of the object's [[ViewedArrayBuffer]] when the Record was created.

10.4.5.9 MakeTypedArrayWithBufferWitnessRecord ( obj, order )

The abstract operation MakeTypedArrayWithBufferWitnessRecord takes arguments obj (a TypedArray) and order (seq-cst or unordered) and returns a TypedArray With Buffer Witness Record. It performs the following steps when called:

  1. Let buffer be obj.[[ViewedArrayBuffer]].
  2. If IsDetachedBuffer(buffer) is true, then
    1. Let byteLength be detached.
  3. Else,
    1. Let byteLength be ArrayBufferByteLength(buffer, order).
  4. Return the TypedArray With Buffer Witness Record { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength }.

10.4.5.10 TypedArrayCreate ( prototype )

The abstract operation TypedArrayCreate takes argument prototype (an Object) and returns a TypedArray. It is used to specify the creation of new TypedArrays. It performs the following steps when called:

  1. Let internalSlotsList be « [[Prototype]], [[Extensible]], [[ViewedArrayBuffer]], [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], [[ArrayLength]] ».
  2. Let A be MakeBasicObject(internalSlotsList).
  3. Set A.[[GetOwnProperty]] as specified in 10.4.5.1.
  4. Set A.[[HasProperty]] as specified in 10.4.5.2.
  5. Set A.[[DefineOwnProperty]] as specified in 10.4.5.3.
  6. Set A.[[Get]] as specified in 10.4.5.4.
  7. Set A.[[Set]] as specified in 10.4.5.5.
  8. Set A.[[Delete]] as specified in 10.4.5.6.
  9. Set A.[[OwnPropertyKeys]] as specified in 10.4.5.7.
  10. Set A.[[Prototype]] to prototype.
  11. Return A.

10.4.5.11 TypedArrayByteLength ( taRecord )

The abstract operation TypedArrayByteLength takes argument taRecord (a TypedArray With Buffer Witness Record) and returns a non-negative integer. It performs the following steps when called:

  1. If IsTypedArrayOutOfBounds(taRecord) is true, return 0.
  2. Let length be TypedArrayLength(taRecord).
  3. If length = 0, return 0.
  4. Let O be taRecord.[[Object]].
  5. If O.[[ByteLength]] is not auto, return O.[[ByteLength]].
  6. Let elementSize be TypedArrayElementSize(O).
  7. Return length × elementSize.

10.4.5.12 TypedArrayLength ( taRecord )

The abstract operation TypedArrayLength takes argument taRecord (a TypedArray With Buffer Witness Record) and returns a non-negative integer. It performs the following steps when called:

  1. Assert: IsTypedArrayOutOfBounds(taRecord) is false.
  2. Let O be taRecord.[[Object]].
  3. If O.[[ArrayLength]] is not auto, return O.[[ArrayLength]].
  4. Assert: IsFixedLengthArrayBuffer(O.[[ViewedArrayBuffer]]) is false.
  5. Let byteOffset be O.[[ByteOffset]].
  6. Let elementSize be TypedArrayElementSize(O).
  7. Let byteLength be taRecord.[[CachedBufferByteLength]].
  8. Assert: byteLength is not detached.
  9. Return floor((byteLength - byteOffset) / elementSize).

10.4.5.13 IsTypedArrayOutOfBounds ( taRecord )

The abstract operation IsTypedArrayOutOfBounds takes argument taRecord (a TypedArray With Buffer Witness Record) and returns a Boolean. It checks if any of the object's numeric properties reference a value at an index not contained within the underlying buffer's bounds. It performs the following steps when called:

  1. Let O be taRecord.[[Object]].
  2. Let bufferByteLength be taRecord.[[CachedBufferByteLength]].
  3. Assert: IsDetachedBuffer(O.[[ViewedArrayBuffer]]) is true if and only if bufferByteLength is detached.
  4. If bufferByteLength is detached, return true.
  5. Let byteOffsetStart be O.[[ByteOffset]].
  6. If O.[[ArrayLength]] is auto, then
    1. Let byteOffsetEnd be bufferByteLength.
  7. Else,
    1. Let elementSize be TypedArrayElementSize(O).
    2. Let byteOffsetEnd be byteOffsetStart + O.[[ArrayLength]] × elementSize.
  8. If byteOffsetStart > bufferByteLength or byteOffsetEnd > bufferByteLength, return true.
  9. NOTE: 0-length TypedArrays are not considered out-of-bounds.
  10. Return false.

10.4.5.14 IsValidIntegerIndex ( O, index )

The abstract operation IsValidIntegerIndex takes arguments O (a TypedArray) and index (a Number) and returns a Boolean. It performs the following steps when called:

  1. If IsDetachedBuffer(O.[[ViewedArrayBuffer]]) is true, return false.
  2. If IsIntegralNumber(index) is false, return false.
  3. If index is -0𝔽, return false.
  4. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, unordered).
  5. NOTE: Bounds checking is not a synchronizing operation when O's backing buffer is a growable SharedArrayBuffer.
  6. If IsTypedArrayOutOfBounds(taRecord) is true, return false.
  7. Let length be TypedArrayLength(taRecord).
  8. If (index) < 0 or (index) ≥ length, return false.
  9. Return true.

10.4.5.15 TypedArrayGetElement ( O, index )

The abstract operation TypedArrayGetElement takes arguments O (a TypedArray) and index (a Number) and returns a Number, a BigInt, or undefined. It performs the following steps when called:

  1. If IsValidIntegerIndex(O, index) is false, return undefined.
  2. Let offset be O.[[ByteOffset]].
  3. Let elementSize be TypedArrayElementSize(O).
  4. Let byteIndexInBuffer be ((index) × elementSize) + offset.
  5. Let elementType be TypedArrayElementType(O).
  6. Return GetValueFromBuffer(O.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, true, unordered).

10.4.5.16 TypedArraySetElement ( O, index, value )

The abstract operation TypedArraySetElement takes arguments O (a TypedArray), index (a Number), 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 O.[[ContentType]] is bigint, let numValue be ? ToBigInt(value).
  2. Otherwise, let numValue be ? ToNumber(value).
  3. If IsValidIntegerIndex(O, index) is true, then
    1. Let offset be O.[[ByteOffset]].
    2. Let elementSize be TypedArrayElementSize(O).
    3. Let byteIndexInBuffer be ((index) × elementSize) + offset.
    4. Let elementType be TypedArrayElementType(O).
    5. Perform SetValueInBuffer(O.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, numValue, true, unordered).
  4. Return unused.
Note

This operation always appears to succeed, but it has no effect when attempting to write past the end of a TypedArray or to a TypedArray which is backed by a detached ArrayBuffer.

10.4.5.17 IsArrayBufferViewOutOfBounds ( O )

The abstract operation IsArrayBufferViewOutOfBounds takes argument O (a TypedArray or a DataView) and returns a Boolean. It checks if either any of a TypedArray's numeric properties or a DataView object's methods can reference a value at an index not contained within the underlying data block's bounds. This abstract operation exists as a convenience for upstream specifications. It performs the following steps when called:

  1. If O has a [[DataView]] internal slot, then
    1. Let viewRecord be MakeDataViewWithBufferWitnessRecord(O, seq-cst).
    2. Return IsViewOutOfBounds(viewRecord).
  2. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  3. Return IsTypedArrayOutOfBounds(taRecord).

10.4.6 Module Namespace Exotic Objects

A module namespace exotic object is an exotic object that exposes the bindings exported from an ECMAScript Module (See 16.2.3). There is a one-to-one correspondence between the String-keyed own properties of a module namespace exotic object and the binding names exported by the Module. The exported bindings include any bindings that are indirectly exported using export * export items. Each String-valued own property key is the StringValue of the corresponding exported binding name. These are the only String-keyed properties of a module namespace exotic object. Each such property has the attributes { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }. Module namespace exotic objects are not extensible.

An object is a module namespace exotic object if its [[GetPrototypeOf]], [[SetPrototypeOf]], [[IsExtensible]], [[PreventExtensions]], [[GetOwnProperty]], [[DefineOwnProperty]], [[HasProperty]], [[Get]], [[Set]], [[Delete]], and [[OwnPropertyKeys]] internal methods use the definitions in this section, and its other essential internal methods use the definitions found in 10.1. These methods are installed by ModuleNamespaceCreate.

Module namespace exotic objects have the internal slots defined in Table 33.

Table 33: Internal Slots of Module Namespace Exotic Objects
Internal Slot Type Description
[[Module]] a Module Record The Module Record whose exports this namespace exposes.
[[Exports]] a List of Strings A List whose elements are the String values of the exported names exposed as own properties of this object. The list is ordered as if an Array of those String values had been sorted using %Array.prototype.sort% using undefined as comparefn.

10.4.6.1 [[GetPrototypeOf]] ( )

The [[GetPrototypeOf]] internal method of a module namespace exotic object takes no arguments and returns a normal completion containing null. It performs the following steps when called:

  1. Return null.

10.4.6.2 [[SetPrototypeOf]] ( V )

The [[SetPrototypeOf]] internal method of a module namespace exotic object O takes argument V (an Object or null) and returns a normal completion containing a Boolean. It performs the following steps when called:

  1. Return ! SetImmutablePrototype(O, V).

10.4.6.3 [[IsExtensible]] ( )

The [[IsExtensible]] internal method of a module namespace exotic object takes no arguments and returns a normal completion containing false. It performs the following steps when called:

  1. Return false.

10.4.6.4 [[PreventExtensions]] ( )

The [[PreventExtensions]] internal method of a module namespace exotic object takes no arguments and returns a normal completion containing true. It performs the following steps when called:

  1. Return true.

10.4.6.5 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of a module namespace exotic object O takes argument P (a property key) and returns either a normal completion containing either a Property Descriptor or undefined, or a throw completion. It performs the following steps when called:

  1. If P is a Symbol, return OrdinaryGetOwnProperty(O, P).
  2. Let exports be O.[[Exports]].
  3. If exports does not contain P, return undefined.
  4. Let value be ? O.[[Get]](P, O).
  5. Return PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }.

10.4.6.6 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of a module namespace exotic object O takes arguments P (a property key) and Desc (a Property Descriptor) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. If P is a Symbol, return ! OrdinaryDefineOwnProperty(O, P, Desc).
  2. Let current be ? O.[[GetOwnProperty]](P).
  3. If current is undefined, return false.
  4. If Desc has a [[Configurable]] field and Desc.[[Configurable]] is true, return false.
  5. If Desc has an [[Enumerable]] field and Desc.[[Enumerable]] is false, return false.
  6. If IsAccessorDescriptor(Desc) is true, return false.
  7. If Desc has a [[Writable]] field and Desc.[[Writable]] is false, return false.
  8. If Desc has a [[Value]] field, return SameValue(Desc.[[Value]], current.[[Value]]).
  9. Return true.

10.4.6.7 [[HasProperty]] ( P )

The [[HasProperty]] internal method of a module namespace exotic object O takes argument P (a property key) and returns a normal completion containing a Boolean. It performs the following steps when called:

  1. If P is a Symbol, return ! OrdinaryHasProperty(O, P).
  2. Let exports be O.[[Exports]].
  3. If exports contains P, return true.
  4. Return false.

10.4.6.8 [[Get]] ( P, Receiver )

The [[Get]] internal method of a module namespace exotic object O takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. If P is a Symbol, then
    1. Return ! OrdinaryGet(O, P, Receiver).
  2. Let exports be O.[[Exports]].
  3. If exports does not contain P, return undefined.
  4. Let m be O.[[Module]].
  5. Let binding be m.ResolveExport(P).
  6. Assert: binding is a ResolvedBinding Record.
  7. Let targetModule be binding.[[Module]].
  8. Assert: targetModule is not undefined.
  9. If binding.[[BindingName]] is namespace, then
    1. Return GetModuleNamespace(targetModule).
  10. Let targetEnv be targetModule.[[Environment]].
  11. If targetEnv is empty, throw a ReferenceError exception.
  12. Return ? targetEnv.GetBindingValue(binding.[[BindingName]], true).
Note

ResolveExport is side-effect free. Each time this operation is called with a specific exportName, resolveSet pair as arguments it must return the same result. An implementation might choose to pre-compute or cache the ResolveExport results for the [[Exports]] of each module namespace exotic object.

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

The [[Set]] internal method of a module namespace exotic object takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns a normal completion containing false. It performs the following steps when called:

  1. Return false.

10.4.6.10 [[Delete]] ( P )

The [[Delete]] internal method of a module namespace exotic object O takes argument P (a property key) and returns a normal completion containing a Boolean. It performs the following steps when called:

  1. If P is a Symbol, then
    1. Return ! OrdinaryDelete(O, P).
  2. Let exports be O.[[Exports]].
  3. If exports contains P, return false.
  4. Return true.

10.4.6.11 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of a module namespace exotic object O takes no arguments and returns a normal completion containing a List of property keys. It performs the following steps when called:

  1. Let exports be O.[[Exports]].
  2. Let symbolKeys be OrdinaryOwnPropertyKeys(O).
  3. Return the list-concatenation of exports and symbolKeys.

10.4.6.12 ModuleNamespaceCreate ( module, exports )

The abstract operation ModuleNamespaceCreate takes arguments module (a Module Record) and exports (a List of Strings) and returns a module namespace exotic object. It is used to specify the creation of new module namespace exotic objects. It performs the following steps when called:

  1. Assert: module.[[Namespace]] is empty.
  2. Let internalSlotsList be the internal slots listed in Table 33.
  3. Let M be MakeBasicObject(internalSlotsList).
  4. Set M's essential internal methods to the definitions specified in 10.4.6.
  5. Set M.[[Module]] to module.
  6. Let sortedExports be a List whose elements are the elements of exports ordered as if an Array of the same values had been sorted using %Array.prototype.sort% using undefined as comparefn.
  7. Set M.[[Exports]] to sortedExports.
  8. Create own properties of M corresponding to the definitions in 28.3.
  9. Set module.[[Namespace]] to M.
  10. Return M.

10.4.7 Immutable Prototype Exotic Objects

An immutable prototype exotic object is an exotic object that has a [[Prototype]] internal slot that will not change once it is initialized.

An object is an immutable prototype exotic object if its [[SetPrototypeOf]] internal method uses the following implementation. (Its other essential internal methods may use any implementation, depending on the specific immutable prototype exotic object in question.)

Note

Unlike other exotic objects, there is not a dedicated creation abstract operation provided for immutable prototype exotic objects. This is because they are only used by %Object.prototype% and by host environments, and in host environments, the relevant objects are potentially exotic in other ways and thus need their own dedicated creation operation.

10.4.7.1 [[SetPrototypeOf]] ( V )

The [[SetPrototypeOf]] internal method of an immutable prototype exotic object O takes argument V (an Object or null) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. Return ? SetImmutablePrototype(O, V).

10.4.7.2 SetImmutablePrototype ( O, V )

The abstract operation SetImmutablePrototype takes arguments O (an Object) and V (an Object or null) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. Let current be ? O.[[GetPrototypeOf]]().
  2. If SameValue(V, current) is true, return true.
  3. Return false.