10 普通对象与异质对象行为

10.1 普通对象内部方法与内部槽

所有普通对象都有一个称为 [[Prototype]] 的内部槽。此内部槽的值要么是 null,要么是一个对象,并用于实现继承。假设名为 propertyKey 的属性在普通对象 obj 中缺失,但存在于其 [[Prototype]] 对象上。如果 propertyKey 引用的是 [[Prototype]] 对象上的数据属性,则 obj 会为 get 访问继承它,使其表现得仿佛 propertyKeyobj 的属性。如果 propertyKey 引用的是 [[Prototype]] 对象上的可写数据属性,则对 objpropertyKey 的 set 访问会在 obj 上创建一个名为 propertyKey 的新数据属性。如果 propertyKey 引用的是 [[Prototype]] 对象上的不可写数据属性,则对 objpropertyKey 的 set 访问会失败。如果 propertyKey 引用的是 [[Prototype]] 对象上的访问器属性,则该访问器会被 obj 继承,用于 get 访问和 set 访问。

每个普通对象都有一个 Boolean 值的 [[Extensible]] 内部槽,用于满足 6.1.7.3 中指定的与可扩展性相关的内部方法不变量。也就是说,一旦对象的 [[Extensible]] 内部槽的值被设置为 false,就不再可能向该对象添加属性、修改该对象的 [[Prototype]] 内部槽的值,或随后将 [[Extensible]] 的值改回 true

在以下算法描述中,假设 obj普通对象propertyKey属性键值,value 是任意 ECMAScript 语言值,且 propertyDesc 是一个 Property Descriptor Record

每个普通对象内部方法都会委托给一个名称类似的抽象操作。如果这样的抽象操作依赖另一个内部方法,则会在 obj 上调用该内部方法,而不是直接调用名称类似的抽象操作。这些语义确保当普通对象内部方法应用于异质对象时,会调用这些异质对象被覆写的内部方法。

10.1.1 [[GetPrototypeOf]] ( )

The [[GetPrototypeOf]] internal method of 一个普通对象 obj takes no arguments and returns a normal completion containing either an Object or null. It performs the following steps when called:

  1. 返回 OrdinaryGetPrototypeOf(obj)。

10.1.1.1 OrdinaryGetPrototypeOf ( obj )

The abstract operation OrdinaryGetPrototypeOf takes argument obj (an Object) and returns an Object or null. It performs the following steps when called:

  1. 返回 obj.[[Prototype]]

10.1.2 [[SetPrototypeOf]] ( proto )

The [[SetPrototypeOf]] internal method of 一个普通对象 obj takes argument proto (an Object or null) and returns a normal completion containing a Boolean. It performs the following steps when called:

  1. 返回 OrdinarySetPrototypeOf(obj, proto)。

10.1.2.1 OrdinarySetPrototypeOf ( obj, proto )

The abstract operation OrdinarySetPrototypeOf takes arguments obj (an Object) and proto (an Object or null) and returns a Boolean. It performs the following steps when called:

  1. currentobj.[[Prototype]]
  2. 如果 SameValue(proto, current) 是 true,则返回 true
  3. extensibleobj.[[Extensible]]
  4. 如果 extensiblefalse,则返回 false
  5. cursorproto
  6. donefalse
  7. 重复,当 donefalse 时,
    1. 如果 cursornull,则
      1. done 设置为 true
    2. 否则如果 SameValue(cursor, obj) 是 true,则
      1. 返回 false
    3. 否则,
      1. 如果 cursor.[[GetPrototypeOf]] 不是 10.1.1 中定义的普通对象内部方法,则将 done 设置为 true
      2. 否则,将 cursor 设置为 cursor.[[Prototype]]
  8. obj.[[Prototype]] 设置为 proto
  9. 返回 true
Note

步骤 7 中的循环保证,在任何只包含使用 [[GetPrototypeOf]][[SetPrototypeOf]] 普通对象定义的对象的原型链中,不会存在循环。

10.1.3 [[IsExtensible]] ( )

The [[IsExtensible]] internal method of 一个普通对象 obj takes no arguments and returns a normal completion containing a Boolean. It performs the following steps when called:

  1. 返回 OrdinaryIsExtensible(obj)。

10.1.3.1 OrdinaryIsExtensible ( obj )

The abstract operation OrdinaryIsExtensible takes argument obj (an Object) and returns a Boolean. It performs the following steps when called:

  1. 返回 obj.[[Extensible]]

10.1.4 [[PreventExtensions]] ( )

The [[PreventExtensions]] internal method of 一个普通对象 obj takes no arguments and returns a normal completion containing true. It performs the following steps when called:

  1. 返回 OrdinaryPreventExtensions(obj)。

10.1.4.1 OrdinaryPreventExtensions ( obj )

The abstract operation OrdinaryPreventExtensions takes argument obj (an Object) and returns true. It performs the following steps when called:

  1. obj.[[Extensible]] 设置为 false
  2. 返回 true

10.1.5 [[GetOwnProperty]] ( propertyKey )

The [[GetOwnProperty]] internal method of 一个普通对象 obj takes argument propertyKey (a property key) and returns a normal completion containing either a Property Descriptor or undefined. It performs the following steps when called:

  1. 返回 OrdinaryGetOwnProperty(obj, propertyKey)。

10.1.5.1 OrdinaryGetOwnProperty ( obj, propertyKey )

The abstract operation OrdinaryGetOwnProperty takes arguments obj (an Object) and propertyKey (a property key) and returns a Property Descriptor or undefined. It performs the following steps when called:

  1. 如果 obj 没有键为 propertyKey 的自有属性,则返回 undefined
  2. propertyDesc 为一个新创建且不含字段的 Property Descriptor
  3. ownPropertyobj 中键为 propertyKey 的自有属性。
  4. 如果 ownProperty数据属性,则
    1. propertyDesc.[[Value]] 设置为 ownProperty[[Value]] 特性的值。
    2. propertyDesc.[[Writable]] 设置为 ownProperty[[Writable]] 特性的值。
  5. 否则,
    1. 断言:ownProperty访问器属性
    2. propertyDesc.[[Get]] 设置为 ownProperty[[Get]] 特性的值。
    3. propertyDesc.[[Set]] 设置为 ownProperty[[Set]] 特性的值。
  6. propertyDesc.[[Enumerable]] 设置为 ownProperty[[Enumerable]] 特性的值。
  7. propertyDesc.[[Configurable]] 设置为 ownProperty[[Configurable]] 特性的值。
  8. 返回 propertyDesc

10.1.6 [[DefineOwnProperty]] ( propertyKey, propertyDesc )

The [[DefineOwnProperty]] internal method of 一个普通对象 obj takes arguments propertyKey (a property key) and propertyDesc (a Property Descriptor) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. 返回 ? OrdinaryDefineOwnProperty(obj, propertyKey, propertyDesc)。

10.1.6.1 OrdinaryDefineOwnProperty ( obj, propertyKey, propertyDesc )

The abstract operation OrdinaryDefineOwnProperty takes arguments obj (an Object), propertyKey (a property key), and propertyDesc (a Property Descriptor) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. current 为 ? obj.[[GetOwnProperty]](propertyKey)
  2. extensible 为 ? IsExtensible(obj)。
  3. 返回 ValidateAndApplyPropertyDescriptor(obj, propertyKey, extensible, propertyDesc, current)。

10.1.6.2 IsCompatiblePropertyDescriptor ( extensible, propertyDesc, current )

The abstract operation IsCompatiblePropertyDescriptor takes arguments extensible (a Boolean), propertyDesc (a Property Descriptor), and current (a Property Descriptor or undefined) and returns a Boolean. It performs the following steps when called:

  1. 返回 ValidateAndApplyPropertyDescriptor(undefined, "", extensible, propertyDesc, current)。

10.1.6.3 ValidateAndApplyPropertyDescriptor ( obj, propertyKey, extensible, propertyDesc, current )

The abstract operation ValidateAndApplyPropertyDescriptor takes arguments obj (an Object or undefined), propertyKey (a property key), extensible (a Boolean), propertyDesc (a Property Descriptor), and current (a Property Descriptor or undefined) and returns a Boolean. 当且仅当 propertyDesc 可在维护不变量的同时,作为具有指定 extensibility 和当前属性 current 的对象的属性被应用时,它返回 true。当这种应用是可能的且 obj 不是 undefined 时,会对名为 propertyKey 的属性执行该应用(必要时创建该属性)。 It performs the following steps when called:

  1. 断言:propertyKey属性键
  2. 如果 currentundefined,则
    1. 如果 extensiblefalse,则返回 false
    2. 如果 objundefined,则返回 true
    3. 如果 IsAccessorDescriptor(propertyDesc) 是 true,则
      1. 创建对象 obj 的一个名为 propertyKey 的自有访问器属性,其 [[Get]][[Set]][[Enumerable]][[Configurable]] 特性被设置为 propertyDesc 中对应字段的值(如果 propertyDesc 具有该字段),否则设置为该特性的默认值
    4. 否则,
      1. 创建对象 obj 的一个名为 propertyKey 的自有数据属性,其 [[Value]][[Writable]][[Enumerable]][[Configurable]] 特性被设置为 propertyDesc 中对应字段的值(如果 propertyDesc 具有该字段),否则设置为该特性的默认值
    5. 返回 true
  3. 断言:current 是一个完全填充的 Property Descriptor
  4. 如果 propertyDesc 没有任何字段,则返回 true
  5. 如果 current.[[Configurable]]false,则
    1. 如果 propertyDesc 具有 [[Configurable]] 字段且 propertyDesc.[[Configurable]]true,则返回 false
    2. 如果 propertyDesc 具有 [[Enumerable]] 字段且 propertyDesc.[[Enumerable]] 不是 current.[[Enumerable]],则返回 false
    3. 如果 IsGenericDescriptor(propertyDesc) 是 falseIsAccessorDescriptor(propertyDesc) 不是 IsAccessorDescriptor(current),则返回 false
    4. 如果 IsAccessorDescriptor(current) 是 true,则
      1. 如果 propertyDesc 具有 [[Get]] 字段且 SameValue(propertyDesc.[[Get]], current.[[Get]]) 是 false,则返回 false
      2. 如果 propertyDesc 具有 [[Set]] 字段且 SameValue(propertyDesc.[[Set]], current.[[Set]]) 是 false,则返回 false
    5. 否则如果 current.[[Writable]]false,则
      1. 如果 propertyDesc 具有 [[Writable]] 字段且 propertyDesc.[[Writable]]true,则返回 false
      2. 注:SameValueNaN 值返回 true,而这些值可能通过其他方式区分。在这里返回可确保 obj 的任何现有属性保持未修改。
      3. 如果 propertyDesc 具有 [[Value]] 字段,则返回 SameValue(propertyDesc.[[Value]], current.[[Value]])。
  6. 如果 obj 不是 undefined,则
    1. 如果 IsDataDescriptor(current) 是 trueIsAccessorDescriptor(propertyDesc) 是 true,则
      1. 如果 propertyDesc 具有 [[Configurable]] 字段,则令 configurablepropertyDesc.[[Configurable]];否则令 configurablecurrent.[[Configurable]]
      2. 如果 propertyDesc 具有 [[Enumerable]] 字段,则令 enumerablepropertyDesc.[[Enumerable]];否则令 enumerablecurrent.[[Enumerable]]
      3. 将对象 obj 的名为 propertyKey 的属性替换为一个访问器属性,其 [[Configurable]][[Enumerable]] 特性分别被设置为 configurableenumerable,且其 [[Get]][[Set]] 特性被设置为 propertyDesc 中对应字段的值(如果 propertyDesc 具有该字段),否则设置为该特性的默认值
    2. 否则如果 IsAccessorDescriptor(current) 是 trueIsDataDescriptor(propertyDesc) 是 true,则
      1. 如果 propertyDesc 具有 [[Configurable]] 字段,则令 configurablepropertyDesc.[[Configurable]];否则令 configurablecurrent.[[Configurable]]
      2. 如果 propertyDesc 具有 [[Enumerable]] 字段,则令 enumerablepropertyDesc.[[Enumerable]];否则令 enumerablecurrent.[[Enumerable]]
      3. 将对象 obj 的名为 propertyKey 的属性替换为一个数据属性,其 [[Configurable]][[Enumerable]] 特性分别被设置为 configurableenumerable,且其 [[Value]][[Writable]] 特性被设置为 propertyDesc 中对应字段的值(如果 propertyDesc 具有该字段),否则设置为该特性的默认值
    3. 否则,
      1. propertyDesc 的每个字段名 fieldName,将对象 obj 的名为 propertyKey 的属性中名为 fieldName 的特性设置为 propertyDescfieldName 字段的值。
  7. 返回 true

10.1.7 [[HasProperty]] ( propertyKey )

The [[HasProperty]] internal method of 一个普通对象 obj takes argument propertyKey (a property key) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. 返回 ? OrdinaryHasProperty(obj, propertyKey)。

10.1.7.1 OrdinaryHasProperty ( obj, propertyKey )

The abstract operation OrdinaryHasProperty takes arguments obj (an Object) and propertyKey (a property key) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. hasOwn 为 ? obj.[[GetOwnProperty]](propertyKey)
  2. 如果 hasOwn 不是 undefined,则返回 true
  3. parent 为 ? obj.[[GetPrototypeOf]]()
  4. 如果 parent 不是 null,则
    1. 返回 ? parent.[[HasProperty]](propertyKey)
  5. 返回 false

10.1.8 [[Get]] ( propertyKey, receiver )

The [[Get]] internal method of 一个普通对象 obj takes arguments propertyKey (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. 返回 ? OrdinaryGet(obj, propertyKey, receiver)。

10.1.8.1 OrdinaryGet ( obj, propertyKey, receiver )

The abstract operation OrdinaryGet takes arguments obj (an Object), propertyKey (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. propertyDesc 为 ? obj.[[GetOwnProperty]](propertyKey)
  2. 如果 propertyDescundefined,则
    1. parent 为 ? obj.[[GetPrototypeOf]]()
    2. 如果 parentnull,则返回 undefined
    3. 返回 ? parent.[[Get]](propertyKey, receiver)
  3. 如果 IsDataDescriptor(propertyDesc) 是 true,则返回 propertyDesc.[[Value]]
  4. 断言:IsAccessorDescriptor(propertyDesc) 是 true
  5. getterpropertyDesc.[[Get]]
  6. 如果 getterundefined,则返回 undefined
  7. 返回 ? Call(getter, receiver)。

10.1.9 [[Set]] ( propertyKey, value, receiver )

The [[Set]] internal method of 一个普通对象 obj takes arguments propertyKey (a property key), value (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. 返回 ? OrdinarySet(obj, propertyKey, value, receiver)。

10.1.9.1 OrdinarySet ( obj, propertyKey, value, receiver )

The abstract operation OrdinarySet takes arguments obj (an Object), propertyKey (a property key), value (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. ownDesc 为 ? obj.[[GetOwnProperty]](propertyKey)
  2. 返回 ? OrdinarySetWithOwnDescriptor(obj, propertyKey, value, receiver, ownDesc)。

10.1.9.2 OrdinarySetWithOwnDescriptor ( obj, propertyKey, value, receiver, ownDesc )

The abstract operation OrdinarySetWithOwnDescriptor takes arguments obj (an Object), propertyKey (a property key), value (an ECMAScript language value), receiver (an ECMAScript language value), and ownDesc (a Property Descriptor or undefined) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. 如果 ownDescundefined,则
    1. parent 为 ? obj.[[GetPrototypeOf]]()
    2. 如果 parent 不是 null,则返回 ? parent.[[Set]](propertyKey, value, receiver)
    3. ownDesc 设置为 PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }。
  2. 如果 IsDataDescriptor(ownDesc) 是 true,则
    1. 如果 ownDesc.[[Writable]]false,则返回 false
    2. 如果 receiver 不是 Object,则返回 false
    3. existingDesc 为 ? receiver.[[GetOwnProperty]](propertyKey)
    4. 如果 existingDescundefined,则
      1. 断言:receiver 当前没有属性 propertyKey
      2. 返回 ? CreateDataProperty(receiver, propertyKey, value)。
    5. 如果 IsAccessorDescriptor(existingDesc) 是 true,则返回 false
    6. 如果 existingDesc.[[Writable]]false,则返回 false
    7. valueDesc 为 PropertyDescriptor { [[Value]]: value }。
    8. 返回 ? receiver.[[DefineOwnProperty]](propertyKey, valueDesc)
  3. 断言:IsAccessorDescriptor(ownDesc) 是 true
  4. setterownDesc.[[Set]]
  5. 如果 setterundefined,则返回 false
  6. 执行 ? Call(setter, receiver, « value »)。
  7. 返回 true

10.1.10 [[Delete]] ( propertyKey )

The [[Delete]] internal method of 一个普通对象 obj takes argument propertyKey (a property key) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. 返回 ? OrdinaryDelete(obj, propertyKey)。

10.1.10.1 OrdinaryDelete ( obj, propertyKey )

The abstract operation OrdinaryDelete takes arguments obj (an Object) and propertyKey (a property key) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. propertyDesc 为 ? obj.[[GetOwnProperty]](propertyKey)
  2. 如果 propertyDescundefined,则返回 true
  3. 如果 propertyDesc.[[Configurable]]true,则
    1. obj 中移除名称为 propertyKey 的自有属性。
    2. 返回 true
  4. 返回 false

10.1.11 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of 一个普通对象 obj takes no arguments and returns a normal completion containing a List of property keys. It performs the following steps when called:

  1. 返回 OrdinaryOwnPropertyKeys(obj)。

10.1.11.1 OrdinaryOwnPropertyKeys ( obj )

The abstract operation OrdinaryOwnPropertyKeys takes argument obj (an Object) and returns a List of property keys. It performs the following steps when called:

  1. keys 为一个新的空 List
  2. obj 的每个自有属性键 propertyKey,如果 propertyKey数组索引,则按升序数值索引顺序,执行:
    1. propertyKey 追加到 keys
  3. obj 的每个自有属性键 propertyKey,如果 propertyKey 是 String 且 propertyKey 不是数组索引,则按属性创建的升序时间顺序,执行:
    1. propertyKey 追加到 keys
  4. obj 的每个自有属性键 propertyKey,如果 propertyKey 是 Symbol,则按属性创建的升序时间顺序,执行:
    1. propertyKey 追加到 keys
  5. 返回 keys

10.1.12 OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] )

The abstract operation OrdinaryObjectCreate takes argument proto (an Object or null) and optional argument additionalInternalSlotsList (a List of names of internal slots) and returns an Object. 它用于指定新普通对象的运行时创建。additionalInternalSlotsList 包含[[Prototype]][[Extensible]] 之外,必须作为对象一部分定义的附加内部槽名称。如果未提供 additionalInternalSlotsList,则使用一个新的空 List。 It performs the following steps when called:

  1. internalSlotsList 为 « [[Prototype]], [[Extensible]] »。
  2. 如果 additionalInternalSlotsList 存在,则将 internalSlotsList 设置为 internalSlotsListadditionalInternalSlotsList列表连接
  3. objMakeBasicObject(internalSlotsList)。
  4. obj.[[Prototype]] 设置为 proto
  5. 返回 obj
Note

尽管 OrdinaryObjectCreate 几乎只是调用 MakeBasicObject,但它的使用传达了创建普通对象而非异质对象的意图。因此,在本规范中,任何随后会以使结果变为非普通对象的方式修改对象内部方法的算法,都不会调用它。创建异质对象的操作会直接调用 MakeBasicObject

10.1.13 OrdinaryCreateFromConstructor ( ctor, intrinsicDefaultProto [ , internalSlotsList ] )

The abstract operation OrdinaryCreateFromConstructor takes arguments ctor (a function object) and intrinsicDefaultProto (a String) and optional argument internalSlotsList (a List of names of internal slots) and returns either a normal completion containing an Object or a throw completion. 它创建一个普通对象,其 [[Prototype]] 值从构造函数"prototype" 属性取得(如果存在)。否则,使用由 intrinsicDefaultProto 命名的固有对象作为 [[Prototype]]internalSlotsList 包含必须作为对象一部分定义的附加内部槽名称。如果未提供 internalSlotsList,则使用一个新的空 List。 It performs the following steps when called:

  1. 断言:intrinsicDefaultProto 是本规范中某个固有对象的名称。对应对象必须是预期用作对象 [[Prototype]] 值的固有对象。
  2. proto 为 ? GetPrototypeFromConstructor(ctor, intrinsicDefaultProto)。
  3. 如果 internalSlotsList 存在,则令 slotsinternalSlotsList
  4. 否则,令 slots 为一个新的空 List
  5. 返回 OrdinaryObjectCreate(proto, slots)。

10.1.14 GetPrototypeFromConstructor ( ctor, intrinsicDefaultProto )

The abstract operation GetPrototypeFromConstructor takes arguments ctor (a function object) and intrinsicDefaultProto (a String) and returns either a normal completion containing an Object or a throw completion. 它确定应当用于创建与特定构造函数对应的对象的 [[Prototype]] 值。该值从构造函数"prototype" 属性取得(如果存在)。否则,使用由 intrinsicDefaultProto 命名的固有对象作为 [[Prototype]]。 It performs the following steps when called:

  1. 断言:intrinsicDefaultProto 是本规范中某个固有对象的名称。对应对象必须是预期用作对象 [[Prototype]] 值的固有对象。
  2. proto 为 ? Get(ctor, "prototype")。
  3. 如果 proto 不是 Object,则
    1. realm 为 ? GetFunctionRealm(ctor)。
    2. proto 设置为 realm 中名为 intrinsicDefaultProto 的固有对象。
  4. 返回 proto
Note

如果 ctor 不提供 [[Prototype]] 值,则所使用的默认值从 ctor 函数的 realm 中取得,而不是从运行中执行上下文取得。

10.1.15 RequireInternalSlot ( obj, internalSlot )

The abstract operation RequireInternalSlot takes arguments obj (an ECMAScript language value) and internalSlot (an internal slot name) and returns either a normal completion containing unused or a throw completion. 除非 obj 是 Object 且具有给定内部槽,否则它会抛出异常。 It performs the following steps when called:

  1. 如果 obj 不是 Object,则抛出 TypeError 异常。
  2. 如果 obj 没有 internalSlot 内部槽,则抛出 TypeError 异常。
  3. 返回 unused

10.2 ECMAScript 函数对象

ECMAScript 函数对象封装了闭合于词法环境的带参数 ECMAScript 代码,并支持该代码的动态求值。ECMAScript 函数对象普通对象,并且具有与其他普通对象相同的内部槽和相同的内部方法。ECMAScript 函数对象的代码可以是严格模式代码(11.2.2),也可以是非严格代码。其代码是严格模式代码的 ECMAScript 函数对象称为严格函数。其代码不是严格模式代码的函数对象称为非严格函数

除了 [[Extensible]][[Prototype]] 之外,ECMAScript 函数对象还具有 Table 26 中列出的内部槽。

Table 26: ECMAScript 函数对象的内部槽
内部槽 类型 描述
[[Environment]] an Environment Record 函数闭合于其上的 Environment Record。在求值函数代码时用作外层环境。
[[PrivateEnvironment]] a PrivateEnvironment Record or null 函数闭合于其上的、用于 Private NamesPrivateEnvironment Record。如果此函数在句法上不包含在类内,则为 null。在求值函数代码时,用作内部类的外层 PrivateEnvironment。
[[FormalParameters]] a Parse Node 定义该函数形式参数列表的源文本的根解析节点。
[[ECMAScriptCode]] a Parse Node 定义该函数体的源文本的根解析节点。
[[ConstructorKind]] base or derived 该函数是否为派生类构造函数
[[Realm]] a Realm Record 函数被创建所在的 realm,并提供在求值函数时访问的任何固有对象。
[[ScriptOrModule]] a Script Record or a Module Record 函数被创建所在的脚本或模块。
[[ThisMode]] lexical, strict, or global 定义如何解释该函数的形式参数和代码体内的 this 引用。lexical 表示 this 引用词法包围函数的 this 值。strict 表示精确使用函数调用所提供的 this 值。global 表示 undefinednullthis 值会被解释为对全局对象的引用,而任何其他 this 值都会先传递给 ToObject
[[Strict]] a Boolean 如果这是严格函数,则为 true;如果这是非严格函数,则为 false
[[HomeObject]] an Object or undefined 如果该函数使用 super,则这是一个对象,其 [[GetPrototypeOf]] 提供 super 属性查找开始所在的对象。
[[SourceText]] a sequence of Unicode code points 定义该函数的源文本
[[Fields]] a List of ClassFieldDefinition Records 如果该函数是一个类,则这是表示该类的非静态字段及对应初始化器的 Records 列表。
[[PrivateMethods]] a List of PrivateElements 如果该函数是一个类,则这是表示该类的非静态私有方法和访问器的列表。
[[ClassFieldInitializerName]] a String, a Symbol, a Private Name, or empty 如果该函数作为类字段的初始化器创建,则为该字段的 NamedEvaluation 使用的名称;否则为 empty
[[IsClassConstructor]] a Boolean 指示该函数是否为类构造函数。(如果为 true,调用该函数的 [[Call]] 会立即抛出 TypeError 异常。)

所有 ECMAScript 函数对象都具有此处定义的 [[Call]] 内部方法。除了是函数之外还是构造函数的 ECMAScript 函数还具有 [[Construct]] 内部方法。

10.2.1 [[Call]] ( thisArg, argList )

The [[Call]] internal method of an ECMAScript function object func takes arguments thisArg (an ECMAScript language value) and argList (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. callerContext 为运行中执行上下文。
  2. calleeContextPrepareForOrdinaryCall(func, undefined)。
  3. 断言:calleeContext 现在是运行中执行上下文。
  4. 如果 func.[[IsClassConstructor]]true,则
    1. error 为新创建的 TypeError 对象。
    2. 注:errorcalleeContext 中、使用 func 的关联 Realm Record 创建。
    3. 从执行上下文栈中移除 calleeContext,并将 callerContext 恢复为运行中执行上下文。
    4. 抛出 error
  5. 执行 OrdinaryCallBindThis(func, calleeContext, thisArg)。
  6. resultCompletion(OrdinaryCallEvaluateBody(func, argList))。
  7. 从执行上下文栈中移除 calleeContext,并将 callerContext 恢复为运行中执行上下文。
  8. 如果 result 是 return completion,则返回 result.[[Value]]
  9. 断言:result 是 throw completion。
  10. 返回 ? result
Note

calleeContext 在步骤 7 中从执行上下文栈中移除时,如果它已暂停并被可访问的 Generator 保留以供稍后恢复,则不得销毁它。

10.2.1.1 PrepareForOrdinaryCall ( func, newTarget )

The abstract operation PrepareForOrdinaryCall takes arguments func (an ECMAScript function object) and newTarget (an Object or undefined) and returns an execution context. It performs the following steps when called:

  1. callerContext 为运行中执行上下文。
  2. calleeContext 为新的 ECMAScript 代码执行上下文
  3. calleeContext 的 Function 设置为 func
  4. calleeRealmfunc.[[Realm]]
  5. calleeContextRealm 设置为 calleeRealm
  6. calleeContext 的 ScriptOrModule 设置为 func.[[ScriptOrModule]]
  7. localEnvNewFunctionEnvironment(func, newTarget)。
  8. calleeContext 的 LexicalEnvironment 设置为 localEnv
  9. calleeContext 的 VariableEnvironment 设置为 localEnv
  10. calleeContext 的 PrivateEnvironment 设置为 func.[[PrivateEnvironment]]
  11. 如果 callerContext 尚未暂停,则暂停 callerContext
  12. calleeContext 压入执行上下文栈;calleeContext 现在是运行中执行上下文。
  13. 注:此点之后产生的任何异常对象都与 calleeRealm 相关联。
  14. 返回 calleeContext

10.2.1.2 OrdinaryCallBindThis ( func, calleeContext, thisArg )

The abstract operation OrdinaryCallBindThis takes arguments func (an ECMAScript function object), calleeContext (an execution context), and thisArg (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. thisModefunc.[[ThisMode]]
  2. 如果 thisModelexical,则返回 unused
  3. calleeRealmfunc.[[Realm]]
  4. localEnvcalleeContext 的 LexicalEnvironment。
  5. 如果 thisModestrict,则
    1. thisValuethisArg
  6. 否则,
    1. 如果 thisArgundefinednull,则
      1. globalEnvcalleeRealm.[[GlobalEnv]]
      2. 断言:globalEnvGlobal Environment Record
      3. thisValueglobalEnv.[[GlobalThisValue]]
    2. 否则,
      1. thisValue 为 ! ToObject(thisArg)。
      2. 注:ToObject 使用 calleeRealm 产生包装器对象。
  7. 断言:localEnvFunction Environment Record
  8. 断言:下一步绝不会返回 abrupt completion,因为 localEnv.[[ThisBindingStatus]] 不是 initialized
  9. 执行 ! BindThisValue(localEnv, thisValue)。
  10. 返回 unused

10.2.1.3 Runtime Semantics: EvaluateBody

The syntax-directed operation EvaluateBody takes arguments func (an ECMAScript function object) and argList (a List of ECMAScript language values) and returns a return completion or a throw completion. It is defined piecewise over the following productions:

FunctionBody : FunctionStatementList
  1. 返回 ? FunctionBody 带实参 funcargListEvaluateFunctionBody
ConciseBody : ExpressionBody
  1. 返回 ? ConciseBody 带实参 funcargListEvaluateConciseBody
GeneratorBody : FunctionBody
  1. 返回 ? GeneratorBody 带实参 funcargListEvaluateGeneratorBody
AsyncGeneratorBody : FunctionBody
  1. 返回 ? AsyncGeneratorBody 带实参 funcargListEvaluateAsyncGeneratorBody
AsyncFunctionBody : FunctionBody
  1. 返回 ? AsyncFunctionBody 带实参 funcargListEvaluateAsyncFunctionBody
AsyncConciseBody : ExpressionBody
  1. 返回 ? AsyncConciseBody 带实参 funcargListEvaluateAsyncConciseBody
Initializer : = AssignmentExpression
  1. 断言:argList 为空。
  2. 断言:func.[[ClassFieldInitializerName]] 不是 empty
  3. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 是 true,则
    1. value 为 ? Initializer 带实参 func.[[ClassFieldInitializerName]]NamedEvaluation
  4. 否则,
    1. rhs 为 ? AssignmentExpressionEvaluation
    2. value 为 ? GetValue(rhs)。
  5. 返回 ReturnCompletion(value)。
Note

即使字段初始化器构成函数边界,调用 FunctionDeclarationInstantiation 也没有任何可观察效果,因此被省略。

ClassStaticBlockBody : ClassStaticBlockStatementList
  1. 断言:argList 为空。
  2. 返回 ? ClassStaticBlockBody 带实参 funcEvaluateClassStaticBlockBody

10.2.1.4 OrdinaryCallEvaluateBody ( func, argList )

The abstract operation OrdinaryCallEvaluateBody takes arguments func (an ECMAScript function object) and argList (a List of ECMAScript language values) and returns a return completion or a throw completion. It performs the following steps when called:

  1. 返回 ? func.[[ECMAScriptCode]] 带实参 funcargListEvaluateBody

10.2.2 [[Construct]] ( argList, newTarget )

The [[Construct]] internal method of an ECMAScript function object func takes arguments argList (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. callerContext 为运行中执行上下文。
  2. kindfunc.[[ConstructorKind]]
  3. 如果 kindbase,则
    1. thisArg 为 ? OrdinaryCreateFromConstructor(newTarget, "%Object.prototype%")。
  4. calleeContextPrepareForOrdinaryCall(func, newTarget)。
  5. 断言:calleeContext 现在是运行中执行上下文。
  6. 如果 kindbase,则
    1. 执行 OrdinaryCallBindThis(func, calleeContext, thisArg)。
    2. initializeResultCompletion(InitializeInstanceElements(thisArg, func))。
    3. 如果 initializeResult 是 abrupt completion,则
      1. 从执行上下文栈中移除 calleeContext,并将 callerContext 恢复为运行中执行上下文。
      2. 返回 ? initializeResult
  7. ctorEnvcalleeContext 的 LexicalEnvironment。
  8. resultCompletion(OrdinaryCallEvaluateBody(func, argList))。
  9. 从执行上下文栈中移除 calleeContext,并将 callerContext 恢复为运行中执行上下文。
  10. 如果 result 是 throw completion,则
    1. 返回 ? result
  11. 断言:result 是 return completion。
  12. 如果 result.[[Value]] 是 Object,则返回 result.[[Value]]
  13. 如果 kindbase,则返回 thisArg
  14. 如果 result.[[Value]] 不是 undefined,则抛出 TypeError 异常。
  15. thisBinding 为 ? ctorEnv.GetThisBinding()。
  16. 断言:thisBinding 是 Object。
  17. 返回 thisBinding

10.2.3 OrdinaryFunctionCreate ( proto, sourceText, paramList, body, thisMode, envRecord, privateEnv )

The abstract operation OrdinaryFunctionCreate takes arguments proto (an Object), sourceText (a sequence of Unicode code points), paramList (a Parse Node), body (a Parse Node), thisMode (lexical-this or non-lexical-this), envRecord (an Environment Record), and privateEnv (a PrivateEnvironment Record or null) and returns an ECMAScript function object. 它用于指定具有默认 [[Call]] 内部方法且不具有 [[Construct]] 内部方法的新函数的运行时创建(尽管随后可以由诸如 MakeConstructor 的操作添加一个)。sourceText 是要创建函数的句法定义的源文本。 It performs the following steps when called:

  1. internalSlotsListTable 26 中列出的内部槽。
  2. funcOrdinaryObjectCreate(proto, internalSlotsList)。
  3. func.[[Call]] 设置为 10.2.1 中指定的定义。
  4. func.[[SourceText]] 设置为 sourceText
  5. func.[[FormalParameters]] 设置为 paramList
  6. func.[[ECMAScriptCode]] 设置为 body
  7. strictIsStrict(body)。
  8. func.[[Strict]] 设置为 strict
  9. 如果 thisModelexical-this,则将 func.[[ThisMode]] 设置为 lexical
  10. 否则如果 stricttrue,则将 func.[[ThisMode]] 设置为 strict
  11. 否则,将 func.[[ThisMode]] 设置为 global
  12. func.[[IsClassConstructor]] 设置为 false
  13. func.[[Environment]] 设置为 envRecord
  14. func.[[PrivateEnvironment]] 设置为 privateEnv
  15. func.[[ScriptOrModule]] 设置为 GetActiveScriptOrModule()。
  16. func.[[Realm]] 设置为当前 Realm Record
  17. func.[[HomeObject]] 设置为 undefined
  18. func.[[Fields]] 设置为一个新的空 List
  19. func.[[PrivateMethods]] 设置为一个新的空 List
  20. func.[[ClassFieldInitializerName]] 设置为 empty
  21. lengthparamListExpectedArgumentCount
  22. 执行 SetFunctionLength(func, length)。
  23. 返回 func

10.2.4 AddRestrictedFunctionProperties ( func, realm )

The abstract operation AddRestrictedFunctionProperties takes arguments func (a function object) and realm (a Realm Record) and returns unused. It performs the following steps when called:

  1. 断言:realm.[[Intrinsics]].[[%ThrowTypeError%]] 存在且已被初始化。
  2. throwerrealm.[[Intrinsics]].[[%ThrowTypeError%]]。
  3. 执行 ! DefinePropertyOrThrow(func, "caller", PropertyDescriptor { [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true })。
  4. 执行 ! DefinePropertyOrThrow(func, "arguments", PropertyDescriptor { [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true })。
  5. 返回 unused

10.2.4.1 %ThrowTypeError% ( )

此函数是 %ThrowTypeError% 固有对象。

它是一个匿名内置函数对象,每个 realm 定义一次。

它在被调用时执行以下步骤:

  1. 抛出 TypeError 异常。

此函数的 [[Extensible]] 内部槽的值为 false

此函数的 "length" 属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

此函数的 "name" 属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

10.2.5 MakeConstructor ( func [ , writableProto [ , proto ] ] )

The abstract operation MakeConstructor takes argument func (an ECMAScript function object or a built-in function object) and optional arguments writableProto (a Boolean) and proto (an Object) and returns unused. 它将 func 转换为构造函数。 It performs the following steps when called:

  1. 如果 func 是 ECMAScript 函数对象,则
    1. 断言:IsConstructor(func) 是 false
    2. 断言:func 是一个可扩展对象,且没有 "prototype" 自有属性。
    3. func.[[Construct]] 设置为 10.2.2 中指定的定义。
  2. 否则,
    1. func.[[Construct]] 设置为 10.3.2 中指定的定义。
  3. func.[[ConstructorKind]] 设置为 base
  4. 如果 writableProto 不存在,则将 writableProto 设置为 true
  5. 如果 proto 不存在,则
    1. proto 设置为 OrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! DefinePropertyOrThrow(proto, "constructor", PropertyDescriptor { [[Value]]: func, [[Writable]]: writableProto, [[Enumerable]]: false, [[Configurable]]: true })。
  6. 执行 ! DefinePropertyOrThrow(func, "prototype", PropertyDescriptor { [[Value]]: proto, [[Writable]]: writableProto, [[Enumerable]]: false, [[Configurable]]: false })。
  7. 返回 unused

10.2.6 MakeClassConstructor ( func )

The abstract operation MakeClassConstructor takes argument func (an ECMAScript function object) and returns unused. It performs the following steps when called:

  1. 断言:func.[[IsClassConstructor]]false
  2. func.[[IsClassConstructor]] 设置为 true
  3. 返回 unused

10.2.7 MakeMethod ( func, homeObj )

The abstract operation MakeMethod takes arguments func (an ECMAScript function object) and homeObj (an Object) and returns unused. 它将 func 配置为方法。 It performs the following steps when called:

  1. 断言:homeObj普通对象
  2. func.[[HomeObject]] 设置为 homeObj
  3. 返回 unused

10.2.8 DefineMethodProperty ( homeObj, name, closure, enumerable )

The abstract operation DefineMethodProperty takes arguments homeObj (an Object), name (a property key or Private Name), closure (a function object), and enumerable (a Boolean) and returns either a normal completion containing either a PrivateElement or unused, or an abrupt completion. It performs the following steps when called:

  1. 断言:homeObj 是普通的、可扩展的对象。
  2. 如果 namePrivate Name,则返回 PrivateElement { [[Key]]: name, [[Kind]]: method, [[Value]]: closure }。
  3. propertyDesc 为 PropertyDescriptor { [[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true }。
  4. 执行 ? DefinePropertyOrThrow(homeObj, name, propertyDesc)。
  5. 注:DefinePropertyOrThrow 仅在尝试定义 name"prototype" 的类静态方法时返回 abrupt completion。
  6. 返回 unused

10.2.9 SetFunctionName ( func, name [ , prefix ] )

The abstract operation SetFunctionName takes arguments func (a function object) and name (a property key or Private Name) and optional argument prefix (a String) and returns unused. 它向 func 添加一个 "name" 属性。 It performs the following steps when called:

  1. 断言:func 是可扩展对象,且没有 "name" 自有属性。
  2. 如果 name 是 Symbol,则
    1. descriptionname.[[Description]]
    2. 如果 descriptionundefined,则将 name 设置为空 String。
    3. 否则,将 name 设置为 "["description"]"字符串连接
  3. 否则如果 namePrivate Name,则
    1. name 设置为 name.[[Description]]
  4. 如果 func 具有 [[InitialName]] 内部槽,则
    1. func.[[InitialName]] 设置为 name
  5. 如果 prefix 存在,则
    1. prefixedNameprefix、代码单元 0x0020 (SPACE) 和 name字符串连接
    2. 如果 func 具有 [[InitialName]] 内部槽,则
      1. 注:以下步骤中的选择在每次调用此抽象操作时独立作出。
      2. func.[[InitialName]] 设置为 nameprefixedName 之一的实现定义选择。
    3. name 设置为 prefixedName
  6. 执行 ! DefinePropertyOrThrow(func, "name", PropertyDescriptor { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true })。
  7. 返回 unused

10.2.10 SetFunctionLength ( func, length )

The abstract operation SetFunctionLength takes arguments func (a function object) and length (a non-negative integer or +∞) and returns unused. 它向 func 添加一个 "length" 属性。 It performs the following steps when called:

  1. 断言:func 是可扩展对象,且没有 "length" 自有属性。
  2. 执行 ! DefinePropertyOrThrow(func, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true })。
  3. 返回 unused

10.2.11 FunctionDeclarationInstantiation ( func, argList )

The abstract operation FunctionDeclarationInstantiation takes arguments func (an ECMAScript function object) and argList (a List of ECMAScript language values) and returns either a normal completion containing unused or a throw completion. func 是正在为其建立执行上下文的函数对象

Note

当为求值 ECMAScript 函数建立执行上下文时,会创建新的 Function Environment Record,并在该 Environment Record 中实例化每个形式参数的绑定。函数体中的每个声明也会被实例化。如果函数的形式参数不包含任何默认值初始化器,则函数体声明会在与参数相同的 Environment Record 中实例化。如果存在默认值参数初始化器,则会为函数体声明创建第二个 Environment Record。形式参数和函数会作为 FunctionDeclarationInstantiation 的一部分被初始化。所有其他绑定会在函数体求值期间初始化。

它在被调用时执行以下步骤:

  1. calleeContext 为正在运行的执行上下文。
  2. codefunc.[[ECMAScriptCode]]
  3. strictfunc.[[Strict]]
  4. formalsfunc.[[FormalParameters]]
  5. paramNamesformalsBoundNames
  6. 如果 paramNames 有任何重复条目,令 hasDuplicatestrue;否则令 hasDuplicatesfalse
  7. simpleParamListformalsIsSimpleParameterList
  8. hasParamExprsformalsContainsExpression
  9. variableNamescodeVarDeclaredNames
  10. variableDeclscodeVarScopedDeclarations
  11. lexicalNamescodeLexicallyDeclaredNames
  12. funcNames 为一个新的空 List
  13. funcsToInitialize 为一个新的空 List
  14. variableDecls 的每个元素 variableDecl,按 List 的逆序执行:
    1. 如果 variableDecl 既不是 VariableDeclaration、也不是 ForBinding、也不是 BindingIdentifier,则
      1. 断言:variableDeclFunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclaration
      2. funcNamevariableDeclBoundNames 的唯一元素。
      3. 如果 funcNames包含 funcName,则
        1. funcName 作为 funcNames 的第一个元素插入。
        2. 注:如果同一名称有多个函数声明,则使用最后一个声明。
        3. variableDecl 作为 funcsToInitialize 的第一个元素插入。
  15. argumentsObjNeededtrue
  16. 如果 func.[[ThisMode]]lexical,则
    1. 注:箭头函数永远没有 arguments 对象。
    2. argumentsObjNeeded 设为 false
  17. 否则,如果 paramNames 包含 "arguments",则
    1. argumentsObjNeeded 设为 false
  18. 否则,如果 hasParamExprsfalse,则
    1. 如果 funcNames 包含 "arguments"lexicalNames 包含 "arguments",则
      1. argumentsObjNeeded 设为 false
  19. 如果 stricttruehasParamExprsfalse,则
    1. 注:参数只需要一个 Environment Record,因为严格模式代码中对 eval 的调用不能创建在 eval 外部可见的新绑定。
    2. envRecordcalleeContext 的 LexicalEnvironment。
  20. 否则,
    1. 注:需要一个单独的 Environment Record,以确保在形式参数列表中的直接 eval 调用所创建的绑定位于声明参数的环境之外。
    2. calleeEnvcalleeContext 的 LexicalEnvironment。
    3. envRecordNewDeclarativeEnvironment(calleeEnv)。
    4. 断言:calleeContext 的 VariableEnvironment 与 calleeEnv 是同一个 Environment Record
    5. calleeContext 的 LexicalEnvironment 设为 envRecord
  21. paramNames 的每个 String paramName,执行:
    1. alreadyDeclared 为 ! envRecord.HasBinding(paramName)。
    2. 注:早期错误确保重复的参数名称只能出现在没有参数默认值或剩余参数的非严格函数中。
    3. 如果 alreadyDeclaredfalse,则
      1. 执行 ! envRecord.CreateMutableBinding(paramName, false)。
      2. 如果 hasDuplicatestrue,则
        1. 执行 ! envRecord.InitializeBinding(paramName, undefined)。
  22. 如果 argumentsObjNeededtrue,则
    1. 如果 stricttruesimpleParamListfalse,则
      1. argumentsObjCreateUnmappedArgumentsObject(argList)。
    2. 否则,
      1. 注:映射 arguments 对象只为没有 rest 参数、任何参数默认值初始化器或任何解构参数的非严格函数提供。
      2. argumentsObjCreateMappedArgumentsObject(func, formals, argList, envRecord)。
    3. 如果 stricttrue,则
      1. 执行 ! envRecord.CreateImmutableBinding("arguments", false)。
      2. 注:在严格模式代码中,早期错误会阻止尝试向此绑定赋值,因此其可变性不可观察。
    4. 否则,
      1. 执行 ! envRecord.CreateMutableBinding("arguments", false)。
    5. 执行 ! envRecord.InitializeBinding("arguments", argumentsObj)。
    6. paramBindingsparamNames 与 « "arguments" » 的列表连接
  23. 否则,
    1. paramBindingsparamNames
  24. iteratorRecordCreateListIteratorRecord(argList)。
  25. 如果 hasDuplicatestrue,则
    1. usedEnvundefined
  26. 否则,
    1. usedEnvenvRecord
  27. 注:以下步骤不能返回 ReturnCompletion,因为这种完成在表达式位置出现的唯一方式是使用 YieldExpression,而早期错误规则在 15.5.115.6.1 中禁止其出现在参数列表中。
  28. 使用参数 iteratorRecordusedEnv 执行 ? formalsIteratorBindingInitialization
  29. 如果 hasParamExprsfalse,则
    1. 注:参数和顶层 vars 只需要一个 Environment Record
    2. instantiatedVariableNamesList paramBindings 的副本。
    3. variableNames 的每个元素 name,执行:
      1. 如果 instantiatedVariableNames包含 name,则
        1. name 追加到 instantiatedVariableNames
        2. 执行 ! envRecord.CreateMutableBinding(name, false)。
        3. 执行 ! envRecord.InitializeBinding(name, undefined)。
    4. variableEnvenvRecord
  30. 否则,
    1. 注:需要一个单独的 Environment Record,以确保由形式参数列表中的表达式创建的闭包看不到函数体中的声明。
    2. variableEnvNewDeclarativeEnvironment(envRecord)。
    3. calleeContext 的 VariableEnvironment 设为 variableEnv
    4. instantiatedVariableNames 为一个新的空 List
    5. variableNames 的每个元素 name,执行:
      1. 如果 instantiatedVariableNames包含 name,则
        1. name 追加到 instantiatedVariableNames
        2. 执行 ! variableEnv.CreateMutableBinding(name, false)。
        3. 如果 paramBindings包含 namefuncNames 包含 name,则
          1. initialValueundefined
        4. 否则,
          1. initialValue 为 ! envRecord.GetBindingValue(name, false)。
        5. 执行 ! variableEnv.InitializeBinding(name, initialValue)。
        6. 注:与形式参数同名的 var 最初具有与相应已初始化参数相同的值。
  31. 如果 stricttrue,则
    1. lexicalEnvvariableEnv
  32. 否则,
    1. 如果宿主是 Web 浏览器,或以其他方式支持 块级函数声明的 Web 遗留兼容性语义,则
      1. 对每个 FunctionDeclaration funcDecl,其直接包含在任何 BlockCaseClauseDefaultClause xStatementList 中,且 code Contains xtrue,执行:
        1. funcNamefuncDeclBindingIdentifierStringValue
        2. 如果将 FunctionDeclaration funcDecl 替换为以 funcName 作为 BindingIdentifierVariableStatement 不会为 func 产生任何早期错误,并且 paramNames包含 funcName,则
          1. 注:只有当 funcName 既不是 VarDeclaredName、形式参数名称,也不是另一个 FunctionDeclaration 的名称时,才在此处实例化 funcName 的 var 绑定。
          2. 如果 instantiatedVariableNames包含 funcNamefuncName 不是 "arguments",则
            1. 执行 ! variableEnv.CreateMutableBinding(funcName, false)。
            2. 执行 ! variableEnv.InitializeBinding(funcName, undefined)。
            3. funcName 追加到 instantiatedVariableNames
          3. FunctionDeclaration funcDecl 被求值时,执行以下步骤以取代 15.2.6 中提供的 FunctionDeclaration Evaluation 算法:
            1. funcEnv 为正在运行的执行上下文的 VariableEnvironment。
            2. blockEnv 为正在运行的执行上下文的 LexicalEnvironment。
            3. funcObj 为 ! blockEnv.GetBindingValue(funcName, false)。
            4. 执行 ! funcEnv.SetMutableBinding(funcName, funcObj, false)。
            5. 返回 unused
    2. lexicalEnvNewDeclarativeEnvironment(variableEnv)。
    3. 注:非严格函数为顶层词法声明使用单独的 Environment Record,使得直接 eval 可以确定 eval 代码引入的任何 var 作用域声明是否与既有的顶层词法作用域声明冲突。严格函数不需要这样做,因为严格的直接 eval 总是将所有声明放入新的 Environment Record
  33. calleeContext 的 LexicalEnvironment 设为 lexicalEnv
  34. lexicalDeclscodeLexicallyScopedDeclarations
  35. lexicalDecls 的每个元素 lexicalDecl,执行:
    1. 注:词法声明的名称不能与函数/生成器声明、形式参数或 var 名称相同。词法声明的名称仅在此处实例化,但不初始化。
    2. lexicalDeclBoundNames 的每个元素 name,执行:
      1. 如果 lexicalDeclIsConstantDeclarationtrue,则
        1. 执行 ! lexicalEnv.CreateImmutableBinding(name, true)。
      2. 否则,
        1. 执行 ! lexicalEnv.CreateMutableBinding(name, false)。
  36. privateEnvcalleeContext 的 PrivateEnvironment。
  37. funcsToInitialize 的每个 Parse Node funcDecl,执行:
    1. funcNamefuncDeclBoundNames 的唯一元素。
    2. funcObj 为使用参数 lexicalEnvprivateEnvfuncDecl 执行 InstantiateFunctionObject 的结果。
    3. 执行 ! variableEnv.SetMutableBinding(funcName, funcObj, false)。
  38. 返回 unused

10.3 内置函数对象

内置函数对象普通对象;它必须满足 10.1 中列出的普通对象要求。

除了每个普通对象都要求的内部槽(参见 10.1)之外,内置函数对象还必须具有以下内部槽:

  • [[Realm]],一个 Realm Record,表示该函数被创建所在的 realm
  • [[InitialName]],一个 String,是该函数的初始名称。它由 20.2.3.5 使用。
  • [[Async]],一个 Boolean,指示该函数在 BuiltinCallOrConstruct 中是否具有 async 函数调用和构造行为。

除非另有指定,内置函数对象[[Prototype]] 内部槽的初始值为 %Function.prototype%

内置函数对象必须具有符合 10.3.1 中定义的 [[Call]] 内部方法。

当且仅当内置函数对象被描述为“constructor”,或本规范中的某个算法显式设置了它的 [[Construct]] 内部方法时,它才具有 [[Construct]] 内部方法。这种 [[Construct]] 内部方法必须符合 10.3.2 中的定义。

实现可以提供本规范未定义的附加内置函数对象

10.3.1 [[Call]] ( thisArg, argList )

The [[Call]] internal method of a built-in function object func takes arguments thisArg (an ECMAScript language value) and argList (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. 返回 ? BuiltinCallOrConstruct(func, thisArg, argList, undefined)。

10.3.2 [[Construct]] ( argList, newTarget )

The [[Construct]] internal method of a built-in function object func(当该方法存在时) takes arguments argList (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. result 为 ? BuiltinCallOrConstruct(func, uninitialized, argList, newTarget)。
  2. 断言:result 是 Object。
  3. 返回 result

10.3.3 BuiltinCallOrConstruct ( func, thisArg, argList, newTarget )

The abstract operation BuiltinCallOrConstruct takes arguments func (a built-in function object), thisArg (an ECMAScript language value or uninitialized), argList (a List of ECMAScript language values), and newTarget (a constructor or undefined) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. callerContext 为运行中执行上下文。
  2. 如果 callerContext 尚未暂停,则暂停 callerContext
  3. calleeContext 为一个新的执行上下文。
  4. calleeContext 的 Function 设置为 func
  5. calleeRealmfunc.[[Realm]]
  6. calleeContextRealm 设置为 calleeRealm
  7. calleeContext 的 ScriptOrModule 设置为 null
  8. 执行 calleeContext 的任何必要的实现定义初始化。
  9. calleeContext 压入执行上下文栈;calleeContext 现在是运行中执行上下文。
  10. 如果 func.[[Async]]true,则
    1. promiseCapability 为 ! NewPromiseCapability(%Promise%)。
    2. resultsClosure 为一个不带形参的新 Abstract Closure,它捕获 functhisArgargListnewTarget,并在被调用时执行以下步骤:
      1. resultCompletion Record,其是以符合 func 规范的方式求值 func 的结果。如果 thisArguninitialized,则 this 值未初始化;否则 thisArg 提供 this 值。argList 提供命名形参。newTarget 提供 NewTarget 值。
      2. 注:如果 func 在本文档中定义,则“func 的规范”是通过算法步骤或其他方式为其指定的行为。
      3. 返回 Completion(result)。
    3. 执行 AsyncFunctionStart(promiseCapability, resultsClosure)。
    4. 从执行上下文栈中移除 calleeContext,并将 callerContext 恢复为运行中执行上下文。
    5. 返回 promiseCapability.[[Promise]]
  11. resultCompletion Record,其是以符合 func 规范的方式求值 func 的结果。如果 thisArguninitialized,则 this 值未初始化;否则 thisArg 提供 this 值。argList 提供命名形参。newTarget 提供 NewTarget 值。
  12. 注:如果 func 在本文档中定义,则“func 的规范”是通过算法步骤或其他方式为其指定的行为。
  13. 从执行上下文栈中移除 calleeContext,并将 callerContext 恢复为运行中执行上下文。
  14. 返回 ? result
Note

calleeContext 从执行上下文栈中移除时,如果它已暂停并被可访问的 Generator 保留以供稍后恢复,则不得销毁它。

10.3.4 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList [ , realm [ , proto [ , prefix [ , async ] ] ] ] )

The abstract operation CreateBuiltinFunction takes arguments behaviour (an Abstract Closure, a set of algorithm steps, or some other definition of a function's behaviour provided in this specification), length (a non-negative integer or +∞), name (a property key or a Private Name), and additionalInternalSlotsList (a List of names of internal slots) and optional arguments realm (a Realm Record), proto (an Object or null), prefix (a String), and async (a Boolean) and returns a built-in function object. additionalInternalSlotsList 包含必须作为对象一部分定义的附加内部槽的名称。此操作会创建一个内置函数对象。 It performs the following steps when called:

  1. 如果 realm 不存在,则将 realm 设置为当前 Realm Record
  2. 如果 proto 不存在,则将 proto 设置为 realm.[[Intrinsics]].[[%Function.prototype%]]。
  3. 如果 async 不存在,则将 async 设置为 false
  4. internalSlotsList 为一个 List,其中包含 10.3 对即将创建的内置函数对象所要求的所有内部槽的名称。
  5. additionalInternalSlotsList 的元素追加到 internalSlotsList
  6. func 为一个新的内置函数对象,当被调用时,它使用所提供实参作为 behaviour 指定的相应形参的值,执行 behaviour 描述的动作。新的函数对象具有名称为 internalSlotsList 元素的内部槽,以及一个 [[InitialName]] 内部槽。
  7. func.[[Async]] 设置为 async
  8. func.[[Prototype]] 设置为 proto
  9. func.[[Extensible]] 设置为 true
  10. func.[[Realm]] 设置为 realm
  11. func.[[InitialName]] 设置为 null
  12. 执行 SetFunctionLength(func, length)。
  13. 如果 prefix 不存在,则
    1. 执行 SetFunctionName(func, name)。
  14. 否则,
    1. 执行 SetFunctionName(func, name, prefix)。
  15. 返回 func

本规范中定义的每个内置函数都是通过调用 CreateBuiltinFunction 抽象操作创建的。

10.4 内置异质对象内部方法与内部槽

本规范定义了若干种内置异质对象。这些对象通常行为类似于普通对象,只是在少数特定情形下不同。以下异质对象使用普通对象内部方法,除非下文明确另有指定:

10.4.1 绑定函数异质对象

绑定函数异质对象是包装另一个函数对象异质对象绑定函数异质对象是可调用的(它有 [[Call]] 内部方法,并且可以有 [[Construct]] 内部方法)。调用绑定函数异质对象通常会导致调用其所包装的函数。

如果一个对象的 [[Call]] 和(如果适用)[[Construct]] 内部方法使用以下实现,且其其他基本内部方法使用 10.1 中的定义,则该对象是绑定函数异质对象。这些方法由 BoundFunctionCreate 安装。

绑定函数异质对象不具有 Table 26 中列出的 ECMAScript 函数对象内部槽。相反,除了 [[Prototype]][[Extensible]] 之外,它们还具有 Table 27 中列出的内部槽。

Table 27: 绑定函数异质对象的内部槽
内部槽 类型 描述
[[BoundTargetFunction]] a callable Object 被包装的函数对象
[[BoundThis]] an ECMAScript language value 调用被包装函数时始终作为 this 值传递的值。
[[BoundArguments]] a List of ECMAScript language values 一个值列表,其元素用作对被包装函数的任何调用的最前面的实参。

10.4.1.1 [[Call]] ( thisArg, argList )

The [[Call]] internal method of a bound function exotic object func takes arguments thisArg (an ECMAScript language value) and argList (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. targetfunc.[[BoundTargetFunction]]
  2. boundThisfunc.[[BoundThis]]
  3. boundArgsfunc.[[BoundArguments]]
  4. argsboundArgsargList列表连接
  5. 返回 ? Call(target, boundThis, args)。

10.4.1.2 [[Construct]] ( argList, newTarget )

The [[Construct]] internal method of a bound function exotic object func takes arguments argList (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. targetfunc.[[BoundTargetFunction]]
  2. 断言:IsConstructor(target) 是 true
  3. boundArgsfunc.[[BoundArguments]]
  4. argsboundArgsargList列表连接
  5. 如果 SameValue(func, newTarget) 是 true,则将 newTarget 设置为 target
  6. 返回 ? Construct(target, args, newTarget)。

10.4.1.3 BoundFunctionCreate ( targetFunc, boundThis, boundArgs )

The abstract operation BoundFunctionCreate takes arguments targetFunc (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 performs the following steps when called:

  1. proto 为 ? targetFunc.[[GetPrototypeOf]]()
  2. internalSlotsList 为 « [[Prototype]], [[Extensible]] » 和 Table 27 中列出的内部槽的列表连接
  3. objMakeBasicObject(internalSlotsList)。
  4. obj.[[Prototype]] 设置为 proto
  5. 按照 10.4.1.1 中指定的方式设置 obj.[[Call]]
  6. 如果 IsConstructor(targetFunc) 是 true,则
    1. 按照 10.4.1.2 中指定的方式设置 obj.[[Construct]]
  7. obj.[[BoundTargetFunction]] 设置为 targetFunc
  8. obj.[[BoundThis]] 设置为 boundThis
  9. obj.[[BoundArguments]] 设置为 boundArgs
  10. 返回 obj

10.4.2 数组异质对象

Array 是一种对数组索引属性键(参见 6.1.7)进行特殊处理的异质对象属性名数组索引的属性也称为元素。每个 Array 都有一个不可配置的 "length" 属性,其值始终是一个非负整数 Number,其数学值严格小于 232"length" 属性的值在数值上大于每个名称为数组索引的自有属性的名称;每当 Array 的自有属性被创建或更改时,其他属性会按需要调整以维持此不变量。具体而言,每当添加一个名称为数组索引的自有属性时,"length" 属性的值会在必要时被改为比该数组索引的数值大一;并且每当 "length" 属性的值改变时,所有名称为数组索引且其值不小于新长度的自有属性都会被删除。此约束仅适用于 Array 的自有属性,并且不受可能从其原型继承的 "length"数组索引属性影响。

如果一个对象的 [[DefineOwnProperty]] 内部方法使用以下实现,且其其他基本内部方法使用 10.1 中的定义,则该对象是 Array 异质对象(或简称为 Array)。这些方法由 ArrayCreate 安装。

10.4.2.1 [[DefineOwnProperty]] ( propertyKey, propertyDesc )

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

  1. 如果 propertyKey"length",则返回 ? ArraySetLength(array, propertyDesc)。
  2. 如果 propertyKey数组索引,则
    1. lengthDescOrdinaryGetOwnProperty(array, "length")。
    2. 断言:lengthDesc 不是 undefined
    3. 断言:IsDataDescriptor(lengthDesc) 是 true
    4. 断言:lengthDesc.[[Configurable]]false
    5. lengthlengthDesc.[[Value]]
    6. 断言:length 是非负整数 Number。
    7. index 为 ! ToUint32(propertyKey)。
    8. 如果 indexlengthlengthDesc.[[Writable]]false,则返回 false
    9. succeeded 为 ! OrdinaryDefineOwnProperty(array, propertyKey, propertyDesc)。
    10. 如果 succeededfalse,则返回 false
    11. 如果 indexlength,则
      1. lengthDesc.[[Value]] 设置为 index + 1𝔽
      2. succeeded 设置为 ! OrdinaryDefineOwnProperty(array, "length", lengthDesc)。
      3. 断言:succeededtrue
    12. 返回 true
  3. 返回 ? OrdinaryDefineOwnProperty(array, propertyKey, propertyDesc)。

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. 它用于指定新 Arrays 的创建。 It performs the following steps when called:

  1. 如果 length > 232 - 1,则抛出 RangeError 异常。
  2. 如果 proto 不存在,则将 proto 设置为 %Array.prototype%
  3. arrayMakeBasicObject[[Prototype]], [[Extensible]] »)。
  4. array.[[Prototype]] 设置为 proto
  5. 按照 10.4.2.1 中指定的方式设置 array.[[DefineOwnProperty]]
  6. 执行 ! OrdinaryDefineOwnProperty(array, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  7. 返回 array

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. 它用于指定使用从 originalArray 派生的构造函数来创建新的 Array 或类似对象。它不强制要求该构造函数返回 Array。 It performs the following steps when called:

  1. isArray 为 ? IsArray(originalArray)。
  2. 如果 isArrayfalse,则返回 ? ArrayCreate(length)。
  3. ctor 为 ? Get(originalArray, "constructor")。
  4. 如果 IsConstructor(ctor) 是 true,则
    1. thisRealm当前 Realm Record
    2. ctorRealm 为 ? GetFunctionRealm(ctor)。
    3. 如果 thisRealmctorRealm 不是同一个 Realm Record,则
      1. 如果 SameValue(ctor, ctorRealm.[[Intrinsics]].[[%Array%]]) 是 true,则将 ctor 设置为 undefined
  5. 如果 ctor 是 Object,则
    1. ctor 设置为 ? Get(ctor, %Symbol.species%)。
    2. 如果 ctornull,则将 ctor 设置为 undefined
  6. 如果 ctorundefined,则返回 ? ArrayCreate(length)。
  7. 如果 IsConstructor(ctor) 是 false,则抛出 TypeError 异常。
  8. 返回 ? Construct(ctor, « 𝔽(length) »)。
Note

如果 originalArray 是使用一个不同于运行中执行上下文 realmrealm 的标准内置 Array 构造函数创建的,则使用运行中执行上下文的 realm 创建新的 Array。这保持了与 Web 浏览器的兼容性,Web 浏览器历史上对现在使用 ArraySpeciesCreate 定义的 Array.prototype 方法具有这种行为。

10.4.2.4 ArraySetLength ( array, propertyDesc )

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

  1. 如果 propertyDesc 不具有 [[Value]] 字段,则
    1. 返回 ! OrdinaryDefineOwnProperty(array, "length", propertyDesc)。
  2. newLengthDescpropertyDesc 的副本。
  3. newLength 为 ? ToUint32(propertyDesc.[[Value]])。
  4. numberLength 为 ? ToNumber(propertyDesc.[[Value]])。
  5. 如果 SameValueZero(newLength, numberLength) 是 false,则抛出 RangeError 异常。
  6. newLengthDesc.[[Value]] 设置为 newLength
  7. oldLengthDescOrdinaryGetOwnProperty(array, "length")。
  8. 断言:oldLengthDesc 不是 undefined
  9. 断言:IsDataDescriptor(oldLengthDesc) 是 true
  10. 断言:oldLengthDesc.[[Configurable]]false
  11. oldLengtholdLengthDesc.[[Value]]
  12. 如果 newLengtholdLength,则
    1. 返回 ! OrdinaryDefineOwnProperty(array, "length", newLengthDesc)。
  13. 如果 oldLengthDesc.[[Writable]]false,则返回 false
  14. 如果 newLengthDesc 不具有 [[Writable]] 字段,或 newLengthDesc.[[Writable]]true,则
    1. newWritabletrue
  15. 否则,
    1. 注:将 [[Writable]] 特性设置为 false 会被推迟,以防某些元素无法删除。
    2. newWritablefalse
    3. newLengthDesc.[[Writable]] 设置为 true
  16. succeeded 为 ! OrdinaryDefineOwnProperty(array, "length", newLengthDesc)。
  17. 如果 succeededfalse,则返回 false
  18. array 的每个自有属性键 propertyKey,如果 propertyKey数组索引且 ! ToUint32(propertyKey) ≥ newLength,则按降序数值索引顺序,执行:
    1. deleteSucceeded 为 ! array.[[Delete]](propertyKey)。
    2. 如果 deleteSucceededfalse,则
      1. newLengthDesc.[[Value]] 设置为 ! ToUint32(propertyKey) + 1𝔽
      2. 如果 newWritablefalse,则将 newLengthDesc.[[Writable]] 设置为 false
      3. 执行 ! OrdinaryDefineOwnProperty(array, "length", newLengthDesc)。
      4. 返回 false
  19. 如果 newWritablefalse,则
    1. succeeded 设置为 ! OrdinaryDefineOwnProperty(array, "length", PropertyDescriptor { [[Writable]]: false })。
    2. 断言:succeededtrue
  20. 返回 true
Note

在步骤 34 中,如果 propertyDesc.[[Value]] 是对象,则其 valueOf 方法会被调用两次。这是一种遗留行为,自本规范第 2nd 版起就以这种效果指定。

10.4.3 字符串异质对象

String 对象是一种异质对象,它封装一个 String 值,并暴露与该 String 值的各个代码单元元素对应的虚拟整数索引数据属性String 异质对象始终具有名为 "length"数据属性,其值是所封装 String 值的长度。代码单元数据属性"length" 属性都不可写且不可配置。

如果一个对象的 [[GetOwnProperty]][[DefineOwnProperty]][[OwnPropertyKeys]] 内部方法使用以下实现,且其其他基本内部方法使用 10.1 中的定义,则该对象是 String 异质对象(或简称为 String 对象)。这些方法由 StringCreate 安装。

String 异质对象具有与普通对象相同的内部槽。它们还具有一个 [[StringData]] 内部槽。

10.4.3.1 [[GetOwnProperty]] ( propertyKey )

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

  1. propertyDescOrdinaryGetOwnProperty(string, propertyKey)。
  2. 如果 propertyDesc 不是 undefined,则返回 propertyDesc
  3. 返回 StringGetOwnProperty(string, propertyKey)。

10.4.3.2 [[DefineOwnProperty]] ( propertyKey, propertyDesc )

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

  1. stringDescStringGetOwnProperty(string, propertyKey)。
  2. 如果 stringDesc 不是 undefined,则
    1. extensiblestring.[[Extensible]]
    2. 返回 IsCompatiblePropertyDescriptor(extensible, propertyDesc, stringDesc)。
  3. 返回 ! OrdinaryDefineOwnProperty(string, propertyKey, propertyDesc)。

10.4.3.3 [[OwnPropertyKeys]] ( )

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

  1. keys 为新的空 List
  2. stringobj.[[StringData]]
  3. 断言:string 是 String。
  4. lengthstring 的长度。
  5. 对每个整数 i,使得 0 ≤ i < length,按升序,执行:
    1. 将 ! ToString(𝔽(i)) 追加到 keys
  6. obj 的每个自有属性键 propertyKey,如果 propertyKey数组索引且 ! ToIntegerOrInfinity(propertyKey) ≥ length,则按升序数值索引顺序,执行:
    1. propertyKey 追加到 keys
  7. obj 的每个自有属性键 propertyKey,如果 propertyKey 是 String 且 propertyKey 不是数组索引,则按属性创建的升序时间顺序,执行:
    1. propertyKey 追加到 keys
  8. obj 的每个自有属性键 propertyKey,如果 propertyKey 是 Symbol,则按属性创建的升序时间顺序,执行:
    1. propertyKey 追加到 keys
  9. 返回 keys

10.4.3.4 StringCreate ( value, proto )

The abstract operation StringCreate takes arguments value (a String) and proto (an Object) and returns a String exotic object. 它用于指定新 String 异质对象的创建。 It performs the following steps when called:

  1. stringMakeBasicObject[[Prototype]], [[Extensible]], [[StringData]] »)。
  2. string.[[Prototype]] 设置为 proto
  3. string.[[StringData]] 设置为 value
  4. 按照 10.4.3.1 中指定的方式设置 string.[[GetOwnProperty]]
  5. 按照 10.4.3.2 中指定的方式设置 string.[[DefineOwnProperty]]
  6. 按照 10.4.3.3 中指定的方式设置 string.[[OwnPropertyKeys]]
  7. lengthvalue 的长度。
  8. 执行 ! DefinePropertyOrThrow(string, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。
  9. 返回 string

10.4.3.5 StringGetOwnProperty ( string, propertyKey )

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

  1. 如果 propertyKey 不是 String,则返回 undefined
  2. numericIndexCanonicalNumericIndexString(propertyKey)。
  3. 如果 numericIndex 不是整数 Number,则返回 undefined
  4. 如果 numericIndex-0𝔽numericIndex < -0𝔽,则返回 undefined
  5. stringDatastring.[[StringData]]
  6. 断言:stringData 是 String。
  7. lengthstringData 的长度。
  8. 如果 (numericIndex) ≥ length,则返回 undefined
  9. resultStringstringData 中从 (numericIndex) 到 (numericIndex) + 1 的子字符串
  10. 返回 PropertyDescriptor { [[Value]]: resultString, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }。

10.4.4 arguments 异质对象

大多数 ECMAScript 函数都会向其代码提供 arguments 对象。取决于函数定义的特征,其 arguments 对象要么是普通对象,要么是 arguments 异质对象arguments 异质对象是一种异质对象,其数组索引属性映射到其关联 ECMAScript 函数某次调用的形式参数绑定。

如果一个对象的内部方法使用以下实现,其中此处未指定的方法使用 10.1 中的定义,则该对象是 arguments 异质对象。这些方法由 CreateMappedArgumentsObject 安装。

Note 1

虽然 CreateUnmappedArgumentsObject 被归入本条款,但它创建的是普通对象,而不是 arguments 异质对象

arguments 异质对象具有与普通对象相同的内部槽。它们还具有一个 [[ParameterMap]] 内部槽。普通 arguments 对象也具有一个 [[ParameterMap]] 内部槽,其值始终为 undefined。对于普通 arguments 对象,[[ParameterMap]] 内部槽仅由 Object.prototype.toString20.1.3.6)用于将其识别为这类对象。

Note 2

arguments 异质对象中数值名称值小于相应函数对象的形式参数数量的整数索引数据属性,初始时与函数执行上下文中的相应实参绑定共享其值。这意味着更改该属性会更改相应实参绑定的值,反之亦然。如果这样的属性被删除然后重新定义,或者该属性被更改为访问器属性,则这种对应关系会被打破。如果 arguments 对象是普通对象,则其属性值只是传给函数的实参的副本,属性值与形式参数值之间没有动态链接。

Note 3

ParameterMap 对象及其属性值用作指定 arguments 对象与实参绑定对应关系的装置。ParameterMap 对象以及作为其属性值的对象不能从 ECMAScript 代码直接观察到。ECMAScript 实现不需要实际创建或使用这些对象来实现指定语义。

Note 4

普通 arguments 对象定义了一个名为 "callee" 的不可配置访问器属性,访问它时会抛出 TypeError 异常。"callee" 属性对于 arguments 异质对象具有更具体的含义,后者只为某些非严格函数类别创建。此属性在普通变体中的定义,是为了确保符合规范的 ECMAScript 实现不会以任何其他方式定义它。

Note 5

ECMAScript 的 arguments 异质对象实现历史上曾包含一个名为 "caller"访问器属性。在 ECMAScript 2017 之前,本规范包含了在普通 arguments 对象上定义抛出型 "caller" 属性的要求。由于实现不再包含此扩展,ECMAScript 2017 删除了对抛出型 "caller" 访问器的要求。

10.4.4.1 [[GetOwnProperty]] ( propertyKey )

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

  1. propertyDescOrdinaryGetOwnProperty(args, propertyKey)。
  2. 如果 propertyDescundefined,则返回 undefined
  3. mapargs.[[ParameterMap]]
  4. isMapped 为 ! HasOwnProperty(map, propertyKey)。
  5. 如果 isMappedtrue,则
    1. propertyDesc.[[Value]] 设置为 ! Get(map, propertyKey)。
  6. 返回 propertyDesc

10.4.4.2 [[DefineOwnProperty]] ( propertyKey, propertyDesc )

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

  1. mapargs.[[ParameterMap]]
  2. isMapped 为 ! HasOwnProperty(map, propertyKey)。
  3. newArgDescpropertyDesc
  4. 如果 isMappedtrueIsDataDescriptor(propertyDesc) 是 true,则
    1. 如果 propertyDesc 不具有 [[Value]] 字段,propertyDesc 具有 [[Writable]] 字段,并且 propertyDesc.[[Writable]]false,则
      1. newArgDesc 设置为 propertyDesc 的副本。
      2. newArgDesc.[[Value]] 设置为 ! Get(map, propertyKey)。
  5. allowed 为 ! OrdinaryDefineOwnProperty(args, propertyKey, newArgDesc)。
  6. 如果 allowedfalse,则返回 false
  7. 如果 isMappedtrue,则
    1. 如果 IsAccessorDescriptor(propertyDesc) 是 true,则
      1. 执行 ! map.[[Delete]](propertyKey)。
    2. 否则,
      1. 如果 propertyDesc 具有 [[Value]] 字段,则
        1. 断言:以下 Set 会成功,因为由 arguments 对象映射的形式参数始终可写。
        2. 执行 ! Set(map, propertyKey, propertyDesc.[[Value]], false)。
      2. 如果 propertyDesc 具有 [[Writable]] 字段且 propertyDesc.[[Writable]]false,则
        1. 执行 ! map.[[Delete]](propertyKey)。
  8. 返回 true

10.4.4.3 [[Get]] ( propertyKey, receiver )

The [[Get]] internal method of an arguments exotic object args takes arguments propertyKey (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. mapargs.[[ParameterMap]]
  2. isMapped 为 ! HasOwnProperty(map, propertyKey)。
  3. 如果 isMappedfalse,则返回 ? OrdinaryGet(args, propertyKey, receiver)。
  4. 断言:map 包含 propertyKey 的形式参数映射。
  5. 返回 ! Get(map, propertyKey)。

10.4.4.4 [[Set]] ( propertyKey, value, receiver )

The [[Set]] internal method of an arguments exotic object args takes arguments propertyKey (a property key), value (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. 如果 SameValue(args, receiver) 是 false,则
    1. isMappedfalse
  2. 否则,
    1. mapargs.[[ParameterMap]]
    2. isMapped 为 ! HasOwnProperty(map, propertyKey)。
  3. 如果 isMappedtrue,则
    1. 断言:以下 Set 会成功,因为由 arguments 对象映射的形式参数始终可写。
    2. 执行 ! Set(map, propertyKey, value, false)。
  4. 返回 ? OrdinarySet(args, propertyKey, value, receiver)。

10.4.4.5 [[Delete]] ( propertyKey )

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

  1. mapargs.[[ParameterMap]]
  2. isMapped 为 ! HasOwnProperty(map, propertyKey)。
  3. result 为 ? OrdinaryDelete(args, propertyKey)。
  4. 如果 resulttrueisMappedtrue,则
    1. 执行 ! map.[[Delete]](propertyKey)。
  5. 返回 result

10.4.4.6 CreateUnmappedArgumentsObject ( argList )

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

  1. lengthargList 中元素的数量。
  2. objOrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »)。
  3. obj.[[ParameterMap]] 设置为 undefined
  4. 执行 ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  5. index 为 0。
  6. 重复,当 index < length 时,
    1. valueargList[index]。
    2. 执行 ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), value)。
    3. index 设置为 index + 1。
  7. 执行 ! DefinePropertyOrThrow(obj, %Symbol.iterator%, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  8. 执行 ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false })。
  9. 返回 obj

10.4.4.7 CreateMappedArgumentsObject ( func, formals, argList, envRecord )

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

  1. 断言:formals包含 rest 参数、任何绑定模式或任何初始化器。它可以包含重复标识符。
  2. lengthargList 中元素的数量。
  3. objMakeBasicObject[[Prototype]], [[Extensible]], [[ParameterMap]] »)。
  4. 按照 10.4.4.1 中指定的方式设置 obj.[[GetOwnProperty]]
  5. 按照 10.4.4.2 中指定的方式设置 obj.[[DefineOwnProperty]]
  6. 按照 10.4.4.3 中指定的方式设置 obj.[[Get]]
  7. 按照 10.4.4.4 中指定的方式设置 obj.[[Set]]
  8. 按照 10.4.4.5 中指定的方式设置 obj.[[Delete]]
  9. obj.[[Prototype]] 设置为 %Object.prototype%
  10. mapOrdinaryObjectCreate(null)。
  11. obj.[[ParameterMap]] 设置为 map
  12. paramNamesformalsBoundNames
  13. paramCountparamNames 中元素的数量。
  14. index 为 0。
  15. 重复,当 index < length 时,
    1. valueargList[index]。
    2. 执行 ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), value)。
    3. index 设置为 index + 1。
  16. 执行 ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  17. mappedNames 为新的空 List
  18. index 设置为 paramCount - 1。
  19. 重复,当 index ≥ 0 时,
    1. nameparamNames[index]。
    2. 如果 mappedNames包含 name,则
      1. name 追加到 mappedNames
      2. 如果 index < length,则
        1. getterMakeArgGetter(name, envRecord)。
        2. setterMakeArgSetter(name, envRecord)。
        3. 执行 ! map.[[DefineOwnProperty]](! ToString(𝔽(index)), PropertyDescriptor { [[Set]]: setter, [[Get]]: getter, [[Enumerable]]: false, [[Configurable]]: true })。
    3. index 设置为 index - 1。
  20. 执行 ! DefinePropertyOrThrow(obj, %Symbol.iterator%, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  21. 执行 ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  22. 返回 obj

10.4.4.7.1 MakeArgGetter ( name, envRecord )

The abstract operation MakeArgGetter takes arguments name (a String) and envRecord (an Environment Record) and returns a function object. 它创建一个内置函数对象,该对象在执行时返回 envRecord 中为 name 绑定的值。 It performs the following steps when called:

  1. getterClosure 为一个不带形参的新 Abstract Closure,它捕获 nameenvRecord,并在被调用时执行以下步骤:
    1. 返回 NormalCompletion(! envRecord.GetBindingValue(name, false))。
  2. getterCreateBuiltinFunction(getterClosure, 0, "", « »)。
  3. 注:getter 永远不能被 ECMAScript 代码直接访问。
  4. 返回 getter

10.4.4.7.2 MakeArgSetter ( name, envRecord )

The abstract operation MakeArgSetter takes arguments name (a String) and envRecord (an Environment Record) and returns a function object. 它创建一个内置函数对象,该对象在执行时设置 envRecord 中为 name 绑定的值。 It performs the following steps when called:

  1. setterClosure 为一个具有形参 (value) 的新 Abstract Closure,它捕获 nameenvRecord,并在被调用时执行以下步骤:
    1. 返回 NormalCompletion(! envRecord.SetMutableBinding(name, value, false))。
  2. setterCreateBuiltinFunction(setterClosure, 1, "", « »)。
  3. 注:setter 永远不能被 ECMAScript 代码直接访问。
  4. 返回 setter

10.4.5 TypedArray 异质对象

TypedArray 是一种异质对象,它对作为规范数值字符串属性键进行特殊处理,使用其中处于边界内的整数索引子集来索引统一类型的元素,并强制执行这样的不变量:其余属性不存在且不会引发原型链遍历。

Note

因为对于任何 Number nToString(n) 都是一个规范数值字符串,所以实现可以将 Numbers 视为 TypedArrays属性键,而无需实际执行字符串转换。

TypedArrays 具有与普通对象相同的内部槽,并且还具有 [[ViewedArrayBuffer]][[TypedArrayName]][[ContentType]][[ByteLength]][[ByteOffset]][[ArrayLength]] 内部槽。

如果一个对象的 [[PreventExtensions]][[GetOwnProperty]][[HasProperty]][[DefineOwnProperty]][[Get]][[Set]][[Delete]][[OwnPropertyKeys]] 内部方法使用本节中的定义,且其其他基本内部方法使用 10.1 中的定义,则该对象是 TypedArray。这些方法由 TypedArrayCreate 安装。

10.4.5.1 [[PreventExtensions]] ( )

The [[PreventExtensions]] internal method of a TypedArray obj takes no arguments and returns a normal completion containing a Boolean. It performs the following steps when called:

  1. 注:6.1.7.3 中指定的与可扩展性相关的不变量,不允许此方法在 obj 可以获得(或失去后重新获得)属性时返回 true;当其底层 buffer 被调整大小时,具有整数索引名称的属性可能发生这种情况。
  2. 如果 IsTypedArrayFixedLength(obj) 是 false,则返回 false
  3. 返回 OrdinaryPreventExtensions(obj)。

10.4.5.2 [[GetOwnProperty]] ( propertyKey )

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

  1. 如果 propertyKey 是 String,则
    1. numericIndexCanonicalNumericIndexString(propertyKey)。
    2. 如果 numericIndex 不是 undefined,则
      1. valueTypedArrayGetElement(obj, numericIndex)。
      2. 如果 valueundefined,则返回 undefined
      3. 返回 PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }。
  2. 返回 OrdinaryGetOwnProperty(obj, propertyKey)。

10.4.5.3 [[HasProperty]] ( propertyKey )

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

  1. 如果 propertyKey 是 String,则
    1. numericIndexCanonicalNumericIndexString(propertyKey)。
    2. 如果 numericIndex 不是 undefined,则返回 IsValidIntegerIndex(obj, numericIndex)。
  2. 返回 ? OrdinaryHasProperty(obj, propertyKey)。

10.4.5.4 [[DefineOwnProperty]] ( propertyKey, propertyDesc )

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

  1. 如果 propertyKey 是 String,则
    1. numericIndexCanonicalNumericIndexString(propertyKey)。
    2. 如果 numericIndex 不是 undefined,则
      1. 如果 IsValidIntegerIndex(obj, numericIndex) 是 false,则返回 false
      2. 如果 propertyDesc 具有 [[Configurable]] 字段且 propertyDesc.[[Configurable]]false,则返回 false
      3. 如果 propertyDesc 具有 [[Enumerable]] 字段且 propertyDesc.[[Enumerable]]false,则返回 false
      4. 如果 IsAccessorDescriptor(propertyDesc) 是 true,则返回 false
      5. 如果 propertyDesc 具有 [[Writable]] 字段且 propertyDesc.[[Writable]]false,则返回 false
      6. 如果 propertyDesc 具有 [[Value]] 字段,则执行 ? TypedArraySetElement(obj, numericIndex, propertyDesc.[[Value]])。
      7. 返回 true
  2. 返回 ! OrdinaryDefineOwnProperty(obj, propertyKey, propertyDesc)。

10.4.5.5 [[Get]] ( propertyKey, receiver )

The [[Get]] internal method of a TypedArray obj takes arguments propertyKey (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. 如果 propertyKey 是 String,则
    1. numericIndexCanonicalNumericIndexString(propertyKey)。
    2. 如果 numericIndex 不是 undefined,则
      1. 返回 TypedArrayGetElement(obj, numericIndex)。
  2. 返回 ? OrdinaryGet(obj, propertyKey, receiver)。

10.4.5.6 [[Set]] ( propertyKey, value, receiver )

The [[Set]] internal method of a TypedArray obj takes arguments propertyKey (a property key), value (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. 如果 propertyKey 是 String,则
    1. numericIndexCanonicalNumericIndexString(propertyKey)。
    2. 如果 numericIndex 不是 undefined,则
      1. 如果 SameValue(obj, receiver) 是 true,则
        1. 执行 ? TypedArraySetElement(obj, numericIndex, value)。
        2. 返回 true
      2. 如果 IsValidIntegerIndex(obj, numericIndex) 是 false,则返回 true
  2. 返回 ? OrdinarySet(obj, propertyKey, value, receiver)。

10.4.5.7 [[Delete]] ( propertyKey )

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

  1. 如果 propertyKey 是 String,则
    1. numericIndexCanonicalNumericIndexString(propertyKey)。
    2. 如果 numericIndex 不是 undefined,则
      1. 如果 IsValidIntegerIndex(obj, numericIndex) 是 false,则返回 true
      2. 返回 false
  2. 返回 ! OrdinaryDelete(obj, propertyKey)。

10.4.5.8 [[OwnPropertyKeys]] ( )

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

  1. taRecordMakeTypedArrayWithBufferWitnessRecord(obj, seq-cst)。
  2. keys 为新的空 List
  3. 如果 IsTypedArrayOutOfBounds(taRecord) 是 false,则
    1. lengthTypedArrayLength(taRecord)。
    2. 对每个整数 i,使得 0 ≤ i < length,按升序,执行:
      1. 将 ! ToString(𝔽(i)) 追加到 keys
  4. obj 的每个自有属性键 propertyKey,如果 propertyKey 是 String 且 propertyKey 不是整数索引,则按属性创建的升序时间顺序,执行:
    1. propertyKey 追加到 keys
  5. obj 的每个自有属性键 propertyKey,如果 propertyKey 是 Symbol,则按属性创建的升序时间顺序,执行:
    1. propertyKey 追加到 keys
  6. 返回 keys

10.4.5.9 TypedArray With Buffer Witness Records

TypedArray With Buffer Witness Record 是一个 Record 值,用于封装 TypedArray 以及被查看 buffer 的缓存字节长度。它用于帮助确保当被查看 buffer 是可增长 SharedArrayBuffer 时,字节长度数据块只有单个 ReadSharedMemory 事件。

TypedArray With Buffer Witness Records 具有 Table 28 中列出的字段。

Table 28: TypedArray With Buffer Witness Record 字段
字段名 含义
[[Object]] a TypedArray 其 buffer 的字节长度被加载的 TypedArray
[[CachedBufferByteLength]] a non-negative integer or detached 创建该 Record 时对象的 [[ViewedArrayBuffer]] 的字节长度。

10.4.5.10 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. bufferobj.[[ViewedArrayBuffer]]
  2. 如果 IsDetachedBuffer(buffer) 是 true,则
    1. byteLengthdetached
  3. 否则,
    1. byteLengthArrayBufferByteLength(buffer, order)。
  4. 返回 TypedArray With Buffer Witness Record { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength }。

10.4.5.11 TypedArrayCreate ( proto )

The abstract operation TypedArrayCreate takes argument proto (an Object) and returns a TypedArray. 它用于指定新 TypedArrays 的创建。 It performs the following steps when called:

  1. internalSlotsList 为 « [[Prototype]], [[Extensible]], [[ViewedArrayBuffer]], [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], [[ArrayLength]] »。
  2. taMakeBasicObject(internalSlotsList)。
  3. 按照 10.4.5.1 中指定的方式设置 ta.[[PreventExtensions]]
  4. 按照 10.4.5.2 中指定的方式设置 ta.[[GetOwnProperty]]
  5. 按照 10.4.5.3 中指定的方式设置 ta.[[HasProperty]]
  6. 按照 10.4.5.4 中指定的方式设置 ta.[[DefineOwnProperty]]
  7. 按照 10.4.5.5 中指定的方式设置 ta.[[Get]]
  8. 按照 10.4.5.6 中指定的方式设置 ta.[[Set]]
  9. 按照 10.4.5.7 中指定的方式设置 ta.[[Delete]]
  10. 按照 10.4.5.8 中指定的方式设置 ta.[[OwnPropertyKeys]]
  11. ta.[[Prototype]] 设置为 proto
  12. 返回 ta

10.4.5.12 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. 断言:IsTypedArrayOutOfBounds(taRecord) 是 false
  2. objtaRecord.[[Object]]
  3. 如果 obj.[[ByteLength]] 不是 auto,则返回 obj.[[ByteLength]]
  4. lengthTypedArrayLength(taRecord)。
  5. elementSizeTypedArrayElementSize(obj)。
  6. 注:返回的字节长度始终是 elementSize 的整数倍,即使底层 buffer 已被调整为非整数倍。
  7. 返回 length × elementSize

10.4.5.13 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. 断言:IsTypedArrayOutOfBounds(taRecord) 是 false
  2. objtaRecord.[[Object]]
  3. 如果 obj.[[ArrayLength]] 不是 auto,则返回 obj.[[ArrayLength]]
  4. 断言:IsFixedLengthArrayBuffer(obj.[[ViewedArrayBuffer]]) 是 false
  5. byteOffsetobj.[[ByteOffset]]
  6. elementSizeTypedArrayElementSize(obj)。
  7. byteLengthtaRecord.[[CachedBufferByteLength]]
  8. 断言:byteLength 不是 detached
  9. 返回 floor((byteLength - byteOffset) / elementSize)。

10.4.5.14 IsTypedArrayOutOfBounds ( taRecord )

The abstract operation IsTypedArrayOutOfBounds takes argument taRecord (a TypedArray With Buffer Witness Record) and returns a Boolean. 它检查该对象的任何数值属性是否引用了不包含在底层 buffer 边界内的索引处的值。 It performs the following steps when called:

  1. objtaRecord.[[Object]]
  2. bufferByteLengthtaRecord.[[CachedBufferByteLength]]
  3. 如果 IsDetachedBuffer(obj.[[ViewedArrayBuffer]]) 是 true,则
    1. 断言:bufferByteLengthdetached
    2. 返回 true
  4. 断言:bufferByteLength 是非负整数。
  5. byteOffsetStartobj.[[ByteOffset]]
  6. 如果 obj.[[ArrayLength]]auto,则
    1. byteOffsetEndbufferByteLength
  7. 否则,
    1. elementSizeTypedArrayElementSize(obj)。
    2. arrayByteLengthobj.[[ArrayLength]] × elementSize
    3. byteOffsetEndbyteOffsetStart + arrayByteLength
  8. 注:[[ByteOffset]]bufferByteLength 的 0 长度 TypedArray 不被视为越界。
  9. 如果 byteOffsetStart > bufferByteLengthbyteOffsetEnd > bufferByteLength,则返回 true
  10. 返回 false

10.4.5.15 IsTypedArrayFixedLength ( obj )

The abstract operation IsTypedArrayFixedLength takes argument obj (a TypedArray) and returns a Boolean. It performs the following steps when called:

  1. 如果 obj.[[ArrayLength]]auto,则返回 false
  2. bufferobj.[[ViewedArrayBuffer]]
  3. 如果 IsFixedLengthArrayBuffer(buffer) 是 falseIsSharedArrayBuffer(buffer) 是 false,则返回 false
  4. 返回 true

10.4.5.16 IsValidIntegerIndex ( obj, index )

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

  1. 如果 IsDetachedBuffer(obj.[[ViewedArrayBuffer]]) 是 true,则返回 false
  2. 如果 index 不是整数 Number,则返回 false
  3. 如果 index-0𝔽index < -0𝔽,则返回 false
  4. taRecordMakeTypedArrayWithBufferWitnessRecord(obj, unordered)。
  5. 注:当 obj 的后备 buffer 是可增长 SharedArrayBuffer 时,边界检查不是同步操作。
  6. 如果 IsTypedArrayOutOfBounds(taRecord) 是 true,则返回 false
  7. lengthTypedArrayLength(taRecord)。
  8. 如果 (index) ≥ length,则返回 false
  9. 返回 true

10.4.5.17 TypedArrayGetElement ( obj, index )

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

  1. 如果 IsValidIntegerIndex(obj, index) 是 false,则返回 undefined
  2. offsetobj.[[ByteOffset]]
  3. elementSizeTypedArrayElementSize(obj)。
  4. byteIndexInBuffer 为 ((index) × elementSize) + offset
  5. elementTypeTypedArrayElementType(obj)。
  6. 返回 GetValueFromBuffer(obj.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, true, unordered)。

10.4.5.18 TypedArraySetElement ( obj, index, value )

The abstract operation TypedArraySetElement takes arguments obj (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. 如果 obj.[[ContentType]]bigint,则令 number 为 ? ToBigInt(value)。
  2. 否则,令 number 为 ? ToNumber(value)。
  3. 如果 IsValidIntegerIndex(obj, index) 是 true,则
    1. offsetobj.[[ByteOffset]]
    2. elementSizeTypedArrayElementSize(obj)。
    3. byteIndexInBuffer 为 ((index) × elementSize) + offset
    4. elementTypeTypedArrayElementType(obj)。
    5. 执行 SetValueInBuffer(obj.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, number, true, unordered)。
  4. 返回 unused
Note

此操作总是表现为成功,但当尝试写入超过 TypedArray 末尾的位置,或写入由 detached ArrayBuffer 支撑的 TypedArray 时,它没有效果。

10.4.5.19 IsArrayBufferViewOutOfBounds ( obj )

The abstract operation IsArrayBufferViewOutOfBounds takes argument obj (a TypedArray or a DataView) and returns a Boolean. 它检查 TypedArray 的任何数值属性或 DataView 对象的方法是否可以引用不包含在底层数据块边界内的索引处的值。此抽象操作作为上游规范的便利而存在。 It performs the following steps when called:

  1. 如果 obj 具有 [[DataView]] 内部槽,则
    1. viewRecordMakeDataViewWithBufferWitnessRecord(obj, seq-cst)。
    2. 返回 IsViewOutOfBounds(viewRecord)。
  2. taRecordMakeTypedArrayWithBufferWitnessRecord(obj, seq-cst)。
  3. 返回 IsTypedArrayOutOfBounds(taRecord)。

10.4.6 模块命名空间异质对象

模块命名空间异质对象是一种暴露从 ECMAScript Module 导出的绑定的异质对象(参见 16.2.3)。模块命名空间异质对象的 String 键自有属性与 Module 导出的绑定名称之间存在一一对应关系。导出的绑定包括使用 export * 导出项间接导出的任何绑定。每个 String 值自有属性键都是相应导出绑定名称的 StringValue。这些是模块命名空间异质对象仅有的 String 键属性。每个这种属性都具有特性 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }。模块命名空间异质对象不可扩展。

如果一个对象的 [[GetPrototypeOf]][[SetPrototypeOf]][[IsExtensible]][[PreventExtensions]][[GetOwnProperty]][[DefineOwnProperty]][[HasProperty]][[Get]][[Set]][[Delete]][[OwnPropertyKeys]] 内部方法使用本节中的定义,且其其他基本内部方法使用 10.1 中的定义,则该对象是模块命名空间异质对象。这些方法由 ModuleNamespaceCreate 安装。

模块命名空间异质对象具有 Table 29 中定义的内部槽。

Table 29: 模块命名空间异质对象的内部槽
内部槽 类型 描述
[[Module]] a Module Record 此命名空间所暴露导出的 Module Record
[[Exports]] a List of Strings 一个 List,其元素是作为此对象自有属性暴露的导出名称的 String 值。该列表按照词典序代码单元顺序排序。

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. 返回 null

10.4.6.2 [[SetPrototypeOf]] ( proto )

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

  1. 返回 ! SetImmutablePrototype(obj, proto)。

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. 返回 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. 返回 true

10.4.6.5 [[GetOwnProperty]] ( propertyKey )

The [[GetOwnProperty]] internal method of a module namespace exotic object obj takes argument propertyKey (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. 如果 propertyKey 是 Symbol,则返回 OrdinaryGetOwnProperty(obj, propertyKey)。
  2. exportsobj.[[Exports]]
  3. 如果 exports包含 propertyKey,则返回 undefined
  4. value 为 ? obj.[[Get]](propertyKey, obj)。
  5. 返回 PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }。

10.4.6.6 [[DefineOwnProperty]] ( propertyKey, propertyDesc )

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

  1. 如果 propertyKey 是 Symbol,则返回 ! OrdinaryDefineOwnProperty(obj, propertyKey, propertyDesc)。
  2. current 为 ? obj.[[GetOwnProperty]](propertyKey)。
  3. 如果 currentundefined,则返回 false
  4. 如果 propertyDesc 具有 [[Configurable]] 字段且 propertyDesc.[[Configurable]]true,则返回 false
  5. 如果 propertyDesc 具有 [[Enumerable]] 字段且 propertyDesc.[[Enumerable]]false,则返回 false
  6. 如果 IsAccessorDescriptor(propertyDesc) 是 true,则返回 false
  7. 如果 propertyDesc 具有 [[Writable]] 字段且 propertyDesc.[[Writable]]false,则返回 false
  8. 如果 propertyDesc 具有 [[Value]] 字段,则返回 SameValue(propertyDesc.[[Value]], current.[[Value]])。
  9. 返回 true

10.4.6.7 [[HasProperty]] ( propertyKey )

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

  1. 如果 propertyKey 是 Symbol,则返回 ! OrdinaryHasProperty(obj, propertyKey)。
  2. exportsobj.[[Exports]]
  3. 如果 exports 包含 propertyKey,则返回 true
  4. 返回 false

10.4.6.8 [[Get]] ( propertyKey, receiver )

The [[Get]] internal method of a module namespace exotic object obj takes arguments propertyKey (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. 如果 propertyKey 是 Symbol,则
    1. 返回 ! OrdinaryGet(obj, propertyKey, receiver)。
  2. exportsobj.[[Exports]]
  3. 如果 exports包含 propertyKey,则返回 undefined
  4. moduleobj.[[Module]]
  5. bindingmodule.ResolveExport(propertyKey)。
  6. 断言:bindingResolvedBinding Record
  7. targetModulebinding.[[Module]]
  8. 断言:targetModule 不是 undefined
  9. 如果 binding.[[BindingName]]namespace,则
    1. 返回 GetModuleNamespace(targetModule)。
  10. targetEnvtargetModule.[[Environment]]
  11. 如果 targetEnvempty,则抛出 ReferenceError 异常。
  12. 返回 ? targetEnv.GetBindingValue(binding.[[BindingName]], true)。
Note

ResolveExport 无副作用。每次此操作以特定 exportNameresolveSet 对作为实参调用时,它必须返回相同结果。实现可以选择为每个模块命名空间异质对象[[Exports]] 预先计算或缓存 ResolveExport 结果。

10.4.6.9 [[Set]] ( propertyKey, value, receiver )

The [[Set]] internal method of a module namespace exotic object takes arguments propertyKey (a property key), value (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. 返回 false

10.4.6.10 [[Delete]] ( propertyKey )

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

  1. 如果 propertyKey 是 Symbol,则
    1. 返回 ! OrdinaryDelete(obj, propertyKey)。
  2. exportsobj.[[Exports]]
  3. 如果 exports 包含 propertyKey,则返回 false
  4. 返回 true

10.4.6.11 [[OwnPropertyKeys]] ( )

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

  1. exportsobj.[[Exports]]
  2. symbolKeysOrdinaryOwnPropertyKeys(obj)。
  3. 返回 exportssymbolKeys列表连接

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 performs the following steps when called:

  1. 断言:module.[[Namespace]]empty
  2. internalSlotsListTable 29 中列出的内部槽。
  3. namespaceMakeBasicObject(internalSlotsList)。
  4. namespace 的基本内部方法设置为 10.4.6 中指定的定义。
  5. namespace.[[Module]] 设置为 module
  6. sortedExports 为一个 List,其元素是 exports 的元素,按词典序代码单元顺序排序。
  7. namespace.[[Exports]] 设置为 sortedExports
  8. 创建 namespace 的自有属性,对应于 28.3 中的定义。
  9. module.[[Namespace]] 设置为 namespace
  10. 返回 namespace

10.4.7 不可变原型异质对象

不可变原型异质对象是一种异质对象,它具有一个 [[Prototype]] 内部槽,一旦初始化后就不会改变。

如果一个对象的 [[SetPrototypeOf]] 内部方法使用以下实现,则该对象是不可变原型异质对象。(其其他基本内部方法可以使用任何实现,取决于所讨论的具体不可变原型异质对象。)

Note

与其他异质对象不同,没有为不可变原型异质对象提供专门的创建抽象操作。这是因为它们仅由 %Object.prototype%宿主环境使用,并且在宿主环境中,相关对象可能在其他方面也是异质的,因此需要其自身专门的创建操作。

10.4.7.1 [[SetPrototypeOf]] ( proto )

The [[SetPrototypeOf]] internal method of an immutable prototype exotic object obj takes argument proto (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. 返回 ? SetImmutablePrototype(obj, proto)。

10.4.7.2 SetImmutablePrototype ( obj, proto )

The abstract operation SetImmutablePrototype takes arguments obj (an Object) and proto (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. current 为 ? obj.[[GetPrototypeOf]]()
  2. 如果 SameValue(proto, current) 是 true,则返回 true
  3. 返回 false

10.5 Proxy 对象内部方法与内部槽

Proxy 对象是一种异质对象,其基本内部方法部分使用 ECMAScript 代码实现。每个 Proxy 对象都有一个称为 [[ProxyHandler]] 的内部槽。[[ProxyHandler]] 的值是一个对象,称为该 proxy 的handler 对象,或为 null。handler 对象的方法(参见 Table 30)可用于增强 Proxy 对象一个或多个内部方法的实现。每个 Proxy 对象还有一个称为 [[ProxyTarget]] 的内部槽,其值要么是一个对象,要么是 null。此对象称为该 proxy 的target 对象

如果一个对象的基本内部方法(包括 [[Call]][[Construct]],如果适用)使用本节中的定义,则该对象是 Proxy 异质对象。这些内部方法由 ProxyCreate 安装。

Table 30: Proxy Handler 方法
内部方法 Handler 方法
[[GetPrototypeOf]] getPrototypeOf
[[SetPrototypeOf]] setPrototypeOf
[[IsExtensible]] isExtensible
[[PreventExtensions]] preventExtensions
[[GetOwnProperty]] getOwnPropertyDescriptor
[[DefineOwnProperty]] defineProperty
[[HasProperty]] has
[[Get]] get
[[Set]] set
[[Delete]] deleteProperty
[[OwnPropertyKeys]] ownKeys
[[Call]] apply
[[Construct]] construct

当调用 handler 方法以提供 Proxy 对象内部方法的实现时,会将该 proxy 的 target 对象作为形参传递给 handler 方法。proxy 的 handler 对象不一定具有与每个基本内部方法对应的方法。如果 handler 对象没有与内部陷阱对应的方法,则在 proxy 上调用内部方法会导致在该 proxy 的 target 对象上调用对应的内部方法。

Proxy 对象的 [[ProxyHandler]][[ProxyTarget]] 内部槽总是在对象创建时初始化,并且通常不能被修改。有些 Proxy 对象以允许它们随后被撤销的方式创建。当 proxy 被撤销时,其 [[ProxyHandler]][[ProxyTarget]] 内部槽被设置为 null,导致随后在该 Proxy 对象上调用内部方法时抛出 TypeError 异常。

由于 Proxy 对象允许由任意 ECMAScript 代码提供内部方法的实现,因此可以定义其 handler 方法违反 6.1.7.3 中定义的不变量的 Proxy 对象。6.1.7.3 中定义的某些内部方法不变量是基本完整性不变量。这些不变量由本节中指定的 Proxy 对象内部方法显式强制执行。ECMAScript 实现必须能稳健地应对所有可能的不变量违反。

在以下算法描述中,假设 obj 是 ECMAScript Proxy 对象,propertyKey属性键值,value 是任意 ECMAScript 语言值,且 propertyDescProperty Descriptor Record

10.5.1 [[GetPrototypeOf]] ( )

The [[GetPrototypeOf]] internal method of a Proxy exotic object obj takes no arguments and returns either a normal completion containing either an Object or null, or a throw completion. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "getPrototypeOf")。
  6. 如果 trapundefined,则
    1. 返回 ? target.[[GetPrototypeOf]]()
  7. handlerProto 为 ? Call(trap, handler, « target »)。
  8. 如果 handlerProto 不是 Object 且 handlerProto 不是 null,则抛出 TypeError 异常。
  9. extensibleTarget 为 ? IsExtensible(target)。
  10. 如果 extensibleTargettrue,则返回 handlerProto
  11. targetProto 为 ? target.[[GetPrototypeOf]]()
  12. 如果 SameValue(handlerProto, targetProto) 是 false,则抛出 TypeError 异常。
  13. 返回 handlerProto
Note

Proxy 对象的 [[GetPrototypeOf]] 会强制执行以下不变量:

  • [[GetPrototypeOf]] 的结果必须是 Object 或 null
  • 如果 target 对象不可扩展,则应用于 Proxy 对象的 [[GetPrototypeOf]] 必须返回与应用于该 Proxy 对象的 target 对象的 [[GetPrototypeOf]] 相同的值。

10.5.2 [[SetPrototypeOf]] ( proto )

The [[SetPrototypeOf]] internal method of a Proxy exotic object obj takes argument proto (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. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "setPrototypeOf")。
  6. 如果 trapundefined,则
    1. 返回 ? target.[[SetPrototypeOf]](proto)
  7. boolTrapResultToBoolean(? Call(trap, handler, « target, proto »))。
  8. 如果 boolTrapResultfalse,则返回 false
  9. extensibleTarget 为 ? IsExtensible(target)。
  10. 如果 extensibleTargettrue,则返回 true
  11. targetProto 为 ? target.[[GetPrototypeOf]]()
  12. 如果 SameValue(proto, targetProto) 是 false,则抛出 TypeError 异常。
  13. 返回 true
Note

Proxy 对象的 [[SetPrototypeOf]] 会强制执行以下不变量:

  • [[SetPrototypeOf]] 的结果是 Boolean 值。
  • 如果 target 对象不可扩展,则实参值必须与应用于 target 对象的 [[GetPrototypeOf]] 的结果相同。

10.5.3 [[IsExtensible]] ( )

The [[IsExtensible]] internal method of a Proxy exotic object obj takes no arguments and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "isExtensible")。
  6. 如果 trapundefined,则
    1. 返回 ? IsExtensible(target)。
  7. boolTrapResultToBoolean(? Call(trap, handler, « target »))。
  8. targetResult 为 ? IsExtensible(target)。
  9. 如果 boolTrapResult 不是 targetResult,则抛出 TypeError 异常。
  10. 返回 boolTrapResult
Note

Proxy 对象的 [[IsExtensible]] 会强制执行以下不变量:

  • [[IsExtensible]] 的结果是 Boolean 值。
  • 应用于 Proxy 对象的 [[IsExtensible]] 必须返回与以相同实参应用于该 Proxy 对象的 target 对象的 [[IsExtensible]] 相同的值。

10.5.4 [[PreventExtensions]] ( )

The [[PreventExtensions]] internal method of a Proxy exotic object obj takes no arguments and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "preventExtensions")。
  6. 如果 trapundefined,则
    1. 返回 ? target.[[PreventExtensions]]()
  7. boolTrapResultToBoolean(? Call(trap, handler, « target »))。
  8. 如果 boolTrapResulttrue,则
    1. extensibleTarget 为 ? IsExtensible(target)。
    2. 如果 extensibleTargettrue,则抛出 TypeError 异常。
  9. 返回 boolTrapResult
Note

Proxy 对象的 [[PreventExtensions]] 会强制执行以下不变量:

  • [[PreventExtensions]] 的结果是 Boolean 值。
  • 应用于 Proxy 对象的 [[PreventExtensions]] 只有在应用于该 Proxy 对象的 target 对象的 [[IsExtensible]]false 时才会返回 true

10.5.5 [[GetOwnProperty]] ( propertyKey )

The [[GetOwnProperty]] internal method of a Proxy exotic object obj takes argument propertyKey (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. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "getOwnPropertyDescriptor")。
  6. 如果 trapundefined,则
    1. 返回 ? target.[[GetOwnProperty]](propertyKey)
  7. trapResultObj 为 ? Call(trap, handler, « target, propertyKey »)。
  8. 如果 trapResultObj 不是 Object 且 trapResultObj 不是 undefined,则抛出 TypeError 异常。
  9. targetDesc 为 ? target.[[GetOwnProperty]](propertyKey)
  10. 如果 trapResultObjundefined,则
    1. 如果 targetDescundefined,则返回 undefined
    2. 如果 targetDesc.[[Configurable]]false,则抛出 TypeError 异常。
    3. extensibleTarget 为 ? IsExtensible(target)。
    4. 如果 extensibleTargetfalse,则抛出 TypeError 异常。
    5. 返回 undefined
  11. extensibleTarget 为 ? IsExtensible(target)。
  12. resultDesc 为 ? ToPropertyDescriptor(trapResultObj)。
  13. 执行 CompletePropertyDescriptor(resultDesc)。
  14. validIsCompatiblePropertyDescriptor(extensibleTarget, resultDesc, targetDesc)。
  15. 如果 validfalse,则抛出 TypeError 异常。
  16. 如果 resultDesc.[[Configurable]]false,则
    1. 如果 targetDescundefinedtargetDesc.[[Configurable]]true,则
      1. 抛出 TypeError 异常。
    2. 如果 resultDesc 具有 [[Writable]] 字段且 resultDesc.[[Writable]]false,则
      1. 断言:targetDesc 具有 [[Writable]] 字段。
      2. 如果 targetDesc.[[Writable]]true,则抛出 TypeError 异常。
  17. 返回 resultDesc
Note

Proxy 对象的 [[GetOwnProperty]] 会强制执行以下不变量:

  • [[GetOwnProperty]] 的结果必须是 Property Descriptorundefined
  • 如果属性作为 target 对象的不可配置自有属性存在,则不能将该属性报告为不存在。
  • 如果属性作为不可扩展 target 对象的自有属性存在,则不能将该属性报告为不存在。
  • 如果属性不是 target 对象的自有属性且 target 对象不可扩展,则不能将该属性报告为存在。
  • 除非属性作为 target 对象的不可配置自有属性存在,否则不能将该属性报告为不可配置。
  • 除非属性作为 target 对象的不可配置、不可写自有属性存在,否则不能将该属性同时报告为不可配置且不可写。

10.5.6 [[DefineOwnProperty]] ( propertyKey, propertyDesc )

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

  1. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "defineProperty")。
  6. 如果 trapundefined,则
    1. 返回 ? target.[[DefineOwnProperty]](propertyKey, propertyDesc)
  7. propertyDescObjFromPropertyDescriptor(propertyDesc)。
  8. boolTrapResultToBoolean(? Call(trap, handler, « target, propertyKey, propertyDescObj »))。
  9. 如果 boolTrapResultfalse,则返回 false
  10. targetDesc 为 ? target.[[GetOwnProperty]](propertyKey)
  11. extensibleTarget 为 ? IsExtensible(target)。
  12. 如果 propertyDesc 具有 [[Configurable]] 字段且 propertyDesc.[[Configurable]]false,则
    1. settingConfigFalsetrue
  13. 否则,
    1. settingConfigFalsefalse
  14. 如果 targetDescundefined,则
    1. 如果 extensibleTargetfalse,则抛出 TypeError 异常。
    2. 如果 settingConfigFalsetrue,则抛出 TypeError 异常。
  15. 否则,
    1. 如果 IsCompatiblePropertyDescriptor(extensibleTarget, propertyDesc, targetDesc) 是 false,则抛出 TypeError 异常。
    2. 如果 settingConfigFalsetruetargetDesc.[[Configurable]]true,则抛出 TypeError 异常。
    3. 如果 IsDataDescriptor(targetDesc) 是 truetargetDesc.[[Configurable]]false,且 targetDesc.[[Writable]]true,则
      1. 如果 propertyDesc 具有 [[Writable]] 字段且 propertyDesc.[[Writable]]false,则抛出 TypeError 异常。
  16. 返回 true
Note

Proxy 对象的 [[DefineOwnProperty]] 会强制执行以下不变量:

  • [[DefineOwnProperty]] 的结果是 Boolean 值。
  • 如果 target 对象不可扩展,则不能添加属性。
  • 除非 target 对象存在对应的不可配置自有属性,否则属性不能是不可配置的。
  • 除非 target 对象存在对应的不可配置、不可写自有属性,否则不可配置属性不能是不可写的。
  • 如果属性有对应的 target 对象属性,则使用 [[DefineOwnProperty]] 将该属性的 Property Descriptor 应用于 target 对象不会抛出异常。

10.5.7 [[HasProperty]] ( propertyKey )

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

  1. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "has")。
  6. 如果 trapundefined,则
    1. 返回 ? target.[[HasProperty]](propertyKey)
  7. boolTrapResultToBoolean(? Call(trap, handler, « target, propertyKey »))。
  8. 如果 boolTrapResultfalse,则
    1. targetDesc 为 ? target.[[GetOwnProperty]](propertyKey)
    2. 如果 targetDesc 不是 undefined,则
      1. 如果 targetDesc.[[Configurable]]false,则抛出 TypeError 异常。
      2. extensibleTarget 为 ? IsExtensible(target)。
      3. 如果 extensibleTargetfalse,则抛出 TypeError 异常。
  9. 返回 boolTrapResult
Note

Proxy 对象的 [[HasProperty]] 会强制执行以下不变量:

  • [[HasProperty]] 的结果是 Boolean 值。
  • 如果属性作为 target 对象的不可配置自有属性存在,则不能将该属性报告为不存在。
  • 如果属性作为 target 对象的自有属性存在且 target 对象不可扩展,则不能将该属性报告为不存在。

10.5.8 [[Get]] ( propertyKey, receiver )

The [[Get]] internal method of a Proxy exotic object obj takes arguments propertyKey (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. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "get")。
  6. 如果 trapundefined,则
    1. 返回 ? target.[[Get]](propertyKey, receiver)
  7. trapResult 为 ? Call(trap, handler, « target, propertyKey, receiver »)。
  8. targetDesc 为 ? target.[[GetOwnProperty]](propertyKey)
  9. 如果 targetDesc 不是 undefinedtargetDesc.[[Configurable]]false,则
    1. 如果 IsDataDescriptor(targetDesc) 是 truetargetDesc.[[Writable]]false,则
      1. 如果 SameValue(trapResult, targetDesc.[[Value]]) 是 false,则抛出 TypeError 异常。
    2. 如果 IsAccessorDescriptor(targetDesc) 是 truetargetDesc.[[Get]]undefined,则
      1. 如果 trapResult 不是 undefined,则抛出 TypeError 异常。
  10. 返回 trapResult
Note

Proxy 对象的 [[Get]] 会强制执行以下不变量:

  • 如果 target 对象属性是不可写、不可配置的自有数据属性,则为某属性报告的值必须与对应 target 对象属性的值相同。
  • 如果对应的 target 对象属性是不可配置的自有访问器属性,且其 [[Get]] 特性为 undefined,则为某属性报告的值必须是 undefined

10.5.9 [[Set]] ( propertyKey, value, receiver )

The [[Set]] internal method of a Proxy exotic object obj takes arguments propertyKey (a property key), value (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. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "set")。
  6. 如果 trapundefined,则
    1. 返回 ? target.[[Set]](propertyKey, value, receiver)
  7. boolTrapResultToBoolean(? Call(trap, handler, « target, propertyKey, value, receiver »))。
  8. 如果 boolTrapResultfalse,则返回 false
  9. targetDesc 为 ? target.[[GetOwnProperty]](propertyKey)
  10. 如果 targetDesc 不是 undefinedtargetDesc.[[Configurable]]false,则
    1. 如果 IsDataDescriptor(targetDesc) 是 truetargetDesc.[[Writable]]false,则
      1. 如果 SameValue(value, targetDesc.[[Value]]) 是 false,则抛出 TypeError 异常。
    2. 如果 IsAccessorDescriptor(targetDesc) 是 true,则
      1. 如果 targetDesc.[[Set]]undefined,则抛出 TypeError 异常。
  11. 返回 true
Note

Proxy 对象的 [[Set]] 会强制执行以下不变量:

  • [[Set]] 的结果是 Boolean 值。
  • 如果对应的 target 对象属性是不可写、不可配置的自有数据属性,则不能将属性值更改为不同于对应 target 对象属性值的值。
  • 如果对应的 target 对象属性是不可配置的自有访问器属性,且其 [[Set]] 特性为 undefined,则不能设置该属性的值。

10.5.10 [[Delete]] ( propertyKey )

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

  1. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "deleteProperty")。
  6. 如果 trapundefined,则
    1. 返回 ? target.[[Delete]](propertyKey)
  7. boolTrapResultToBoolean(? Call(trap, handler, « target, propertyKey »))。
  8. 如果 boolTrapResultfalse,则返回 false
  9. targetDesc 为 ? target.[[GetOwnProperty]](propertyKey)
  10. 如果 targetDescundefined,则返回 true
  11. 如果 targetDesc.[[Configurable]]false,则抛出 TypeError 异常。
  12. extensibleTarget 为 ? IsExtensible(target)。
  13. 如果 extensibleTargetfalse,则抛出 TypeError 异常。
  14. 返回 true
Note

Proxy 对象的 [[Delete]] 会强制执行以下不变量:

  • [[Delete]] 的结果是 Boolean 值。
  • 如果属性作为 target 对象的不可配置自有属性存在,则不能将该属性报告为已删除。
  • 如果属性作为 target 对象的自有属性存在且 target 对象不可扩展,则不能将该属性报告为已删除。

10.5.11 [[OwnPropertyKeys]] ( )

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

  1. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "ownKeys")。
  6. 如果 trapundefined,则
    1. 返回 ? target.[[OwnPropertyKeys]]()
  7. trapResultArray 为 ? Call(trap, handler, « target »)。
  8. trapResult 为 ? CreateListFromArrayLike(trapResultArray, property-key)。
  9. 如果 trapResult 包含任何重复项,则抛出 TypeError 异常。
  10. extensibleTarget 为 ? IsExtensible(target)。
  11. targetKeys 为 ? target.[[OwnPropertyKeys]]()
  12. 断言:targetKeys属性键List
  13. 断言:targetKeys包含重复项。
  14. targetConfigurableKeys 为新的空 List
  15. targetNonconfigurableKeys 为新的空 List
  16. targetKeys 的每个元素 key,执行:
    1. propertyDesc 为 ? target.[[GetOwnProperty]](key)
    2. 如果 propertyDesc 不是 undefinedpropertyDesc.[[Configurable]]false,则
      1. key 追加到 targetNonconfigurableKeys
    3. 否则,
      1. key 追加到 targetConfigurableKeys
  17. 如果 extensibleTargettruetargetNonconfigurableKeys 为空,则
    1. 返回 trapResult
  18. uncheckedResultKeys 为一个 List,其元素是 trapResult 的元素。
  19. targetNonconfigurableKeys 的每个元素 key,执行:
    1. 如果 uncheckedResultKeys包含 key,则抛出 TypeError 异常。
    2. uncheckedResultKeys 中移除 key
  20. 如果 extensibleTargettrue,则返回 trapResult
  21. targetConfigurableKeys 的每个元素 key,执行:
    1. 如果 uncheckedResultKeys包含 key,则抛出 TypeError 异常。
    2. uncheckedResultKeys 中移除 key
  22. 如果 uncheckedResultKeys 不为空,则抛出 TypeError 异常。
  23. 返回 trapResult
Note

Proxy 对象的 [[OwnPropertyKeys]] 会强制执行以下不变量:

  • [[OwnPropertyKeys]] 的结果是 List
  • 返回的 List包含重复项。
  • 返回的 List 的每个元素都是属性键
  • 结果 List 必须包含 target 对象所有不可配置自有属性的键。
  • 如果 target 对象不可扩展,则结果 List 必须包含 target 对象自有属性的所有键,且不包含其他值。

10.5.12 [[Call]] ( thisArg, argList )

The [[Call]] internal method of a Proxy exotic object obj takes arguments thisArg (an ECMAScript language value) and argList (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. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. handlerobj.[[ProxyHandler]]
  4. 断言:handler 是 Object。
  5. trap 为 ? GetMethod(handler, "apply")。
  6. 如果 trapundefined,则
    1. 返回 ? Call(target, thisArg, argList)。
  7. argArrayCreateArrayFromList(argList)。
  8. 返回 ? Call(trap, handler, « target, thisArg, argArray »)。
Note

只有当 Proxy 异质对象[[ProxyTarget]] 内部槽的初始值是具有 [[Call]] 内部方法的对象时,该 Proxy 异质对象才具有 [[Call]] 内部方法。

10.5.13 [[Construct]] ( argList, newTarget )

The [[Construct]] internal method of a Proxy exotic object obj takes arguments argList (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. 执行 ? ValidateNonRevokedProxy(obj)。
  2. targetobj.[[ProxyTarget]]
  3. 断言:IsConstructor(target) 是 true
  4. handlerobj.[[ProxyHandler]]
  5. 断言:handler 是 Object。
  6. trap 为 ? GetMethod(handler, "construct")。
  7. 如果 trapundefined,则
    1. 返回 ? Construct(target, argList, newTarget)。
  8. argArrayCreateArrayFromList(argList)。
  9. newObj 为 ? Call(trap, handler, « target, argArray, newTarget »)。
  10. 如果 newObj 不是 Object,则抛出 TypeError 异常。
  11. 返回 newObj
Note 1

只有当 Proxy 异质对象[[ProxyTarget]] 内部槽的初始值是具有 [[Construct]] 内部方法的对象时,该 Proxy 异质对象才具有 [[Construct]] 内部方法。

Note 2

Proxy 对象的 [[Construct]] 会强制执行以下不变量:

  • [[Construct]] 的结果必须是 Object。

10.5.14 ValidateNonRevokedProxy ( proxy )

The abstract operation ValidateNonRevokedProxy takes argument proxy (a Proxy exotic object) and returns either a normal completion containing unused or a throw completion. 如果 proxy 已被撤销,它会抛出 TypeError 异常。 It performs the following steps when called:

  1. 如果 proxy.[[ProxyTarget]]null,则抛出 TypeError 异常。
  2. 断言:proxy.[[ProxyHandler]] 不是 null
  3. 返回 unused

10.5.15 ProxyCreate ( target, handler )

The abstract operation ProxyCreate takes arguments target (an ECMAScript language value) and handler (an ECMAScript language value) and returns either a normal completion containing a Proxy exotic object or a throw completion. 它用于指定新 Proxy 对象的创建。 It performs the following steps when called:

  1. 如果 target 不是 Object,则抛出 TypeError 异常。
  2. 如果 handler 不是 Object,则抛出 TypeError 异常。
  3. proxyMakeBasicObject[[ProxyHandler]], [[ProxyTarget]] »)。
  4. proxy 的基本内部方法([[Call]][[Construct]] 除外)设置为 10.5 中指定的定义。
  5. 如果 IsCallable(target) 是 true,则
    1. 按照 10.5.12 中指定的方式设置 proxy.[[Call]]
    2. 如果 IsConstructor(target) 是 true,则
      1. 按照 10.5.13 中指定的方式设置 proxy.[[Construct]]
  6. proxy.[[ProxyTarget]] 设置为 target
  7. proxy.[[ProxyHandler]] 设置为 handler
  8. 返回 proxy