10 普通与特异(Exotic)对象的行为 (Ordinary and Exotic Objects Behaviours)

10.1 普通对象的内部方法与内部槽 (Ordinary Object Internal Methods and Internal Slots)

所有普通对象都有名为 [[Prototype]] 的内部槽。该内部槽的值要么是 null 要么是一个对象,用于实现继承。假设一个名为 P 的属性在普通对象 O 上缺失,但存在于其 [[Prototype]] 对象上。如果 P 指向 [[Prototype]] 对象上的数据属性,则 O 在“取值”访问(get access)时继承它,使其表现得仿佛 PO 的一个属性。如果 P 指向 [[Prototype]] 对象上的可写数据属性,在 O 上对 P 进行“设值”访问(set access)会在 O 上创建一个名为 P 的新数据属性。如果 P 指向 [[Prototype]] 对象上的不可写数据属性,在 O 上对 P 的设值访问会失败。如果 P 指向 [[Prototype]] 对象上的访问器属性(accessor property),则该访问器在 O 上同时被继承用于 get 与 set 访问。

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

在下面的算法描述中,假设 O 是一个普通对象P 是一个属性键值,V 是任意 ECMAScript 语言值Desc 是一个 Property Descriptor 记录。

每个普通对象内部方法委派给一个同名的抽象操作。如果该抽象操作依赖另一个内部方法,那么会在 O 上调用该内部方法,而不是直接调用同名的抽象操作。这些语义确保当普通对象的内部方法应用到特异(exotic)对象时,被重写的内部方法能够被调用。

10.1.1 [[GetPrototypeOf]] ( )

The [[GetPrototypeOf]] internal method of 一个普通对象 O takes no arguments and returns 一个正常完成,包含一个 Object 或 null. It performs the following steps when called:

  1. 返回 OrdinaryGetPrototypeOf(O)。

10.1.1.1 OrdinaryGetPrototypeOf ( O )

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

  1. 返回 O.[[Prototype]]

10.1.2 [[SetPrototypeOf]] ( V )

The [[SetPrototypeOf]] internal method of 一个普通对象 O takes argument V (an Object or null) and returns 一个正常完成,包含一个 Boolean. It performs the following steps when called:

  1. 返回 OrdinarySetPrototypeOf(O, V)。

10.1.2.1 OrdinarySetPrototypeOf ( O, V )

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

  1. currentO.[[Prototype]]
  2. SameValue(V, current) 为 true,返回 true
  3. extensibleO.[[Extensible]]
  4. extensiblefalse,返回 false
  5. pV
  6. donefalse
  7. donefalse 重复,
    1. pnull,则
      1. donetrue
    2. 否则若 SameValue(p, O) 为 true,则
      1. 返回 false
    3. 否则,
      1. p.[[GetPrototypeOf]] 不是 10.1.1 中定义的普通对象内部方法,设 donetrue
      2. 否则,将 p 设为 p.[[Prototype]]
  8. O.[[Prototype]]V
  9. 返回 true
Note

步骤 7 中的循环保证:任何仅包含使用普通对象定义之 [[GetPrototypeOf]][[SetPrototypeOf]] 的对象的原型链中不会出现循环。

10.1.3 [[IsExtensible]] ( )

The [[IsExtensible]] internal method of 一个普通对象 O takes no arguments and returns 一个正常完成,包含一个 Boolean. It performs the following steps when called:

  1. 返回 OrdinaryIsExtensible(O)。

10.1.3.1 OrdinaryIsExtensible ( O )

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

  1. 返回 O.[[Extensible]]

10.1.4 [[PreventExtensions]] ( )

The [[PreventExtensions]] internal method of 一个普通对象 O takes no arguments and returns 一个正常完成,包含 true. It performs the following steps when called:

  1. 返回 OrdinaryPreventExtensions(O)。

10.1.4.1 OrdinaryPreventExtensions ( O )

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

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

10.1.5 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of 一个普通对象 O takes argument P (a property key) and returns 一个正常完成,包含一个 Property Descriptorundefined. It performs the following steps when called:

  1. 返回 OrdinaryGetOwnProperty(O, P)。

10.1.5.1 OrdinaryGetOwnProperty ( O, P )

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

  1. O 不存在键为 P 的自身属性,返回 undefined
  2. D 为一个新建的无字段 Property Descriptor
  3. XO 的键为 P 的自身属性。
  4. X数据属性,则
    1. D.[[Value]]X[[Value]] 特性的值。
    2. D.[[Writable]]X[[Writable]] 特性的值。
  5. 否则,
    1. 断言:X访问器属性
    2. D.[[Get]]X[[Get]] 特性的值。
    3. D.[[Set]]X[[Set]] 特性的值。
  6. D.[[Enumerable]]X[[Enumerable]] 特性的值。
  7. D.[[Configurable]]X[[Configurable]] 特性的值。
  8. 返回 D

10.1.6 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of 一个普通对象 O takes arguments P (a property key) and Desc (a Property Descriptor) and returns 一个正常完成(包含 Boolean)或一个抛出完成. It performs the following steps when called:

  1. 返回 ? OrdinaryDefineOwnProperty(O, P, Desc)。

10.1.6.1 OrdinaryDefineOwnProperty ( O, P, Desc )

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

  1. current 为 ? O.[[GetOwnProperty]](P)。
  2. extensible 为 ? IsExtensible(O)。
  3. 返回 ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current)。

10.1.6.2 IsCompatiblePropertyDescriptor ( Extensible, Desc, Current )

The abstract operation IsCompatiblePropertyDescriptor takes arguments Extensible (a Boolean), Desc (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, Desc, Current)。

10.1.6.3 ValidateAndApplyPropertyDescriptor ( O, P, extensible, Desc, current )

The abstract operation ValidateAndApplyPropertyDescriptor takes arguments O (an Object or undefined), P (a property key), extensible (a Boolean), Desc (a Property Descriptor), and current (a Property Descriptor or undefined) and returns a Boolean. 当且仅当 Desc 可以在指定 extensibility 与当前属性 current 的条件下,作为某对象的属性(维护 不变式)被应用时,返回 true。当应用可行且 O 不为 undefined 时,会对名为 P 的属性执行(必要时创建)。 It performs the following steps when called:

  1. 断言:P 是一个属性键
  2. currentundefined,则
    1. extensiblefalse,返回 false
    2. Oundefined,返回 true
    3. IsAccessorDescriptor(Desc) 为 true,则
      1. 在对象 O 上创建名为 P 的自身访问器属性,其 [[Get]][[Set]][[Enumerable]][[Configurable]] 特性若 Desc 含该字段则取其值,否则取该特性的 默认值
    4. 否则,
      1. 在对象 O 上创建名为 P 的自身数据属性,其 [[Value]][[Writable]][[Enumerable]][[Configurable]] 特性若 Desc 含该字段则取其值,否则取该特性的 默认值
    5. 返回 true
  3. 断言:current 为一个完全填充的 Property Descriptor
  4. Desc 不含任何字段,返回 true
  5. current.[[Configurable]]false,则
    1. Desc[[Configurable]]Desc.[[Configurable]]true,返回 false
    2. Desc[[Enumerable]]Desc.[[Enumerable]] 不等于 current.[[Enumerable]],返回 false
    3. IsGenericDescriptor(Desc) 为 falseIsAccessorDescriptor(Desc) 不等于 IsAccessorDescriptor(current),返回 false
    4. IsAccessorDescriptor(current) 为 true,则
      1. Desc[[Get]]SameValue(Desc.[[Get]], current.[[Get]]) 为 false,返回 false
      2. Desc[[Set]]SameValue(Desc.[[Set]], current.[[Set]]) 为 false,返回 false
    5. 否则若 current.[[Writable]]false,则
      1. Desc[[Writable]]Desc.[[Writable]]true,返回 false
      2. NOTE: SameValueNaN 返回 true(可能通过其他方式区分)。此处返回可确保 O 任何已有属性保持不变。
      3. Desc[[Value]] 字段,返回 SameValue(Desc.[[Value]], current.[[Value]])。
  6. O 不为 undefined,则
    1. IsDataDescriptor(current) 为 trueIsAccessorDescriptor(Desc) 为 true,则
      1. Desc[[Configurable]],令 configurableDesc.[[Configurable]];否则令 configurablecurrent.[[Configurable]]
      2. Desc[[Enumerable]],令 enumerableDesc.[[Enumerable]];否则令 enumerablecurrent.[[Enumerable]]
      3. 用一个访问器属性替换对象 O 上名为 P 的属性,其 [[Configurable]][[Enumerable]] 分别设为 configurableenumerable,其 [[Get]][[Set]] 特性若 Desc 含该字段则取其值,否则取该特性的 默认值
    2. 否则若 IsAccessorDescriptor(current) 为 trueIsDataDescriptor(Desc) 为 true,则
      1. Desc[[Configurable]],令 configurableDesc.[[Configurable]];否则令 configurablecurrent.[[Configurable]]
      2. Desc[[Enumerable]],令 enumerableDesc.[[Enumerable]];否则令 enumerablecurrent.[[Enumerable]]
      3. 用一个数据属性替换对象 O 上名为 P 的属性,其 [[Configurable]][[Enumerable]] 分别设为 configurableenumerable,其 [[Value]][[Writable]] 特性若 Desc 含该字段则取其值,否则取该特性的 默认值
    3. 否则,
      1. Desc 的每个字段,将对象 O 上名为 P 的属性对应特性设为该字段的值。
  7. 返回 true

10.1.7 [[HasProperty]] ( P )

The [[HasProperty]] internal method of 一个普通对象 O takes argument P (a property key) and returns 一个正常完成(包含 Boolean)或一个抛出完成. It performs the following steps when called:

  1. 返回 ? OrdinaryHasProperty(O, P)。

10.1.7.1 OrdinaryHasProperty ( O, P )

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

  1. hasOwn 为 ? O.[[GetOwnProperty]](P)。
  2. hasOwn 不为 undefined,返回 true
  3. parent 为 ? O.[[GetPrototypeOf]]()。
  4. parent 不为 null,则
    1. 返回 ? parent.[[HasProperty]](P)。
  5. 返回 false

10.1.8 [[Get]] ( P, Receiver )

The [[Get]] internal method of 一个普通对象 O takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns 一个正常完成(包含 ECMAScript 语言值)或一个抛出完成. It performs the following steps when called:

  1. 返回 ? OrdinaryGet(O, P, Receiver)。

10.1.8.1 OrdinaryGet ( O, P, Receiver )

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

  1. desc 为 ? O.[[GetOwnProperty]](P)。
  2. descundefined,则
    1. parent 为 ? O.[[GetPrototypeOf]]()。
    2. parentnull,返回 undefined
    3. 返回 ? parent.[[Get]](P, Receiver)。
  3. IsDataDescriptor(desc) 为 true,返回 desc.[[Value]]
  4. 断言:IsAccessorDescriptor(desc) 为 true
  5. getterdesc.[[Get]]
  6. getterundefined,返回 undefined
  7. 返回 ? Call(getter, Receiver)。

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

The [[Set]] internal method of 一个普通对象 O takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns 一个正常完成(包含 Boolean)或一个抛出完成. It performs the following steps when called:

  1. 返回 ? OrdinarySet(O, P, V, Receiver)。

10.1.9.1 OrdinarySet ( O, P, V, Receiver )

The abstract operation OrdinarySet takes arguments O (an Object), P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. ownDesc 为 ? O.[[GetOwnProperty]](P)。
  2. 返回 ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc)。

10.1.9.2 OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc )

The abstract operation OrdinarySetWithOwnDescriptor takes arguments O (an Object), P (a property key), V (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 为 ? O.[[GetPrototypeOf]]()。
    2. parent 不为 null,则
      1. 返回 ? parent.[[Set]](P, V, Receiver)。
    3. 否则,
      1. ownDesc 设为 PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }。
  2. IsDataDescriptor(ownDesc) 为 true,则
    1. ownDesc.[[Writable]]false,返回 false
    2. Receiver 不是 Object,返回 false
    3. existingDescriptor 为 ? Receiver.[[GetOwnProperty]](P)。
    4. existingDescriptor 不为 undefined,则
      1. IsAccessorDescriptor(existingDescriptor) 为 true,返回 false
      2. existingDescriptor.[[Writable]]false,返回 false
      3. valueDesc 为 PropertyDescriptor { [[Value]]: V }。
      4. 返回 ? Receiver.[[DefineOwnProperty]](P, valueDesc)。
    5. 否则,
      1. 断言:Receiver 目前没有属性 P
      2. 返回 ? CreateDataProperty(Receiver, P, V)。
  3. 断言:IsAccessorDescriptor(ownDesc) 为 true
  4. setterownDesc.[[Set]]
  5. setterundefined,返回 false
  6. 执行 ? Call(setter, Receiver, « V »)。
  7. 返回 true

10.1.10 [[Delete]] ( P )

The [[Delete]] internal method of 一个普通对象 O takes argument P (a property key) and returns 一个正常完成(包含 Boolean)或一个抛出完成. It performs the following steps when called:

  1. 返回 ? OrdinaryDelete(O, P)。

10.1.10.1 OrdinaryDelete ( O, P )

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

  1. desc 为 ? O.[[GetOwnProperty]](P)。
  2. descundefined,返回 true
  3. desc.[[Configurable]]true,则
    1. O 中移除名为 P 的自身属性。
    2. 返回 true
  4. 返回 false

10.1.11 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of 一个普通对象 O takes no arguments and returns 一个正常完成,包含一个属性键 List. It performs the following steps when called:

  1. 返回 OrdinaryOwnPropertyKeys(O)。

10.1.11.1 OrdinaryOwnPropertyKeys ( O )

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

  1. keys 为一个新的空 List
  2. O 的每个自身属性键 P,若 P数组索引,按数字索引升序:
    1. P 追加至 keys
  3. O 的每个自身属性键 P,若 P 是 String 且不是数组索引,按属性创建的时间顺序:
    1. P 追加至 keys
  4. O 的每个自身属性键 P,若 P 是 Symbol,按属性创建时间顺序:
    1. P 追加至 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. OMakeBasicObject(internalSlotsList)。
  4. O.[[Prototype]] 设为 proto
  5. 返回 O
Note

尽管 OrdinaryObjectCreate 除调用 MakeBasicObject 外做的事情很少,使用它明确传达了要创建一个“普通”对象而非特异对象的意图。因此,在本规范中,它不会被任何随后修改对象内部方法、从而使结果变为“非普通”的算法调用。创建特异对象的操作会直接调用 MakeBasicObject

10.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )

The abstract operation OrdinaryCreateFromConstructor takes arguments constructor (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(constructor, intrinsicDefaultProto)。
  3. internalSlotsList 存在,令 slotsListinternalSlotsList
  4. 否则,令 slotsList 为一个新的空 List
  5. 返回 OrdinaryObjectCreate(proto, slotsList)。

10.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )

The abstract operation GetPrototypeFromConstructor takes arguments constructor (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(constructor, "prototype")。
  3. proto 不是 Object,则
    1. realm 为 ? GetFunctionRealm(constructor)。
    2. proto 设为 realm 中名为 intrinsicDefaultProto 的内在对象。
  4. 返回 proto
Note

constructor 未提供 [[Prototype]] 值,则使用的默认值取自 constructor 函数所属的 realm,而非当前运行执行上下文。

10.1.15 RequireInternalSlot ( O, internalSlot )

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

  1. O 不是 Object,抛出 TypeError 异常。
  2. O 不具有内部槽 internalSlot,抛出 TypeError 异常。
  3. 返回 unused

10.2 ECMAScript 函数对象 (ECMAScript Function Objects)

ECMAScript 函数对象封装了带参数的、闭包于某词法环境之上的 ECMAScript 代码,并支持对该代码的动态求值。一个 ECMAScript 函数对象是一个普通对象,具有与其它普通对象相同的内部槽与内部方法。ECMAScript 函数对象的代码可以是严格模式代码(11.2.2)或非严格代码。其代码为严格模式代码的 ECMAScript 函数对象称为 严格函数 (strict function)。其代码不是严格模式代码的称为 非严格函数 (non-strict function)

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

Table 28: ECMAScript 函数对象的内部槽 (Internal Slots of ECMAScript Function Objects)
内部槽 (Internal Slot) 类型 (Type) 描述 (Description)
[[Environment]] an Environment Record 函数闭包所捕获的 Environment Record。作为求值该函数代码时的外层环境。
[[PrivateEnvironment]] a PrivateEnvironment Record or null 函数闭包所捕获的 Private NamesPrivateEnvironment Record。若函数在语法上不被包含于 class 内则为 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 若函数使用 super,此槽为其 super 属性查找起始的对象(通过该对象的 [[GetPrototypeOf]])。
[[SourceText]] a sequence of Unicode code points 定义该函数的源文本
[[Fields]] a List of ClassFieldDefinition Records 若该函数是一个 class,则此列表为该类的非静态字段及其初始化器的记录。
[[PrivateMethods]] a List of PrivateElements 若该函数是一个 class,则此列表表示该类的非静态私有方法与访问器。
[[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]] ( thisArgument, argumentsList )

The [[Call]] internal method of 一个 ECMAScript 函数对象 F takes arguments thisArgument (an ECMAScript language value) and argumentsList (a List of ECMAScript language values) and returns 一个正常完成(包含 ECMAScript 语言值)或一个抛出完成. It performs the following steps when called:

  1. callerContext 为当前运行执行上下文。
  2. calleeContextPrepareForOrdinaryCall(F, undefined)。
  3. 断言:calleeContext 现在是运行执行上下文。
  4. F.[[IsClassConstructor]]true,则
    1. error 为一个新创建的 TypeError 对象。
    2. NOTE: errorcalleeContext 中、使用 F 关联的 Realm Record 创建。
    3. 从执行上下文栈移除 calleeContext 并恢复 callerContext 为运行执行上下文。
    4. 返回 ThrowCompletion(error)。
  5. 执行 OrdinaryCallBindThis(F, calleeContext, thisArgument)。
  6. resultCompletion(OrdinaryCallEvaluateBody(F, argumentsList))。
  7. 从执行上下文栈移除 calleeContext 并恢复 callerContext 为运行执行上下文。
  8. result 是一个 return completion,返回 result.[[Value]]
  9. 断言:result 是一个 throw completion。
  10. 返回 ? result
Note

当在步骤 7 中把 calleeContext 自执行上下文栈移除时,若它被一个可访问的 Generator 挂起并保留以供后续恢复,则不得销毁它。

10.2.1.1 PrepareForOrdinaryCall ( F, newTarget )

The abstract operation PrepareForOrdinaryCall takes arguments F (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 设为 F
  4. calleeRealmF.[[Realm]]
  5. calleeContextRealm 设为 calleeRealm
  6. calleeContext 的 ScriptOrModule 设为 F.[[ScriptOrModule]]
  7. localEnvNewFunctionEnvironment(F, newTarget)。
  8. calleeContext 的 LexicalEnvironment 设为 localEnv
  9. calleeContext 的 VariableEnvironment 设为 localEnv
  10. calleeContext 的 PrivateEnvironment 设为 F.[[PrivateEnvironment]]
  11. callerContext 尚未被挂起,则挂起 callerContext
  12. calleeContext 压入执行上下文栈;calleeContext 现在是运行执行上下文。
  13. NOTE: 之后产生的任何异常对象与 calleeRealm 关联。
  14. 返回 calleeContext

10.2.1.2 OrdinaryCallBindThis ( F, calleeContext, thisArgument )

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

  1. thisModeF.[[ThisMode]]
  2. thisModelexical,返回 unused
  3. calleeRealmF.[[Realm]]
  4. localEnvcalleeContext 的 LexicalEnvironment。
  5. thisModestrict,则
    1. thisValuethisArgument
  6. 否则,
    1. thisArgumentundefinednull,则
      1. globalEnvcalleeRealm.[[GlobalEnv]]
      2. 断言:globalEnv 是一个 Global Environment Record
      3. thisValueglobalEnv.[[GlobalThisValue]]
    2. 否则,
      1. thisValue 为 ! ToObject(thisArgument)。
      2. NOTE: ToObject 使用 calleeRealm 产生包装对象。
  7. 断言:localEnv 是一个 Function Environment Record
  8. 断言:下一步不会返回一个 abrupt completion,因为 localEnv.[[ThisBindingStatus]] 不是 initialized
  9. 执行 ! BindThisValue(localEnv, thisValue)。
  10. 返回 unused

10.2.1.3 运行时语义:EvaluateBody

The syntax-directed operation 运行时语义:EvaluateBody takes arguments functionObject (an ECMAScript function object) and argumentsList (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. Return ? EvaluateFunctionBody of FunctionBody with arguments functionObject and argumentsList.
ConciseBody : ExpressionBody
  1. Return ? EvaluateConciseBody of ConciseBody with arguments functionObject and argumentsList.
GeneratorBody : FunctionBody
  1. Return ? EvaluateGeneratorBody of GeneratorBody with arguments functionObject and argumentsList.
AsyncGeneratorBody : FunctionBody
  1. Return ? EvaluateAsyncGeneratorBody of AsyncGeneratorBody with arguments functionObject and argumentsList.
AsyncFunctionBody : FunctionBody
  1. Return ? EvaluateAsyncFunctionBody of AsyncFunctionBody with arguments functionObject and argumentsList.
AsyncConciseBody : ExpressionBody
  1. Return ? EvaluateAsyncConciseBody of AsyncConciseBody with arguments functionObject and argumentsList.
Initializer : = AssignmentExpression
  1. Assert: argumentsList is empty.
  2. Assert: functionObject.[[ClassFieldInitializerName]] is not empty.
  3. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let value be ? NamedEvaluation of Initializer with argument functionObject.[[ClassFieldInitializerName]].
  4. Else,
    1. Let rhs be ? Evaluation of AssignmentExpression.
    2. Let value be ? GetValue(rhs).
  5. Return ReturnCompletion(value).
Note

尽管字段初始化器构成了函数边界,调用 FunctionDeclarationInstantiation 没有可观察效果,因此省略。

ClassStaticBlockBody : ClassStaticBlockStatementList
  1. Assert: argumentsList is empty.
  2. Return ? EvaluateClassStaticBlockBody of ClassStaticBlockBody with argument functionObject.

10.2.1.4 OrdinaryCallEvaluateBody ( F, argumentsList )

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

  1. Return ? EvaluateBody of F.[[ECMAScriptCode]] with arguments F and argumentsList.

10.2.2 [[Construct]] ( argumentsList, newTarget )

The [[Construct]] internal method of 一个 ECMAScript 函数对象 F takes arguments argumentsList (a List of ECMAScript language values) and newTarget (a constructor) and returns 一个正常完成(包含 Object)或一个抛出完成. It performs the following steps when called:

  1. callerContext 为当前运行执行上下文。
  2. kindF.[[ConstructorKind]]
  3. kindbase,则
    1. thisArgument 为 ? OrdinaryCreateFromConstructor(newTarget, "%Object.prototype%")。
  4. calleeContextPrepareForOrdinaryCall(F, newTarget)。
  5. 断言:calleeContext 现在是运行执行上下文。
  6. kindbase,则
    1. 执行 OrdinaryCallBindThis(F, calleeContext, thisArgument)。
    2. initializeResultCompletion(InitializeInstanceElements(thisArgument, F))。
    3. initializeResult 是一个 abrupt completion,则
      1. 从执行上下文栈移除 calleeContext 并恢复 callerContext 为运行执行上下文。
      2. 返回 ? initializeResult
  7. constructorEnvcalleeContext 的 LexicalEnvironment。
  8. resultCompletion(OrdinaryCallEvaluateBody(F, argumentsList))。
  9. 从执行上下文栈移除 calleeContext 并恢复 callerContext 为运行执行上下文。
  10. result 是一个 throw completion,则
    1. 返回 ? result
  11. 断言:result 是一个 return completion。
  12. result.[[Value]] 是一个 Object,返回 result.[[Value]]
  13. kindbase,返回 thisArgument
  14. result.[[Value]] 不是 undefined,抛出 TypeError 异常。
  15. thisBinding 为 ? constructorEnv.GetThisBinding()。
  16. 断言:thisBinding 是一个 Object。
  17. 返回 thisBinding

10.2.3 OrdinaryFunctionCreate ( functionPrototype, sourceText, ParameterList, Body, thisMode, env, privateEnv )

The abstract operation OrdinaryFunctionCreate takes arguments functionPrototype (an Object), sourceText (a sequence of Unicode code points), ParameterList (a Parse Node), Body (a Parse Node), thisMode (lexical-this or non-lexical-this), env (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 28 中列出的内部槽。
  2. FOrdinaryObjectCreate(functionPrototype, internalSlotsList)。
  3. F.[[Call]] 设为 10.2.1 中指定的定义。
  4. F.[[SourceText]] 设为 sourceText
  5. F.[[FormalParameters]] 设为 ParameterList
  6. F.[[ECMAScriptCode]] 设为 Body
  7. Strict 为 IsStrict(Body)。
  8. F.[[Strict]] 设为 Strict
  9. thisModelexical-this,将 F.[[ThisMode]] 设为 lexical
  10. 否则若 Stricttrue,将 F.[[ThisMode]] 设为 strict
  11. 否则,将 F.[[ThisMode]] 设为 global
  12. F.[[IsClassConstructor]] 设为 false
  13. F.[[Environment]] 设为 env
  14. F.[[PrivateEnvironment]] 设为 privateEnv
  15. F.[[ScriptOrModule]] 设为 GetActiveScriptOrModule()。
  16. F.[[Realm]] 设为当前 Realm Record
  17. F.[[HomeObject]] 设为 undefined
  18. F.[[Fields]] 设为一个新的空 List
  19. F.[[PrivateMethods]] 设为一个新的空 List
  20. F.[[ClassFieldInitializerName]] 设为 empty
  21. lenParameterList 的 ExpectedArgumentCount。
  22. 执行 SetFunctionLength(F, len)。
  23. 返回 F

10.2.4 AddRestrictedFunctionProperties ( F, realm )

The abstract operation AddRestrictedFunctionProperties takes arguments F (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(F, "caller", PropertyDescriptor { [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true })。
  4. 执行 ! DefinePropertyOrThrow(F, "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 ( F [ , writablePrototype [ , prototype ] ] )

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

  1. F 是 ECMAScript 函数对象,则
    1. 断言:IsConstructor(F) 为 false
    2. 断言:F 是一个可扩展对象且无 "prototype" 自身属性。
    3. F.[[Construct]] 设为 10.2.2 中指定的定义。
  2. 否则,
    1. F.[[Construct]] 设为 10.3.2 中指定的定义。
  3. F.[[ConstructorKind]] 设为 base
  4. 若未提供 writablePrototype,将 writablePrototype 设为 true
  5. 若未提供 prototype,则
    1. prototype 设为 OrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! DefinePropertyOrThrow(prototype, "constructor", PropertyDescriptor { [[Value]]: F, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: true })。
  6. 执行 ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: false })。
  7. 返回 unused

10.2.6 MakeClassConstructor ( F )

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

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

10.2.7 MakeMethod ( F, homeObject )

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

  1. 断言:homeObject 是一个普通对象
  2. F.[[HomeObject]] 设为 homeObject
  3. 返回 unused

10.2.8 DefineMethodProperty ( homeObject, key, closure, enumerable )

The abstract operation DefineMethodProperty takes arguments homeObject (an Object), key (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. 断言:homeObject 是一个普通、可扩展对象。
  2. key 是一个 Private Name,则
    1. 返回 PrivateElement { [[Key]]: key, [[Kind]]: method, [[Value]]: closure }。
  3. 否则,
    1. desc 为 PropertyDescriptor { [[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true }。
    2. 执行 ? DefinePropertyOrThrow(homeObject, key, desc)。
    3. NOTE: DefinePropertyOrThrow 只有在尝试定义 key"prototype" 的类静态方法时才会返回一个 abrupt completion。
    4. 返回 unused

10.2.9 SetFunctionName ( F, name [ , prefix ] )

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

  1. 断言:F 是一个可扩展对象,且没有 "name" 自身属性。
  2. name 是一个 Symbol,则
    1. descriptionname.[[Description]]
    2. descriptionundefined,将 name 设为空字符串。
    3. 否则,将 name 设为 "["description" ]" 的字符串连接。
  3. 否则若 name 是一个 Private Name,则
    1. name 设为 name.[[Description]]
  4. F 具有 [[InitialName]] 内部槽,则
    1. F.[[InitialName]] 设为 name
  5. 若提供了 prefix,则
    1. name 设为 prefix、代码单元 0x0020 (SPACE)、name 的字符串连接。
    2. F 具有 [[InitialName]] 内部槽,则
      1. NOTE: 下述步骤中的选择在本抽象操作每次执行时独立决定。
      2. 可选地,将 F.[[InitialName]] 设为 name
  6. 执行 ! DefinePropertyOrThrow(F, "name", PropertyDescriptor { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true })。
  7. 返回 unused

10.2.10 SetFunctionLength ( F, length )

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

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

10.2.11 FunctionDeclarationInstantiation ( func, argumentsList )

The abstract operation FunctionDeclarationInstantiation takes arguments func (an ECMAScript function object) and argumentsList (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。形式参数与函数在 FunctionDeclarationInstantiation 过程中被初始化。所有其它绑定在函数体求值期间初始化。

被调用时执行以下步骤:

  1. calleeContext 为当前运行执行上下文。
  2. codefunc.[[ECMAScriptCode]]
  3. strictfunc.[[Strict]]
  4. formalsfunc.[[FormalParameters]]
  5. parameterNamesformals 的 BoundNames。
  6. parameterNames 含有任意重复项,令 hasDuplicatestrue;否则令其为 false
  7. simpleParameterList 为 IsSimpleParameterList of formals
  8. hasParameterExpressions 为 ContainsExpression of formals
  9. varNamescode 的 VarDeclaredNames。
  10. varDeclarationscode 的 VarScopedDeclarations。
  11. lexicalNamescode 的 LexicallyDeclaredNames。
  12. functionNames 为一个新的空 List
  13. functionsToInitialize 为一个新的空 List
  14. 依逆序遍历 varDeclarations 中每个元素 d,执行
    1. d 既不是 VariableDeclaration 也不是 ForBinding 也不是 BindingIdentifier,则
      1. 断言:dFunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclaration 之一。
      2. fnd 的 BoundNames 唯一元素。
      3. functionNames 不包含 fn,则
        1. fn 插入 functionNames 首部。
        2. NOTE: 若同名函数声明出现多次,使用最后一个声明。
        3. d 插入 functionsToInitialize 首部。
  15. argumentsObjectNeededtrue
  16. func.[[ThisMode]]lexical,则
    1. NOTE: 箭头函数永远没有 arguments 对象。
    2. argumentsObjectNeeded 设为 false
  17. 否则若 parameterNames 包含 "arguments",则
    1. argumentsObjectNeeded 设为 false
  18. 否则若 hasParameterExpressionsfalse,则
    1. functionNames 包含 "arguments"lexicalNames 包含 "arguments",则
      1. argumentsObjectNeeded 设为 false
  19. stricttruehasParameterExpressionsfalse,则
    1. NOTE: 参数只需一个 Environment Record,因为严格模式代码中的 eval 调用不能创建对外可见的新绑定。
    2. envcalleeContext 的 LexicalEnvironment。
  20. 否则,
    1. NOTE: 需要单独的 Environment Record 以确保形式参数列表中的直接 eval 创建的绑定不在参数声明的环境内。
    2. calleeEnvcalleeContext 的 LexicalEnvironment。
    3. envNewDeclarativeEnvironment(calleeEnv)。
    4. 断言:calleeContext 的 VariableEnvironment 与 calleeEnv 相同。
    5. calleeContext 的 LexicalEnvironment 设为 env
  21. parameterNames 中每个字符串 paramName,执行
    1. alreadyDeclared 为 ! env.HasBinding(paramName)。
    2. NOTE: 早期错误确保重复参数名只可出现在无参数默认值或 rest 参数的非严格函数中。
    3. alreadyDeclaredfalse,则
      1. 执行 ! env.CreateMutableBinding(paramName, false)。
      2. hasDuplicatestrue,则
        1. 执行 ! env.InitializeBinding(paramName, undefined)。
  22. argumentsObjectNeededtrue,则
    1. stricttruesimpleParameterListfalse,则
      1. aoCreateUnmappedArgumentsObject(argumentsList)。
    2. 否则,
      1. NOTE: 仅对没有 rest 参数、没有任何参数默认值初始化器、且无解构参数的非严格函数提供映射 arguments 对象。
      2. aoCreateMappedArgumentsObject(func, formals, argumentsList, env)。
    3. stricttrue,则
      1. 执行 ! env.CreateImmutableBinding("arguments", false)。
      2. NOTE: 严格模式代码的早期错误阻止对该绑定的赋值,因此其可变性不可观察。
    4. 否则,
      1. 执行 ! env.CreateMutableBinding("arguments", false)。
    5. 执行 ! env.InitializeBinding("arguments", ao)。
    6. parameterBindingsparameterNames 与 « "arguments" » 的列表连接。
  23. 否则,
    1. parameterBindingsparameterNames
  24. iteratorRecordCreateListIteratorRecord(argumentsList)。
  25. hasDuplicatestrue,则
    1. usedEnvundefined
  26. 否则,
    1. usedEnvenv
  27. NOTE: 下列步骤不会返回 ReturnCompletion,因为在表达式位置唯一产生此类完成的方式是使用 YieldExpression,而其在参数列表中已由 15.5.115.6.1早期错误规则禁止。
  28. 执行 ? IteratorBindingInitialization of formals with arguments iteratorRecord and usedEnv
  29. hasParameterExpressionsfalse,则
    1. NOTE: 参数与顶层 var 只需一个 Environment Record
    2. instantiatedVarNamesparameterBindings 的拷贝。
    3. varNames 中每个元素 n,执行
      1. instantiatedVarNames 不含 n,则
        1. n 追加至 instantiatedVarNames
        2. 执行 ! env.CreateMutableBinding(n, false)。
        3. 执行 ! env.InitializeBinding(n, undefined)。
    4. varEnvenv
  30. 否则,
    1. NOTE: 需要单独的 Environment Record 以确保形式参数列表中的表达式创建的闭包无法见到函数体内的声明。
    2. varEnvNewDeclarativeEnvironment(env)。
    3. calleeContext 的 VariableEnvironment 设为 varEnv
    4. instantiatedVarNames 为一个新的空 List
    5. varNames 中每个元素 n,执行
      1. instantiatedVarNames 不含 n,则
        1. n 追加至 instantiatedVarNames
        2. 执行 ! varEnv.CreateMutableBinding(n, false)。
        3. parameterBindings 不含 n,或 functionNamesn,则
          1. initialValueundefined
        4. 否则,
          1. initialValue 为 ! env.GetBindingValue(n, false)。
        5. 执行 ! varEnv.InitializeBinding(n, initialValue)。
        6. NOTE: 与形式参数同名的 var 最初具有与对应已初始化参数相同的值。
  31. stricttrue,则
    1. lexEnvvarEnv
  32. 否则,
    1. Normative Optional
      宿主是 Web 浏览器或以其它方式支持 块级函数声明 Web 历史兼容语义,则
      1. 对任意 BlockCaseClauseDefaultClause xStatementList 中直接包含,且 code Contains xtrue 的每个 FunctionDeclaration f,执行
        1. FfBindingIdentifier 的 StringValue。
        2. 若用以 FBindingIdentifierVariableStatement 替换该 FunctionDeclaration f 不会为 func 产生早期错误,且 parameterNames 不含 F,则
          1. NOTE: 仅当 F 既不是 VarDeclaredName、也不是形式参数名、也不是另一个 FunctionDeclaration 时才在此实例化 F 的 var 绑定。
          2. instantiatedVarNames 不含 FF 不是 "arguments",则
            1. 执行 ! varEnv.CreateMutableBinding(F, false)。
            2. 执行 ! varEnv.InitializeBinding(F, undefined)。
            3. F 追加至 instantiatedVarNames
          3. FunctionDeclaration f 被求值时,用以下步骤取代 15.2.6 中的 FunctionDeclaration Evaluation 算法:
            1. fEnv 为当前运行执行上下文的 VariableEnvironment。
            2. bEnv 为当前运行执行上下文的 LexicalEnvironment。
            3. fObj 为 ! bEnv.GetBindingValue(F, false)。
            4. 执行 ! fEnv.SetMutableBinding(F, fObj, false)。
            5. 返回 unused
    2. lexEnvNewDeclarativeEnvironment(varEnv)。
    3. NOTE: 非严格函数为顶层词法声明使用一个单独的 Environment Record,以便直接 eval 能确定 eval 代码引入的 var 作用域声明是否与预先存在的顶层词法作用域声明冲突。严格函数不需要此步骤,因为严格直接 eval 总是将所有声明放入新的 Environment Record
  33. calleeContext 的 LexicalEnvironment 设为 lexEnv
  34. lexDeclarationscode 的 LexicallyScopedDeclarations。
  35. lexDeclarations 中每个元素 d,执行
    1. NOTE: 词法声明的名字不可能与函数/生成器声明、形式参数或 var 名相同。词法声明的名字在此仅被实例化但未初始化。
    2. d 的 BoundNames 中每个元素 dn,执行
      1. 若 IsConstantDeclaration of dtrue,则
        1. 执行 ! lexEnv.CreateImmutableBinding(dn, true)。
      2. 否则,
        1. 执行 ! lexEnv.CreateMutableBinding(dn, false)。
  36. privateEnvcalleeContext 的 PrivateEnvironment。
  37. functionsToInitialize 中每个 Parse Node f,执行
    1. fnf 的 BoundNames 唯一元素。
    2. fo 为 InstantiateFunctionObject of f with arguments lexEnv and privateEnv
    3. 执行 ! varEnv.SetMutableBinding(fn, fo, false)。
  38. 返回 unused

10.3 内置函数对象 (Built-in Function Objects)

内置函数对象普通对象;它必须符合 10.1 中对普通对象的要求。

除每个普通对象所需的内部槽(见 10.1)外,内置函数对象还必须具有下列内部槽:

  • [[Realm]]:一个 Realm Record,表示创建该函数的 realm
  • [[InitialName]]:一个 String,函数的初始名称,被 20.2.3.5 使用。

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

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

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

实现可以提供未在本规范中定义的额外内置函数对象

10.3.1 [[Call]] ( thisArgument, argumentsList )

The [[Call]] internal method of 内置函数对象 F takes arguments thisArgument (an ECMAScript language value) and argumentsList (a List of ECMAScript language values) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. 返回 ? BuiltinCallOrConstruct(F, thisArgument, argumentsList, undefined)。

10.3.2 [[Construct]] ( argumentsList, newTarget )

The [[Construct]] internal method of 内置函数对象 F(当该方法存在时) takes arguments argumentsList (a List of ECMAScript language values) and newTarget (a constructor) and returns 返回一个包含 Object 的正常完成或一个抛出完成. It performs the following steps when called:

  1. result 为 ? BuiltinCallOrConstruct(F, uninitialized, argumentsList, newTarget)。
  2. 断言:result 是一个 Object。
  3. 返回 result

10.3.3 BuiltinCallOrConstruct ( F, thisArgument, argumentsList, newTarget )

The abstract operation BuiltinCallOrConstruct takes arguments F (a built-in function object), thisArgument (an ECMAScript language value or uninitialized), argumentsList (a List of ECMAScript language values), and newTarget (a constructor or undefined) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. callerContext 为正在运行的执行上下文。
  2. callerContext 尚未被挂起,则挂起 callerContext
  3. calleeContext 为一个新的执行上下文。
  4. calleeContext 的 Function 设为 F
  5. calleeRealmF.[[Realm]]
  6. calleeContextRealm 设为 calleeRealm
  7. calleeContext 的 ScriptOrModule 设为 null
  8. 执行任何实现定义的、对 calleeContext 必要的初始化。
  9. calleeContext 压入执行上下文栈;calleeContext 现在为运行执行上下文。
  10. resultF 的求值 且符合其规范描述的完成记录结果。若 thisArgumentuninitialized,则 this 值未初始化;否则由 thisArgument 提供 this 值。argumentsList 提供具名参数。newTarget 提供 NewTarget 值。
  11. 注:若 F 在本文档中定义,其“规范描述”即通过算法步骤或其他方式给出的行为。
  12. calleeContext 自执行上下文栈移除并恢复 callerContext 为运行执行上下文。
  13. 返回 ? result
Note

calleeContext 被自执行上下文栈移除时,若其已被可访问的 Generator 挂起并被保留以供后续恢复,则不得销毁它。

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

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), prototype (an Object or null), and prefix (a String) and returns 一个内置函数对象. additionalInternalSlotsList 含必须作为该对象一部分定义的额外内部槽名称。此操作创建一个内置函数对象。 It performs the following steps when called:

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

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

10.4 内置特异对象的内部方法与内部槽 (Built-in Exotic Object Internal Methods and Slots)

本规范定义了多种内置特异对象。除少数特定情形外,它们与普通对象的行为相似。以下特异对象除非下文明确另行规定,否则使用普通对象的内部方法:

10.4.1 绑定函数特异对象 (Bound Function Exotic Objects)

绑定函数特异对象是包装另一个函数对象的特异对象。它是可调用的(具有 [[Call]],可能具有 [[Construct]])。调用它通常导致调用其被包装的函数。

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

绑定函数特异对象不具有 Table 28 中 ECMAScript 函数对象的内部槽;它们改为(除 [[Prototype]][[Extensible]] 外)具有 Table 29 所列的内部槽。

Table 29: 绑定函数特异对象的内部槽 (Internal Slots of Bound Function Exotic Objects)
Internal Slot Type Description
[[BoundTargetFunction]] a callable Object 被包装的函数对象
[[BoundThis]] an ECMAScript language value 调用被包装函数时始终作为 this 的值。
[[BoundArguments]] a List of ECMAScript language values 在任何调用中用作被包装函数前置实参的值列表。

10.4.1.1 [[Call]] ( thisArgument, argumentsList )

The [[Call]] internal method of 绑定函数特异对象 F takes arguments thisArgument (an ECMAScript language value) and argumentsList (a List of ECMAScript language values) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. targetF.[[BoundTargetFunction]]
  2. boundThisF.[[BoundThis]]
  3. boundArgsF.[[BoundArguments]]
  4. argsboundArgsargumentsList 的列表连接。
  5. 返回 ? Call(target, boundThis, args)。

10.4.1.2 [[Construct]] ( argumentsList, newTarget )

The [[Construct]] internal method of 绑定函数特异对象 F takes arguments argumentsList (a List of ECMAScript language values) and newTarget (a constructor) and returns 返回一个包含 Object 的正常完成或一个抛出完成. It performs the following steps when called:

  1. targetF.[[BoundTargetFunction]]
  2. 断言:IsConstructor(target) 为 true
  3. boundArgsF.[[BoundArguments]]
  4. argsboundArgsargumentsList 的列表连接。
  5. SameValue(F, newTarget) 为 true,则将 newTarget 设为 target
  6. 返回 ? Construct(target, args, newTarget)。

10.4.1.3 BoundFunctionCreate ( targetFunction, boundThis, boundArgs )

The abstract operation BoundFunctionCreate takes arguments targetFunction (a function object), boundThis (an ECMAScript language value), and boundArgs (a List of ECMAScript language values) and returns 返回一个包含 function object 的正常完成或一个抛出完成. 用于指定创建新的绑定函数特异对象。 It performs the following steps when called:

  1. proto 为 ? targetFunction.[[GetPrototypeOf]]()。
  2. internalSlotsList 为 « [[Prototype]], [[Extensible]] » 与 Table 29 中内部槽列表的连接。
  3. objMakeBasicObject(internalSlotsList)。
  4. obj.[[Prototype]] 设为 proto
  5. 10.4.1.1 所述设置 obj.[[Call]]
  6. IsConstructor(targetFunction) 为 true,则
    1. 10.4.1.2 所述设置 obj.[[Construct]]
  7. obj.[[BoundTargetFunction]] 设为 targetFunction
  8. obj.[[BoundThis]] 设为 boundThis
  9. obj.[[BoundArguments]] 设为 boundArgs
  10. 返回 obj

10.4.2 数组特异对象 (Array Exotic Objects)

Array 是对数组索引属性键(见 6.1.7)做特殊处理的特异对象。属性名数组索引的属性也称为 element。每个 Array 有一个不可配置的 "length" 属性,其值始终是数学值严格小于 232 的非负整数 Number。"length" 的值在数值上大于其每个名称为数组索引的自身属性的名称;当 Array 的自身属性被创建或改变时,为保持该不变式,会按需要调整其他属性。具体地,当添加一个名称为数组索引的自身属性时,必要时将 "length" 的值改为该索引数值加一;当 "length" 值被改变时,删除所有名称为数组索引且其值不小于新 length 的自身属性。该约束仅适用于 Array 的自身属性,不受其原型链上继承的 "length"数组索引属性影响。

若对象的 [[DefineOwnProperty]] 内部方法使用以下实现,且其其它基本内部方法使用 10.1 中的定义,则其为 数组特异对象(简称 Array)。这些方法在 ArrayCreate 中安装。

10.4.2.1 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of 数组特异对象 A takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

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

10.4.2.2 ArrayCreate ( length [ , proto ] )

The abstract operation ArrayCreate takes argument length (a non-negative integer) and optional argument proto (an Object) and returns 返回一个包含数组特异对象正常完成或一个抛出完成. 用于指定创建新的 Array。 It performs the following steps when called:

  1. length > 232 - 1,抛出 RangeError 异常。
  2. 若未提供 proto,则设 proto%Array.prototype%
  3. AMakeBasicObject[[Prototype]], [[Extensible]] »)。
  4. A.[[Prototype]] 设为 proto
  5. 10.4.2.1 规定设置 A.[[DefineOwnProperty]]
  6. 执行 ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  7. 返回 A

10.4.2.3 ArraySpeciesCreate ( originalArray, length )

The abstract operation ArraySpeciesCreate takes arguments originalArray (an Object) and length (a non-negative integer) and returns 返回一个包含 Object 的正常完成或一个抛出完成. 用于指定通过由 originalArray 派生的构造函数创建新的 Array 或相似对象;不强制该构造函数返回 Array。 It performs the following steps when called:

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

originalArray 使用非当前执行上下文 realm 的标准内置 Array 构造器创建,则新 Array 使用当前执行上下文的 realm 创建,以保持与历史浏览器行为兼容。

10.4.2.4 ArraySetLength ( A, Desc )

The abstract operation ArraySetLength takes arguments A (an Array) and Desc (a Property Descriptor) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. Desc 不含 [[Value]] 字段,则
    1. 返回 ! OrdinaryDefineOwnProperty(A, "length", Desc)。
  2. newLenDescDesc 的拷贝。
  3. newLen 为 ? ToUint32(Desc.[[Value]])。
  4. numberLen 为 ? ToNumber(Desc.[[Value]])。
  5. SameValueZero(newLen, numberLen) 为 false,抛出 RangeError 异常。
  6. newLenDesc.[[Value]] 设为 newLen
  7. oldLenDescOrdinaryGetOwnProperty(A, "length")。
  8. 断言:oldLenDesc 不为 undefined
  9. 断言:IsDataDescriptor(oldLenDesc) 为 true
  10. 断言:oldLenDesc.[[Configurable]]false
  11. oldLenoldLenDesc.[[Value]]
  12. newLenoldLen,则
    1. 返回 ! OrdinaryDefineOwnProperty(A, "length", newLenDesc)。
  13. oldLenDesc.[[Writable]]false,返回 false
  14. newLenDesc[[Writable]] 字段或 newLenDesc.[[Writable]]true,则
    1. newWritabletrue
  15. 否则,
    1. 注:若某些元素无法删除,则延迟将 [[Writable]] 设为 false
    2. newWritablefalse
    3. newLenDesc.[[Writable]] 设为 true
  16. succeeded 为 ! OrdinaryDefineOwnProperty(A, "length", newLenDesc)。
  17. succeededfalse,返回 false
  18. A 的每个自身属性键 P,若 P数组索引且 ! ToUint32(P) ≥ newLen,按递减数值索引顺序:
    1. deleteSucceeded 为 ! A.[[Delete]](P)。
    2. deleteSucceededfalse,则
      1. newLenDesc.[[Value]] 设为 ! ToUint32(P) + 1𝔽
      2. newWritablefalse,将 newLenDesc.[[Writable]] 设为 false
      3. 执行 ! OrdinaryDefineOwnProperty(A, "length", newLenDesc)。
      4. 返回 false
  19. newWritablefalse,则
    1. succeeded 设为 ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Writable]]: false })。
    2. 断言:succeededtrue
  20. 返回 true
Note

在步骤 34 中,若 Desc.[[Value]] 是对象,其 valueOf 方法被调用两次(历史遗留行为)。

10.4.3 字符串特异对象 (String Exotic Objects)

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

若对象的 [[GetOwnProperty]][[DefineOwnProperty]][[OwnPropertyKeys]] 内部方法使用以下实现,且其他基本内部方法使用 10.1 中的定义,则该对象是 字符串特异对象(或简称 String 对象)。这些方法在 StringCreate 中安装。

字符串特异对象拥有与普通对象相同的内部槽,另有 [[StringData]] 内部槽。

10.4.3.1 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of 字符串特异对象 S takes argument P (a property key) and returns 返回一个包含 Property Descriptorundefined正常完成. It performs the following steps when called:

  1. descOrdinaryGetOwnProperty(S, P)。
  2. desc 不为 undefined,返回 desc
  3. 返回 StringGetOwnProperty(S, P)。

10.4.3.2 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of 字符串特异对象 S takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. stringDescStringGetOwnProperty(S, P)。
  2. stringDesc 不为 undefined,则
    1. extensibleS.[[Extensible]]
    2. 返回 IsCompatiblePropertyDescriptor(extensible, Desc, stringDesc)。
  3. 返回 ! OrdinaryDefineOwnProperty(S, P, Desc)。

10.4.3.3 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of 字符串特异对象 O takes no arguments and returns 返回一个包含属性键列表的正常完成. It performs the following steps when called:

  1. keys 为一个新的空列表。
  2. strO.[[StringData]]
  3. 断言:str 是一个 String。
  4. lenstr 的长度。
  5. 对每个整数 i(0 ≤ i < len,按升序):
    1. 追加 ! ToString(𝔽(i)) 至 keys
  6. O 的每个自身属性键 PP数组索引 且 ! ToIntegerOrInfinity(P) ≥ len,按数值索引升序):
    1. 追加 Pkeys
  7. O 的每个自身属性键 PP 为 String 且非数组索引,按创建时间升序):
    1. 追加 Pkeys
  8. O 的每个自身属性键 PP 为 Symbol,按创建时间升序):
    1. 追加 Pkeys
  9. 返回 keys

10.4.3.4 StringCreate ( value, prototype )

The abstract operation StringCreate takes arguments value (a String) and prototype (an Object) and returns 一个字符串特异对象. 用于指定创建新的字符串特异对象。 It performs the following steps when called:

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

10.4.3.5 StringGetOwnProperty ( S, P )

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

  1. P 不是 String,返回 undefined
  2. indexCanonicalNumericIndexString(P)。
  3. index 不是整数 Number,返回 undefined
  4. index-0𝔽index < -0𝔽,返回 undefined
  5. strS.[[StringData]]
  6. 断言:str 是 String。
  7. lenstr 的长度。
  8. (index) ≥ len,返回 undefined
  9. resultStr 为从 (index) 到 (index) + 1 的 str 子串。
  10. 返回 PropertyDescriptor { [[Value]]: resultStr, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }。

10.4.4 Arguments 特异对象 (Arguments Exotic Objects)

大多数 ECMAScript 函数向其代码提供一个 arguments 对象。依据函数定义特征,该对象要么是普通对象,要么是 arguments 特异对象arguments 特异对象数组索引属性映射到其关联函数一次调用的形式参数绑定。

若对象的内部方法按以下实现(未指明者使用 10.1 的定义),则为 arguments 特异对象。这些方法在 CreateMappedArgumentsObject 中安装。

Note 1

CreateUnmappedArgumentsObject 归入本条款,但它创建的是普通对象而非 arguments 特异对象

Arguments 特异对象普通对象具有相同内部槽,并另有 [[ParameterMap]]。普通 arguments 对象也有 [[ParameterMap]],其值恒为 undefined,仅被 Object.prototype.toString (20.1.3.6) 用来识别。

Note 2

数值名称小于对应函数形式参数个数的整数索引数据属性初始与执行上下文中的参数绑定共享其值;修改其一会影响另一方。删除并重新定义该属性或将其改为访问器属性会打破这种对应。普通 arguments 对象的属性值仅是实参副本,不与形式参数动态联动。

Note 3

ParameterMap 对象及其属性值是描述 arguments 对象与参数绑定对应关系的机制;它们对 ECMAScript 代码不可直接观察,实现无需实际创建。

Note 4

普通 arguments 对象定义一个名为 "callee" 的不可配置访问器属性,访问时抛出 TypeError。在 arguments 特异对象"callee" 有更具体含义。普通变体的定义防止实现以其他方式定义它。

Note 5

历史上 arguments 特异对象实现包含 "caller" 访问器。ECMAScript 2017 之前规范在普通 arguments 对象上要求其抛出。此扩展已弃用,相关要求被移除。

10.4.4.1 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of arguments 特异对象 args takes argument P (a property key) and returns 返回包含 Property Descriptorundefined正常完成. It performs the following steps when called:

  1. descOrdinaryGetOwnProperty(args, P)。
  2. descundefined,返回 undefined
  3. mapargs.[[ParameterMap]]
  4. isMapped 为 ! HasOwnProperty(map, P)。
  5. isMappedtrue,则
    1. desc.[[Value]] 设为 ! Get(map, P)。
  6. 返回 desc

10.4.4.2 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of arguments 特异对象 args takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回包含 Boolean 的正常完成. It performs the following steps when called:

  1. mapargs.[[ParameterMap]]
  2. isMapped 为 ! HasOwnProperty(map, P)。
  3. newArgDescDesc
  4. isMappedtrueIsDataDescriptor(Desc) 为 true,则
    1. Desc 不含 [[Value]] 字段、含 [[Writable]] 字段且 Desc.[[Writable]]false,则
      1. newArgDesc 设为 Desc 的拷贝。
      2. newArgDesc.[[Value]] 设为 ! Get(map, P)。
  5. allowed 为 ! OrdinaryDefineOwnProperty(args, P, newArgDesc)。
  6. allowedfalse,返回 false
  7. isMappedtrue,则
    1. IsAccessorDescriptor(Desc) 为 true,则
      1. 执行 ! map.[[Delete]](P)。
    2. 否则,
      1. Desc[[Value]] 字段,则
        1. 断言:下面的 Set 会成功,因为被映射的形式参数总是可写。
        2. 执行 ! Set(map, P, Desc.[[Value]], false)。
      2. Desc[[Writable]] 字段且 Desc.[[Writable]]false,则
        1. 执行 ! map.[[Delete]](P)。
  8. 返回 true

10.4.4.3 [[Get]] ( P, Receiver )

The [[Get]] internal method of arguments 特异对象 args takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. mapargs.[[ParameterMap]]
  2. isMapped 为 ! HasOwnProperty(map, P)。
  3. isMappedfalse,则
    1. 返回 ? OrdinaryGet(args, P, Receiver)。
  4. 否则,
    1. 断言:map 包含 P 的形式参数映射。
    2. 返回 ! Get(map, P)。

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

The [[Set]] internal method of arguments 特异对象 args takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. SameValue(args, Receiver) 为 false,则
    1. isMappedfalse
  2. 否则,
    1. mapargs.[[ParameterMap]]
    2. isMapped 为 ! HasOwnProperty(map, P)。
  3. isMappedtrue,则
    1. 断言:以下 Set 会成功,因为被映射形式参数总是可写。
    2. 执行 ! Set(map, P, V, false)。
  4. 返回 ? OrdinarySet(args, P, V, Receiver)。

10.4.4.5 [[Delete]] ( P )

The [[Delete]] internal method of arguments 特异对象 args takes argument P (a property key) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

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

10.4.4.6 CreateUnmappedArgumentsObject ( argumentsList )

The abstract operation CreateUnmappedArgumentsObject takes argument argumentsList (a List of ECMAScript language values) and returns 一个普通对象. It performs the following steps when called:

  1. lenargumentsList 中元素个数。
  2. objOrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »)。
  3. obj.[[ParameterMap]] 设为 undefined
  4. 执行 ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  5. index 为 0。
  6. index < len 重复:
    1. valargumentsList[index]。
    2. 执行 ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val)。
    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, argumentsList, env )

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

  1. 断言:formals 不含 rest 参数、任何绑定模式或初始化器;可包含重复标识符。
  2. lenargumentsList 元素个数。
  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. parameterNamesformals 的 BoundNames。
  13. numberOfParametersparameterNames 元素个数。
  14. index 为 0。
  15. index < len 重复:
    1. valargumentsList[index]。
    2. 执行 ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val)。
    3. index 设为 index + 1。
  16. 执行 ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  17. mappedNames 为新空列表。
  18. index 设为 numberOfParameters - 1。
  19. index ≥ 0 重复:
    1. nameparameterNames[index]。
    2. mappedNames 不含 name,则
      1. 追加 namemappedNames
      2. index < len,则
        1. gMakeArgGetter(name, env)。
        2. pMakeArgSetter(name, env)。
        3. 执行 ! map.[[DefineOwnProperty]](! ToString(𝔽(index)), PropertyDescriptor { [[Set]]: p, [[Get]]: g, [[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, env )

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

  1. getterClosure 为一个新的无参数 Abstract Closure,捕获 nameenv,调用时执行:
    1. 返回 NormalCompletion(! env.GetBindingValue(name, false))。
  2. getterCreateBuiltinFunction(getterClosure, 0, "", « »)。
  3. 注:getter 不会被 ECMAScript 代码直接访问。
  4. 返回 getter

10.4.4.7.2 MakeArgSetter ( name, env )

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

  1. setterClosure 为一个带参数 (value) 的新 Abstract Closure,捕获 nameenv,调用时执行:
    1. 返回 NormalCompletion(! env.SetMutableBinding(name, value, false))。
  2. setterCreateBuiltinFunction(setterClosure, 1, "", « »)。
  3. 注:setter 不会被 ECMAScript 代码直接访问。
  4. 返回 setter

10.4.5 TypedArray 特异对象 (TypedArray Exotic Objects)

TypedArray 是对规范数字字符串属性键做特殊处理的特异对象,使用其中属于界内整数索引的子集访问同类型元素,并在不遍历原型链的情况下确保其余索引缺失的不变式。

Note

由于对任意 Number nToString(n) 为规范数字字符串,实现可在无需真实字符串转换的情况下将 Number 当作属性键

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 TypedArray O takes no arguments and returns 返回一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. 注:6.1.7.3 中的可扩展性不变式不允许在 O 仍可能获得(或失去后再获得)属性时返回 true;当底层缓冲区重分配且涉及整数索引属性时可能发生该情况。
  2. IsTypedArrayFixedLength(O) 为 false,返回 false
  3. 返回 OrdinaryPreventExtensions(O)。

10.4.5.2 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of TypedArray O takes argument P (a property key) and returns 返回包含 Property Descriptorundefined正常完成. It performs the following steps when called:

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

10.4.5.3 [[HasProperty]] ( P )

The [[HasProperty]] internal method of TypedArray O takes argument P (a property key) and returns 返回包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 String,则
    1. numericIndexCanonicalNumericIndexString(P)。
    2. numericIndex 不为 undefined,返回 IsValidIntegerIndex(O, numericIndex)。
  2. 返回 ? OrdinaryHasProperty(O, P)。

10.4.5.4 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of TypedArray O takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 String,则
    1. numericIndexCanonicalNumericIndexString(P)。
    2. numericIndex 不为 undefined,则
      1. IsValidIntegerIndex(O, numericIndex) 为 false,返回 false
      2. Desc[[Configurable]] 且为 false,返回 false
      3. Desc[[Enumerable]] 且为 false,返回 false
      4. IsAccessorDescriptor(Desc) 为 true,返回 false
      5. Desc[[Writable]] 且为 false,返回 false
      6. Desc[[Value]] 字段,执行 ? TypedArraySetElement(O, numericIndex, Desc.[[Value]])。
      7. 返回 true
  2. 返回 ! OrdinaryDefineOwnProperty(O, P, Desc)。

10.4.5.5 [[Get]] ( P, Receiver )

The [[Get]] internal method of TypedArray O takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns 返回包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 String,则
    1. numericIndexCanonicalNumericIndexString(P)。
    2. numericIndex 不为 undefined,则
      1. 返回 TypedArrayGetElement(O, numericIndex)。
  2. 返回 ? OrdinaryGet(O, P, Receiver)。

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

The [[Set]] internal method of TypedArray O takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns 返回包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 String,则
    1. numericIndexCanonicalNumericIndexString(P)。
    2. numericIndex 不为 undefined,则
      1. SameValue(O, Receiver) 为 true,则
        1. 执行 ? TypedArraySetElement(O, numericIndex, V)。
        2. 返回 true
      2. IsValidIntegerIndex(O, numericIndex) 为 false,返回 true
  2. 返回 ? OrdinarySet(O, P, V, Receiver)。

10.4.5.7 [[Delete]] ( P )

The [[Delete]] internal method of TypedArray O takes argument P (a property key) and returns 返回包含 Boolean 的正常完成. It performs the following steps when called:

  1. P 是 String,则
    1. numericIndexCanonicalNumericIndexString(P)。
    2. numericIndex 不为 undefined,则
      1. IsValidIntegerIndex(O, numericIndex) 为 false,返回 true;否则返回 false
  2. 返回 ! OrdinaryDelete(O, P)。

10.4.5.8 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of TypedArray O takes no arguments and returns 返回包含属性键列表的正常完成. It performs the following steps when called:

  1. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
  2. keys 为新空列表。
  3. IsTypedArrayOutOfBounds(taRecord) 为 false,则
    1. lengthTypedArrayLength(taRecord)。
    2. 对每个整数 i(0 ≤ i < length,升序):
      1. 追加 ! ToString(𝔽(i)) 至 keys
  4. O 的每个自身属性键 PP 为 String 且不是整数索引,按创建时间升序):
    1. 追加 Pkeys
  5. O 的每个自身属性键 PP 为 Symbol,按创建时间升序):
    1. 追加 Pkeys
  6. 返回 keys

10.4.5.9 带缓冲区见证记录的 TypedArray (TypedArray With Buffer Witness Records)

TypedArray With Buffer Witness Record 是用于封装一个 TypedArray 及其被查看缓冲区缓存字节长度的 Record;当缓冲区为可增长 SharedArrayBuffer 时用于确保字节长度数据块的共享内存读取仅发生一次。

其字段列于 Table 30

Table 30: TypedArray With Buffer Witness Record 字段
Field Name Value Meaning
[[Object]] a TypedArray 其缓冲区字节长度被加载的 TypedArray
[[CachedBufferByteLength]] a non-negative integer or detached 记录创建时对象 [[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 一个 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 ( prototype )

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

  1. internalSlotsList 为 « [[Prototype]], [[Extensible]], [[ViewedArrayBuffer]], [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], [[ArrayLength]] »。
  2. AMakeBasicObject(internalSlotsList)。
  3. 10.4.5.1 设置 A.[[PreventExtensions]]
  4. 10.4.5.2 设置 A.[[GetOwnProperty]]
  5. 10.4.5.3 设置 A.[[HasProperty]]
  6. 10.4.5.4 设置 A.[[DefineOwnProperty]]
  7. 10.4.5.5 设置 A.[[Get]]
  8. 10.4.5.6 设置 A.[[Set]]
  9. 10.4.5.7 设置 A.[[Delete]]
  10. 10.4.5.8 设置 A.[[OwnPropertyKeys]]
  11. A.[[Prototype]] 设为 prototype
  12. 返回 A

10.4.5.12 TypedArrayByteLength ( taRecord )

The abstract operation TypedArrayByteLength takes argument taRecord (a TypedArray With Buffer Witness Record) and returns 一个非负整数. It performs the following steps when called:

  1. IsTypedArrayOutOfBounds(taRecord) 为 true,返回 0。
  2. lengthTypedArrayLength(taRecord)。
  3. length = 0,返回 0。
  4. OtaRecord.[[Object]]
  5. O.[[ByteLength]] 不为 auto,返回 O.[[ByteLength]]
  6. elementSizeTypedArrayElementSize(O)。
  7. 返回 length × elementSize

10.4.5.13 TypedArrayLength ( taRecord )

The abstract operation TypedArrayLength takes argument taRecord (a TypedArray With Buffer Witness Record) and returns 一个非负整数. It performs the following steps when called:

  1. 断言:IsTypedArrayOutOfBounds(taRecord) 为 false
  2. OtaRecord.[[Object]]
  3. O.[[ArrayLength]] 不为 auto,返回 O.[[ArrayLength]]
  4. 断言:IsFixedLengthArrayBuffer(O.[[ViewedArrayBuffer]]) 为 false
  5. byteOffsetO.[[ByteOffset]]
  6. elementSizeTypedArrayElementSize(O)。
  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 一个 Boolean. 检查任一数值属性是否引用了底层缓冲区边界外的索引。 It performs the following steps when called:

  1. OtaRecord.[[Object]]
  2. bufferByteLengthtaRecord.[[CachedBufferByteLength]]
  3. 断言:IsDetachedBuffer(O.[[ViewedArrayBuffer]]) 为 true 当且仅当 bufferByteLengthdetached
  4. bufferByteLengthdetached,返回 true
  5. byteOffsetStartO.[[ByteOffset]]
  6. O.[[ArrayLength]]auto,则
    1. byteOffsetEndbufferByteLength
  7. 否则,
    1. elementSizeTypedArrayElementSize(O)。
    2. byteOffsetEndbyteOffsetStart + O.[[ArrayLength]] × elementSize
  8. byteOffsetStart > bufferByteLengthbyteOffsetEnd > bufferByteLength,返回 true
  9. 注:长度为 0 的 TypedArray 不视为越界。
  10. 返回 false

10.4.5.15 IsTypedArrayFixedLength ( O )

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

  1. O.[[ArrayLength]]auto,返回 false
  2. bufferO.[[ViewedArrayBuffer]]
  3. IsFixedLengthArrayBuffer(buffer) 为 falseIsSharedArrayBuffer(buffer) 为 false,返回 false
  4. 返回 true

10.4.5.16 IsValidIntegerIndex ( O, index )

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

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

10.4.5.17 TypedArrayGetElement ( O, index )

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

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

10.4.5.18 TypedArraySetElement ( O, index, value )

The abstract operation TypedArraySetElement takes arguments O (a TypedArray), index (a Number), and value (an ECMAScript language value) and returns 返回包含 unused正常完成或一个抛出完成. It performs the following steps when called:

  1. O.[[ContentType]]bigint,令 numValue 为 ? ToBigInt(value);否则令 numValue 为 ? ToNumber(value)。
  2. IsValidIntegerIndex(O, index) 为 true,则
    1. offsetO.[[ByteOffset]]
    2. elementSizeTypedArrayElementSize(O)。
    3. byteIndexInBuffer 为 ((index) × elementSize) + offset
    4. elementTypeTypedArrayElementType(O)。
    5. 执行 SetValueInBuffer(O.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, numValue, true, unordered)。
  3. 返回 unused
Note

此操作表面上总是成功;当写入越界或底层 ArrayBuffer 已分离时不产生效果。

10.4.5.19 IsArrayBufferViewOutOfBounds ( O )

The abstract operation IsArrayBufferViewOutOfBounds takes argument O (a TypedArray or a DataView) and returns 一个 Boolean. 检查 TypedArray 的数值属性或 DataView 方法是否可能引用底层数据块范围之外的值;为上游规范提供便利。 It performs the following steps when called:

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

10.4.6 模块命名空间特异对象 (Module Namespace Exotic Objects)

模块命名空间特异对象是一个暴露 ECMAScript Module 导出绑定的特异对象(见 16.2.3)。其字符串键自身属性与该 Module 导出的绑定名一一对应,包括通过 export * 间接导出的绑定。每个字符串键属性的键即对应导出绑定名的 StringValue。这些是其全部字符串键属性。每个此类属性特性为 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }。模块命名空间特异对象不可扩展。

若对象的 [[GetPrototypeOf]][[SetPrototypeOf]][[IsExtensible]][[PreventExtensions]][[GetOwnProperty]][[DefineOwnProperty]][[HasProperty]][[Get]][[Set]][[Delete]][[OwnPropertyKeys]] 内部方法使用本节定义,且其它基本内部方法使用 10.1 的定义,则其为 模块命名空间特异对象。这些方法由 ModuleNamespaceCreate 安装。

模块命名空间特异对象具有 Table 31 定义的内部槽。

Table 31: 模块命名空间特异对象的内部槽 (Internal Slots of Module Namespace Exotic Objects)
Internal Slot Type Description
[[Module]] a Module Record 此命名空间暴露其导出的 Module Record
[[Exports]] a List of Strings 作为该对象自身属性暴露的导出名称字符串列表,按字典序代码单元顺序排序。

10.4.6.1 [[GetPrototypeOf]] ( )

The [[GetPrototypeOf]] internal method of 模块命名空间特异对象 takes no arguments and returns 返回一个包含 null正常完成. It performs the following steps when called:

  1. 返回 null

10.4.6.2 [[SetPrototypeOf]] ( V )

The [[SetPrototypeOf]] internal method of 模块命名空间特异对象 O takes argument V (an Object or null) and returns 返回一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. 返回 ! SetImmutablePrototype(O, V)。

10.4.6.3 [[IsExtensible]] ( )

The [[IsExtensible]] internal method of 模块命名空间特异对象 takes no arguments and returns 返回一个包含 false正常完成. It performs the following steps when called:

  1. 返回 false

10.4.6.4 [[PreventExtensions]] ( )

The [[PreventExtensions]] internal method of 模块命名空间特异对象 takes no arguments and returns 返回一个包含 true正常完成. It performs the following steps when called:

  1. 返回 true

10.4.6.5 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of 模块命名空间特异对象 O takes argument P (a property key) and returns 返回一个包含 Property Descriptorundefined正常完成,或一个抛出完成. It performs the following steps when called:

  1. P 是 Symbol,返回 OrdinaryGetOwnProperty(O, P)。
  2. exportsO.[[Exports]]
  3. exports 不含 P,返回 undefined
  4. value 为 ? O.[[Get]](P, O)。
  5. 返回 PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }。

10.4.6.6 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of 模块命名空间特异对象 O takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 Symbol,返回 ! OrdinaryDefineOwnProperty(O, P, Desc)。
  2. current 为 ? O.[[GetOwnProperty]](P)。
  3. currentundefined,返回 false
  4. Desc[[Configurable]] 且为 true,返回 false
  5. Desc[[Enumerable]] 且为 false,返回 false
  6. IsAccessorDescriptor(Desc) 为 true,返回 false
  7. Desc[[Writable]] 且为 false,返回 false
  8. Desc[[Value]] 字段,返回 SameValue(Desc.[[Value]], current.[[Value]])。
  9. 返回 true

10.4.6.7 [[HasProperty]] ( P )

The [[HasProperty]] internal method of 模块命名空间特异对象 O takes argument P (a property key) and returns 返回一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. P 是 Symbol,返回 ! OrdinaryHasProperty(O, P)。
  2. exportsO.[[Exports]]
  3. exportsP,返回 true
  4. 返回 false

10.4.6.8 [[Get]] ( P, Receiver )

The [[Get]] internal method of 模块命名空间特异对象 O takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. P 是 Symbol,则
    1. 返回 ! OrdinaryGet(O, P, Receiver)。
  2. exportsO.[[Exports]]
  3. exports 不含 P,返回 undefined
  4. mO.[[Module]]
  5. bindingm.ResolveExport(P)。
  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 无副作用;对相同参数组合多次调用结果必须一致。实现可预先计算或缓存每个命名空间对象 [[Exports]] 的 ResolveExport 结果。

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

The [[Set]] internal method of 模块命名空间特异对象 takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns 返回一个包含 false正常完成. It performs the following steps when called:

  1. 返回 false

10.4.6.10 [[Delete]] ( P )

The [[Delete]] internal method of 模块命名空间特异对象 O takes argument P (a property key) and returns 返回一个包含 Boolean 的正常完成. It performs the following steps when called:

  1. P 是 Symbol,则
    1. 返回 ! OrdinaryDelete(O, P)。
  2. exportsO.[[Exports]]
  3. exportsP,返回 false
  4. 返回 true

10.4.6.11 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of 模块命名空间特异对象 O takes no arguments and returns 返回一个包含属性键列表的正常完成. It performs the following steps when called:

  1. exportsO.[[Exports]]
  2. symbolKeysOrdinaryOwnPropertyKeys(O)。
  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 一个模块命名空间特异对象. 用于指定创建新的模块命名空间特异对象。 It performs the following steps when called:

  1. 断言:module.[[Namespace]]empty
  2. internalSlotsListTable 31 中列出的内部槽列表。
  3. MMakeBasicObject(internalSlotsList)。
  4. M 的基本内部方法设为 10.4.6 中的定义。
  5. M.[[Module]] 设为 module
  6. sortedExports 为对 exports 元素按字典序代码单元排序后的列表。
  7. M.[[Exports]] 设为 sortedExports
  8. 创建 M 的自身属性以对应 28.3 中的定义。
  9. module.[[Namespace]] 设为 M
  10. 返回 M

10.4.7 不可变原型特异对象 (Immutable Prototype Exotic Objects)

不可变原型特异对象是其 [[Prototype]] 内部槽一旦初始化即不再改变的特异对象。

若对象的 [[SetPrototypeOf]] 内部方法使用以下实现(其它基本内部方法可视具体对象采用任意实现),则该对象是 不可变原型特异对象

Note

与其它特异对象不同,不可变原型特异对象没有专门的创建抽象操作;因它们仅用于 %Object.prototype%宿主环境宿主环境中相关对象可能在其它方面也是特异的,需单独的创建过程。

10.4.7.1 [[SetPrototypeOf]] ( V )

The [[SetPrototypeOf]] internal method of 不可变原型特异对象 O takes argument V (an Object or null) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 返回 ? SetImmutablePrototype(O, V)。

10.4.7.2 SetImmutablePrototype ( O, V )

The abstract operation SetImmutablePrototype takes arguments O (an Object) and V (an Object or null) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. current 为 ? O.[[GetPrototypeOf]]()。
  2. SameValue(V, current) 为 true,返回 true
  3. 返回 false

10.5 Proxy 对象的内部方法与内部槽 (Proxy Object Internal Methods and Internal Slots)

Proxy 对象是一种特异对象,其关键内部方法部分由 ECMAScript 代码实现。每个 Proxy 对象都有名为 [[ProxyHandler]] 的内部槽。[[ProxyHandler]] 的值要么是一个对象(称为该 proxy 的 handler 对象),要么是 null。handler 对象的方法(见 Table 32)可用于增强一个或多个 Proxy 内部方法的实现。每个 Proxy 对象还具有名为 [[ProxyTarget]] 的内部槽,其值是一个对象或 null。该对象称为 proxy 的 target 对象

若一个对象的关键内部方法(若适用包括 [[Call]][[Construct]])使用本节的定义,则该对象为 Proxy 特异对象。这些内部方法在 ProxyCreate 中安装。

Table 32: Proxy 处理器方法 (Proxy Handler Methods)
内部方法 (Internal Method) 处理器方法 (Handler Method)
[[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 对象不一定具备每个关键内部方法对应的 trap;如果缺少对应 trap,则在 proxy 上调用该内部方法会转发到 target 对象上的对应内部方法。

Proxy 对象的 [[ProxyHandler]][[ProxyTarget]] 内部槽在创建时总被初始化,通常不可再修改。某些 Proxy 被创建为可随后被 撤销(revoked)。当一个 proxy 被撤销时,其 [[ProxyHandler]][[ProxyTarget]] 被设为 null,使得后续对该 Proxy 的内部方法调用抛出 TypeError 异常。

由于 Proxy 允许内部方法实现由任意 ECMAScript 代码提供,可能定义出其 handler 方法违反 6.1.7.3 中不变式的 Proxy。该处定义的一些内部方法不变式是关键完整性不变式;本节给出的 Proxy 内部方法会显式强制这些不变式。ECMAScript 实现必须在所有可能的不变式违例情况下保持健壮。

以下算法中,假设 O 为一个 ECMAScript Proxy 对象,P属性键值,V 为任意 ECMAScript 语言值Desc 为一个 Property Descriptor 记录。

10.5.1 [[GetPrototypeOf]] ( )

The [[GetPrototypeOf]] internal method of Proxy 特异对象 O takes no arguments and returns 返回一个包含 Object 或 null正常完成,或一个抛出完成. It performs the following steps when called:

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

Proxy 的 [[GetPrototypeOf]] 强制以下不变式:

  • 结果必须是 Objectnull
  • 若 target 不可扩展,对 Proxy 调用 [[GetPrototypeOf]] 的结果须与对其 target 调用的结果相同。

10.5.2 [[SetPrototypeOf]] ( V )

The [[SetPrototypeOf]] internal method of Proxy 特异对象 O takes argument V (an Object or null) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "setPrototypeOf")。
  6. trapundefined,则
    1. 返回 ? target.[[SetPrototypeOf]](V)。
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, V »))。
  8. booleanTrapResultfalse,返回 false
  9. extensibleTarget 为 ? IsExtensible(target)。
  10. extensibleTargettrue,返回 true
  11. targetProto 为 ? target.[[GetPrototypeOf]]()。
  12. SameValue(V, targetProto) 为 false,抛出 TypeError 异常。
  13. 返回 true
Note

Proxy 的 [[SetPrototypeOf]] 强制以下不变式:

  • 结果是一个 Boolean。
  • 若 target 不可扩展,参数值必须与对 target 调用 [[GetPrototypeOf]] 的结果相同。

10.5.3 [[IsExtensible]] ( )

The [[IsExtensible]] internal method of Proxy 特异对象 O takes no arguments and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "isExtensible")。
  6. trapundefined,则
    1. 返回 ? IsExtensible(target)。
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target »))。
  8. targetResult 为 ? IsExtensible(target)。
  9. booleanTrapResult 不等于 targetResult,抛出 TypeError 异常。
  10. 返回 booleanTrapResult
Note

Proxy 的 [[IsExtensible]] 强制以下不变式:

  • 结果是 Boolean。
  • 对 Proxy 的调用结果必须与对其 target 的调用结果一致。

10.5.4 [[PreventExtensions]] ( )

The [[PreventExtensions]] internal method of Proxy 特异对象 O takes no arguments and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "preventExtensions")。
  6. trapundefined,则
    1. 返回 ? target.[[PreventExtensions]]()
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target »))。
  8. booleanTrapResulttrue,则
    1. extensibleTarget 为 ? IsExtensible(target)。
    2. extensibleTargettrue,抛出 TypeError 异常。
  9. 返回 booleanTrapResult
Note

Proxy 的 [[PreventExtensions]] 强制以下不变式:

  • 结果是 Boolean。
  • 仅当 target 的 [[IsExtensible]]false 时才可返回 true

10.5.5 [[GetOwnProperty]] ( P )

The [[GetOwnProperty]] internal method of Proxy 特异对象 O takes argument P (a property key) and returns 返回一个包含 Property Descriptorundefined正常完成,或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "getOwnPropertyDescriptor")。
  6. trapundefined,则
    1. 返回 ? target.[[GetOwnProperty]](P)。
  7. trapResultObj 为 ? Call(trap, handler, « target, P »)。
  8. trapResultObj 不是 Object 且也不是 undefined,抛出 TypeError 异常。
  9. targetDesc 为 ? target.[[GetOwnProperty]](P)。
  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]] 强制以下不变式:

  • 结果必须是 Objectundefined
  • 若 target 上存在一个不可配置自身属性,不得报告其不存在。
  • 若 target 不可扩展且存在该自身属性,不得报告其不存在。
  • 若 target 不可扩展且不存在该自身属性,不得报告其存在。
  • 不得报告某属性为不可配置,除非它在 target 上为不可配置自身属性。
  • 不得同时报告某属性为不可配置且不可写,除非它在 target 上为不可配置且不可写自身属性。

10.5.6 [[DefineOwnProperty]] ( P, Desc )

The [[DefineOwnProperty]] internal method of Proxy 特异对象 O takes arguments P (a property key) and Desc (a Property Descriptor) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "defineProperty")。
  6. trapundefined,则
    1. 返回 ? target.[[DefineOwnProperty]](P, Desc)。
  7. descObjFromPropertyDescriptor(Desc)。
  8. booleanTrapResultToBoolean(? Call(trap, handler, « target, P, descObj »))。
  9. booleanTrapResultfalse,返回 false
  10. targetDesc 为 ? target.[[GetOwnProperty]](P)。
  11. extensibleTarget 为 ? IsExtensible(target)。
  12. Desc[[Configurable]]Desc.[[Configurable]]false,则
    1. settingConfigFalsetrue
  13. 否则,
    1. settingConfigFalsefalse
  14. targetDescundefined,则
    1. extensibleTargetfalse,抛出 TypeError 异常。
    2. settingConfigFalsetrue,抛出 TypeError 异常。
  15. 否则,
    1. IsCompatiblePropertyDescriptor(extensibleTarget, Desc, targetDesc) 为 false,抛出 TypeError 异常。
    2. settingConfigFalsetruetargetDesc.[[Configurable]]true,抛出 TypeError 异常。
    3. IsDataDescriptor(targetDesc) 为 truetargetDesc.[[Configurable]]falsetargetDesc.[[Writable]]true,则
      1. Desc[[Writable]]Desc.[[Writable]]false,抛出 TypeError 异常。
  16. 返回 true
Note

Proxy 的 [[DefineOwnProperty]] 强制以下不变式:

  • 结果为 Boolean。
  • 若 target 不可扩展,不得添加新属性。
  • 不得创建不可配置属性,除非 target 上已有对应不可配置自身属性。
  • 不得创建既不可配置又不可写属性,除非 target 上已有对应不可配置且不可写自身属性。
  • 若属性在 target 上已有对应属性,则用给定描述符通过 [[DefineOwnProperty]] 作用于 target 不会抛出异常。

10.5.7 [[HasProperty]] ( P )

The [[HasProperty]] internal method of Proxy 特异对象 O takes argument P (a property key) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "has")。
  6. trapundefined,则
    1. 返回 ? target.[[HasProperty]](P)。
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, P »))。
  8. booleanTrapResultfalse,则
    1. targetDesc 为 ? target.[[GetOwnProperty]](P)。
    2. targetDesc 不为 undefined,则
      1. targetDesc.[[Configurable]]false,抛出 TypeError 异常。
      2. extensibleTarget 为 ? IsExtensible(target)。
      3. extensibleTargetfalse,抛出 TypeError 异常。
  9. 返回 booleanTrapResult
Note

Proxy 的 [[HasProperty]] 强制以下不变式:

  • 结果为 Boolean。
  • 若 target 上存在不可配置自身属性,不得报告其不存在。
  • 若 target 不可扩展且存在该自身属性,不得报告其不存在。

10.5.8 [[Get]] ( P, Receiver )

The [[Get]] internal method of Proxy 特异对象 O takes arguments P (a property key) and Receiver (an ECMAScript language value) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "get")。
  6. trapundefined,则
    1. 返回 ? target.[[Get]](P, Receiver)。
  7. trapResult 为 ? Call(trap, handler, « target, P, Receiver »)。
  8. targetDesc 为 ? target.[[GetOwnProperty]](P)。
  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 上对应属性为不可配置自身访问器属性且其 [[Get]]undefined,则读取结果必须为 undefined

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

The [[Set]] internal method of Proxy 特异对象 O takes arguments P (a property key), V (an ECMAScript language value), and Receiver (an ECMAScript language value) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "set")。
  6. trapundefined,则
    1. 返回 ? target.[[Set]](P, V, Receiver)。
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, P, V, Receiver »))。
  8. booleanTrapResultfalse,返回 false
  9. targetDesc 为 ? target.[[GetOwnProperty]](P)。
  10. targetDesc 不为 undefinedtargetDesc.[[Configurable]]false,则
    1. IsDataDescriptor(targetDesc) 为 truetargetDesc.[[Writable]]false,则
      1. SameValue(V, targetDesc.[[Value]]) 为 false,抛出 TypeError 异常。
    2. IsAccessorDescriptor(targetDesc) 为 true,则
      1. targetDesc.[[Set]]undefined,抛出 TypeError 异常。
  11. 返回 true
Note

Proxy 的 [[Set]] 强制以下不变式:

  • 结果为 Boolean。
  • 若 target 上对应属性为不可写且不可配置的数据属性,不得改为不同的值。
  • 若 target 上对应属性为不可配置自身访问器属性且其 [[Set]]undefined,不得设置该属性值。

10.5.10 [[Delete]] ( P )

The [[Delete]] internal method of Proxy 特异对象 O takes argument P (a property key) and returns 返回一个包含 Boolean 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "deleteProperty")。
  6. trapundefined,则
    1. 返回 ? target.[[Delete]](P)。
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, P »))。
  8. booleanTrapResultfalse,返回 false
  9. targetDesc 为 ? target.[[GetOwnProperty]](P)。
  10. targetDescundefined,返回 true
  11. targetDesc.[[Configurable]]false,抛出 TypeError 异常。
  12. extensibleTarget 为 ? IsExtensible(target)。
  13. extensibleTargetfalse,抛出 TypeError 异常。
  14. 返回 true
Note

Proxy 的 [[Delete]] 强制以下不变式:

  • 结果为 Boolean。
  • 若属性在 target 上是不可配置自身属性,不得报告其已删除。
  • 若属性在 target 上是自身属性且 target 不可扩展,不得报告其已删除。

10.5.11 [[OwnPropertyKeys]] ( )

The [[OwnPropertyKeys]] internal method of Proxy 特异对象 O takes no arguments and returns 返回一个包含属性键列表的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[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属性键列表。
  13. 断言:targetKeys 不含重复项。
  14. targetConfigurableKeys 为新空列表。
  15. targetNonconfigurableKeys 为新空列表。
  16. targetKeys 中每个元素 key
    1. desc 为 ? target.[[GetOwnProperty]](key)。
    2. desc 不为 undefineddesc.[[Configurable]]false,则
      1. key 追加至 targetNonconfigurableKeys
    3. 否则,
      1. key 追加至 targetConfigurableKeys
  17. extensibleTargettruetargetNonconfigurableKeys 为空,则
    1. 返回 trapResult
  18. uncheckedResultKeys 为包含 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]] 强制以下不变式:

  • 结果是一个列表。
  • 返回列表不含重复项。
  • 列表中每个元素都是属性键
  • 列表必须包含 target 所有不可配置自身属性的键。
  • 若 target 不可扩展,则列表必须精确包含其全部自身属性键且不含其他值。

10.5.12 [[Call]] ( thisArgument, argumentsList )

The [[Call]] internal method of Proxy 特异对象 O takes arguments thisArgument (an ECMAScript language value) and argumentsList (a List of ECMAScript language values) and returns 返回一个包含 ECMAScript 语言值正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言:handler 是一个 Object。
  5. trap 为 ? GetMethod(handler, "apply")。
  6. trapundefined,则
    1. 返回 ? Call(target, thisArgument, argumentsList)。
  7. argArrayCreateArrayFromList(argumentsList)。
  8. 返回 ? Call(trap, handler, « target, thisArgument, argArray »)。
Note

仅当 [[ProxyTarget]] 初始值是一个具有 [[Call]] 内部方法的对象时,Proxy 特异对象才具有 [[Call]]

10.5.13 [[Construct]] ( argumentsList, newTarget )

The [[Construct]] internal method of Proxy 特异对象 O takes arguments argumentsList (a List of ECMAScript language values) and newTarget (a constructor) and returns 返回一个包含 Object 的正常完成或一个抛出完成. It performs the following steps when called:

  1. 执行 ? ValidateNonRevokedProxy(O)。
  2. targetO.[[ProxyTarget]]
  3. 断言:IsConstructor(target) 为 true
  4. handlerO.[[ProxyHandler]]
  5. 断言:handler 是一个 Object。
  6. trap 为 ? GetMethod(handler, "construct")。
  7. trapundefined,则
    1. 返回 ? Construct(target, argumentsList, newTarget)。
  8. argArrayCreateArrayFromList(argumentsList)。
  9. newObj 为 ? Call(trap, handler, « target, argArray, newTarget »)。
  10. newObj 不是 Object,抛出 TypeError 异常。
  11. 返回 newObj
Note 1

仅当 [[ProxyTarget]] 初始值是一个具有 [[Construct]] 内部方法的对象时,Proxy 特异对象才具有 [[Construct]]

Note 2

Proxy 的 [[Construct]] 强制以下不变式:

  • 结果必须是一个 Object。

10.5.14 ValidateNonRevokedProxy ( proxy )

The abstract operation ValidateNonRevokedProxy takes argument proxy (a Proxy exotic object) and returns 返回一个包含 unused正常完成或一个抛出完成. 若 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 返回一个包含 Proxy 特异对象正常完成或一个抛出完成. 用于指定创建新的 Proxy 对象。 It performs the following steps when called:

  1. target 不是 Object,抛出 TypeError 异常。
  2. handler 不是 Object,抛出 TypeError 异常。
  3. PMakeBasicObject[[ProxyHandler]], [[ProxyTarget]] »)。
  4. 设置 P 的关键内部方法(除 [[Call]][[Construct]])为 10.5 中的定义。
  5. IsCallable(target) 为 true,则
    1. 10.5.12 设置 P.[[Call]]
    2. IsConstructor(target) 为 true,则
      1. 10.5.13 设置 P.[[Construct]]
  6. P.[[ProxyTarget]] 设为 target
  7. P.[[ProxyHandler]] 设为 handler
  8. 返回 P