このページはECMAScript® 2020 Language Specification9 Ordinary and Exotic Objects Behaviours章をJavaScriptの学習目的で私的に日本語訳したものであり、直訳と意訳および推測が混在しています。そのため内容については正確ではない可能性があります。正確な情報を知りたい場合は、原文をご覧ください。また一部訳者によるコメントが含まれていることがあります。※このサイトの内容で損害や不利益を受けたとしても当方は一切の責任を負いません。

9.1 通常のオブジェクトの内部メソッドと内部スロット(Ordinary Object Internal Methods and Internal Slots)

すべての通常のオブジェクトには、[[Prototype]]という内部スロットがあります。 この内部スロットの値はnullまたはオブジェクトであり、継承の実装に使用されます。 [[Prototype]]オブジェクトのデータプロパティは、取得アクセスは継承されます(子オブジェクトのプロパティとして表示されます)が、セットアクセスは継承されません。 アクセサプロパティは、取得アクセスとセットアクセスの両方で継承されます。

    const a =function () {};
    a.prototype.b=1;

    const b = new a();
    console.log( a.prototype.b , b.b); // 1 , 1(データプロパティ取得アクセス)
    b.b = 3; // データプロパティセットアクセス
    console.log( a.prototype.b , b.b); // 1 , 3 オブジェクトbに新規でプロパティbが作成された

すべての通常のオブジェクトにはブール値[[Extensible]]内部スロットがあり、6.1.7.3で指定された拡張性関連の内部メソッドの不変条件を満たすために使用されます。 つまり、オブジェクトの[[Extensible]]内部スロットの値がfalseに設定されると、オブジェクトにプロパティを追加したり、オブジェクトの[[Prototype]]内部スロットの値を変更したり、[[Extensible]]の値をtrueに変更できなくなります。

次のアルゴリズムの説明では、O が通常のオブジェクト、P がプロパティキー値、V がECMAScript言語値、および Desc がプロパティ記述子レコードであると想定しています。

通常のオブジェクトの内部メソッドは、同じ名前の抽象操作に委譲します。 同じ名前の抽象操作が別の内部メソッドに依存している場合、同じ名前の抽象操作を直接呼び出すのではなく、O で内部メソッドが呼び出されます。 これらのセマンティクスは、通常のオブジェクトの内部メソッドが適用されたときに、エキゾチックオブジェクトがオーバーライドされた内部メソッドを確実に呼び出すようにします。

9.1.1 [[GetPrototypeOf]] ( )

O の[[GetPrototypeOf]]内部メソッドが呼び出されると、次の手順が実行されます。

9.1.1.1 OrdinaryGetPrototypeOf ( O )

抽象操作OrdinaryGetPrototypeOfがオブジェクトOで呼び出されると、次の手順が実行されます。

  1. O.[[Prototype]]を返す

9.1.2 [[SetPrototypeOf]] ( V )

引数 V を指定して O の[[SetPrototypeOf]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. ! OrdinarySetPrototypeOf(O, V)を返す

9.1.2.1 OrdinarySetPrototypeOf ( O, V )

抽象演算OrdinarySetPrototypeOfがオブジェクト O と値 V で呼び出されると、次の手順が実行されます。

  1. Assert: Type(V) は Object型か Null
  2. O.[[Prototype]] を current とする
  3. SameValue(V, current) が true なら、true を返す
  4. O.[[Extensible]] を extensible とする
  5. extensiblefalse なら、 false を返す
  6. Vp とする
  7. falsedone とする
  8. donefalse の間繰り返す
    1. pnull なら truedone にセットする
    2. a.ではなく SameValue(p, O) が true なら false を返す
    3. a. b.でなければ、
      1. p.[[GetPrototypeOf]] の実体が 9.1.1で定義している 通常のオブジェクトの内部メソッド[[GetPrototypeOf]]と異なるなら、 true を done にセット
      2. 上と異なるなら、 p.[[Prototype]] を p にセット
  9. VO.[[Prototype]] にセットする
  10. trueを返す
ステップ8のループは、[[GetPrototypeOf]]および[[SetPrototypeOf]]の通常のオブジェクト定義を使用するオブジェクトのみを含むプロトタイプチェーンに循環が発生しないことを保証します。

9.1.3 [[IsExtensible]] ( )

O の[[IsExtensible]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. ! OrdinaryIsExtensible(O)を返す

9.1.3.1 OrdinaryIsExtensible ( O )

抽象操作OrdinaryIsExtensibleがオブジェクト O で呼び出されると、次の手順が実行されます。

  1. O.[[Extensible]]を返す

9.1.4 [[PreventExtensions]] ( )

Oの[[PreventExtensions]]内部メソッドが呼び出されると、次の手順が実行されます。

9.1.4.1 OrdinaryPreventExtensions ( O )

抽象操作OrdinaryPreventExtensionsがオブジェクト O で呼び出されると、次の手順が実行されます。

  1. falseO.[[Extensible]] にセットする
  2. true を返す

9.1.5 [[GetOwnProperty]] ( P )

O の[[GetOwnProperty]]内部メソッドがプロパティキーP で呼び出されると、次の手順が実行されます。

  1. ! OrdinaryGetOwnProperty(O, P)を返す

9.1.5.1 OrdinaryGetOwnProperty ( O, P )

抽象操作OrdinaryGetOwnPropertyがオブジェクトO とプロパティキーP で呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. O に キーP に対応する 所有プロパティ がないなら、undefined を返す
  3. フィールドなしで新規作成したプロパティ記述子D とする
  4. キーP に対応する O の 所有プロパティX とする
  5. Xデータプロパティ なら
    1. X の [[Value]] 属性値 を D.[[Value]] にセットする
    2. X の [[Writable]] 属性値 を D.[[Writable]] にセットする
  6. 5.と異なるなら
    1. Assert: X はアクセサプロパティ
    2. X の [[Get]] 属性値 を D.[[Get]] にセットする
    3. X の [Set]] 属性値 を D.[[Set]] にセットする
  7. X の [[Enumerable]] 属性値 を D.[[Enumerable]] にセットする
  8. X の [[Configurable]] 属性値 を D.[[Configurable]] にセットする
  9. Dを返す

9.1.6 [[DefineOwnProperty]] ( P, Desc )

O の[[DefineOwnProperty]]内部メソッドがプロパティキーP とプロパティ記述子Desc で呼び出されると、次の手順が実行されます。

  1. ? OrdinaryDefineOwnProperty(O, P, Desc)を返す

9.1.6.1 OrdinaryDefineOwnProperty ( O, P, Desc )

抽象操作OrdinaryDefineOwnPropertyがオブジェクトO、プロパティキーP、およびプロパティ記述子Desc で呼び出されると、次の手順が実行されます。

  1. ? O.[[GetOwnProperty]](P) を current とする
  2. ? IsExtensible(O) を extensible とする
  3. ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current)を返す

9.1.6.2 IsCompatiblePropertyDescriptor ( Extensible, Desc, Current )

抽象演算IsCompatiblePropertyDescriptorがブール値Extensible、プロパティ記述子Desc、およびCurrent で呼び出されると、次の手順が実行されます。

  1. ValidateAndApplyPropertyDescriptor(undefined, undefined, Extensible, Desc, Current)を返す

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

抽象操作ValidateAndApplyPropertyDescriptorがオブジェクトO、プロパティキーP、ブール値extensible、プロパティ記述子Desc、およびcurrentで呼び出されると、次の手順が実行されます。

Oundefinedが渡された場合、検証のみが実行され、オブジェクトは更新されません。
  1. Assert: Oundefined でないなら IsPropertyKey(P) は true
  2. currentundefined なら、
    1. extensiblefalse なら、 false を返す
    2. Assert: extensibletrue
    3. IsGenericDescriptor(Desc) が true または IsDataDescriptor(Desc) が true なら
      1. Oundefined でないなら、O に Pという名前のデータプロパティする。Desc を元に、作成したプロパティの [[Value]]、[[Writable]]、[[Enumerable]]、[[Configurable]] 属性をセットする。Desc に目的のフィールドが存在しないなら、デフォルト値(表5)をセットする
    4. c.でないなら
      1. Assert: ! IsAccessorDescriptor(Desc) は true
      2. Oundefined でないなら、O に P という名前の アクセサプロパティ を作成する。Desc を元に、作成したプロパティの [[Get]]、[[Set]]、[[Enumerable]]、[[Configurable]] 属性をセットする。 Desc に目的のフィールドが存在しないなら、デフォルト値(表5)をセットする
    5. true を返す
  3. Desc にフィールドがないなら、true を返す
  4. current.[[Configurable]] が false なら、
    1. Desc.[[Configurable]] が存在していて、 その値が true なら、 false を返す
    2. Desc.[[Enumerable]] が存在していて、 ! SameValue(Desc.[[Enumerable]], current.[[Enumerable]]) が false なら、 false を返す
  5. ! IsGenericDescriptor(Desc) が true なら、
    1. NOTE: これ以上の検証は不要
  6. 5.でなく、 ! SameValue(! IsDataDescriptor(current), ! IsDataDescriptor(Desc)) が false なら
    1. current.[[Configurable]] が false なら、 false を返す
    2. IsDataDescriptor(current) が true なら、
      1. Oundefined でないなら、OP という名前のプロパティを、データプロパティからアクセサプロパティに変換する。変換されたプロパティの[[Configurable]]と[[Enumerable]]属性の既存値を保持し、残りの属性をデフォルト値(表5)で設定する。
    3. b.でなければ
      1. Oundefined でないなら、OP という名前のプロパティを、アクセサプロパティからデータプロパティに変換する。変換されたプロパティの [[Configurable]] と [[Enumerable]]属性の既存値を保持し、残りの属性をデフォルト値(表5)で設定する。
  7. 5. 6.でなく IsDataDescriptor(current) と IsDataDescriptor(Desc) が true なら、
    1. current.[[Configurable]] が falsecurrent.[[Writable]] が false なら、
      1. Desc.[[Writable]] が存在していて Desc.[[Writable]] が true なら、 false を返す
      2. Desc.[[Value]] が存在していて SameValue(Desc.[[Value]], current.[[Value]]) が false なら、 false を返す
      3. true を返す
  8. 5. 6. 7.でないなら
    1. Assert: ! IsAccessorDescriptor(current) と ! IsAccessorDescriptor(Desc) は true
    2. current.[[Configurable]] が false なら、
      1. Desc.[[Set]] が存在していて SameValue(Desc.[[Set]], current.[[Set]]) が false なら、 false を返す
      2. Desc.[[Get]] が存在していて SameValue(Desc.[[Get]], current.[[Get]]) が false なら、false を返す
      3. true を返す
  9. Oundefined でないなら、
    1. Descの存在している各フィールドを、O の P という名前のプロパティの対応する属性フィールドにセットする
  10. true を返す

9.1.7 [[HasProperty]] ( P )

O の[[HasProperty]]内部メソッドがプロパティキーP で呼び出されると、次の手順が実行されます。

  1. ? OrdinaryHasProperty(O, P)を返す

9.1.7.1 OrdinaryHasProperty ( O, P )

抽象演算OrdinaryHasPropertyがオブジェクトOとプロパティキーPで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. ? O.[[GetOwnProperty]](P) を hasOwn とする
  3. hasOwnundefined でないなら、 true を返す
  4. ? O.[[GetPrototypeOf]]() を parent とする
  5. parentnull でないなら、
    1. ? parent.[[HasProperty]](P)を返す
  6. false を返す

9.1.8 [[Get]] ( P, Receiver )

O の[[Get]]内部メソッドがプロパティキーPおよびECMAScript言語値Receiverで呼び出されると、次の手順が実行されます。

  1. ? OrdinaryGet(O, P, Receiver)を返す

9.1.8.1 OrdinaryGet ( O, P, Receiver )

抽象操作OrdinaryGetがオブジェクトO、プロパティキーP、ECMAScript言語値Receiverで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. ? O.[[GetOwnProperty]](P) を desc とする
  3. descundefined なら、
    1. ? O.[[GetPrototypeOf]]() を parent とする
    2. parentnull なら undefined を返す
    3. ? parent.[[Get]](P, Receiver)を返す
  4. IsDataDescriptor(desc) が true なら、 desc.[[Value]]を返す
  5. Assert: IsAccessorDescriptor(desc) は true
  6. desc.[[Get]] を getter とする
  7. getterundefined なら、 undefined を返す
  8. ? Call(getter, Receiver)を返す

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

Oの[[Set]]内部メソッドがプロパティキーP、値V、およびECMAScript言語値Receiverで呼び出されると、次の手順が実行されます。

  1. ? OrdinarySet(O, P, V, Receiver)を返す

9.1.9.1 OrdinarySet ( O, P, V, Receiver )

抽象操作OrdinarySetがオブジェクトO、プロパティキーP、値V、およびECMAScript言語値Receiverで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. ? O.[[GetOwnProperty]](P) を ownDesc とする
  3. OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc)を返す

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

抽象演算OrdinarySetWithOwnDescriptorが、オブジェクトO、プロパティキーP、値V、ECMAScript言語値Receiver、およびプロパティ記述子(またはundefined)のownDescで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. ownDescundefined なら、
    1. ? O.[[GetPrototypeOf]]() を parent とする
    2. parentnull でないなら、
      1. ? parent.[[Set]](P, V, Receiver)を返す
    3. b. でないなら
      1. PropertyDescriptor型{ [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true } を ownDesc にセットする
  3. IsDataDescriptor(ownDesc) が true なら、
    1. ownDesc.[[Writable]] が false なら、false を返す
    2. Type(Receiver) Object型でないなら、 false を返す
    3. ? Receiver.[[GetOwnProperty]](P) を existingDescriptor とする
    4. existingDescriptorundefined なら、
      1. IsAccessorDescriptor(existingDescriptor) が true なら、false を返す
      2. existingDescriptor.[[Writable]] が false なら、false を返す
      3. PropertyDescriptor型 { [[Value]]: V } を valueDesc とする
      4. ? Receiver.[[DefineOwnProperty]](P, valueDesc)を返す
    5. d. でないなら
      1. Assert: ReceiverにはプロパティPがない
      2. ? CreateDataProperty(Receiver, P, V)を返す
  4. Assert: IsAccessorDescriptor(ownDesc) は true
  5. ownDesc.[[Set]] を setter とする
  6. setterundefined なら、false を返す
  7. ?Call(setter, Receiver, « V »)を実行
  8. true を返す

9.1.10 [[Delete]] ( P )

プロパティキーPを使用してOの[[Delete]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. ? OrdinaryDelete(O, P)を返す

9.1.10.1 OrdinaryDelete ( O, P )

抽象操作OrdinaryDeleteがオブジェクトOとプロパティキーPで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. ? O.[[GetOwnProperty]](P) を desc とする
  3. descundefined なら、true を返す
  4. desc.[[Configurable]] が true なら、
    1. OからPという名前の独自プロパティを削除する
    2. true を返す.
  5. false を返す.

9.1.11 [[OwnPropertyKeys]] ( )

Oの[[OwnPropertyKeys]]内部メソッドが呼び出されると、次の手順が実行されます。

9.1.11.1 OrdinaryOwnPropertyKeys ( O )

抽象操作OrdinaryOwnPropertyKeysがオブジェクトOで呼び出されると、次の手順が実行されます。

  1. 空の新規Listkeys とする
  2. O独自プロパティキーで配列インデックスとして有効なものをPとし、昇順で次をおこなう。
    1. keysの最後の要素としてPを追加する
  3. O独自プロパティキーのうちType(プロパティキー) が String型で配列インデックスではないものをPとして、プロパティ作成時系列の昇順で、次をおこなう。
    1. keysの最後の要素としてPを追加する
  4. O独自プロパティキーのうちType(プロパティキー) が Symbol型のものをPとして、プロパティ作成時系列の昇順で、次をおこなう。
    1. keysの最後の要素としてPを追加する
  5. keysを返す

9.1.12 OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] )

オブジェクトproto(またはnull)を持つ抽象オペレーションOrdinaryObjectCreateは、ランタイムで新しい通常のオブジェクトを作成します。 オプションの引数additionalInternalSlotsListは、[[Prototype]]および[[Extensible]]の他に、オブジェクトの一部として追加する内部スロットの名前のリストです。 リストが提供されない場合、新しい空のリストが使用されます。 この抽象操作は次の手順を実行します。

  1. « [[Prototype]], [[Extensible]] »internalSlotsList とする
  2. additionalInternalSlotsList が存在するなら、 各要素をinternalSlotsListに追加する
  3. ! MakeBasicObject(internalSlotsList) を O とする
  4. protoO.[[Prototype]] にセットする
  5. Oを返す
OrdinaryObjectCreateはMakeBasicObjectを呼び出すだけですが、エキゾチックなオブジェクトではなく、通常のオブジェクトを作成する意図を伝えています。この仕様内では、内部メソッドを後で変更する目的で呼び出されることはありません。 エキゾチックなオブジェクトを作成する場合、MakeBasicObjectを直接呼び出します。

9.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )

抽象オペレーションOrdinaryCreateFromConstructorは、constructor"prototype"プロパティが存在する場合、そのプロパティ値が[[Prototype]]に使用された通常のオブジェクトを作成します。 それ以外の場合、[[Prototype]]には、intrinicDefaultProtoで指定された組み込みオブジェクトが使用されます。 オプションのinternalSlotsListは、オブジェクトの一部として追加する内部スロット名のリストです。 リストが提供されない場合、新しい空のリストが使用されます。 この抽象操作は次の手順を実行します。

  1. Assert: intrinsicDefaultProto はString値で、この仕様の組み込みオブジェクトの名前。 対応するオブジェクトは、オブジェクトの[[Prototype]]値として使用するための組み込み関数である必要がある。
  2. ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto) を proto とする
  3. OrdinaryObjectCreate(proto, internalSlotsList)を返す

9.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )

抽象操作GetPrototypeFromConstructorは、constructorに対応するオブジェクトを作成するために必要な[[Prototype]]値を取得します。 constructor"prototype"プロパティが存在する場合、そのプロパティが使用されます。 それ以外の場合、[[Prototype]]は、intrinicDefaultProtoで指定された組み込みオブジェクトが使用されます。 この抽象操作は次の手順を実行します。

  1. Assert:intrinsicDefaultProto はString値で、この仕様の組み込みオブジェクトの名前。 対応するオブジェクトは、オブジェクトの[[Prototype]]値として使用するための組み込み関数である必要がある。
  2. Assert: IsCallable(constructor) は true
  3. ? Get(constructor, "prototype") を proto とする
  4. Type(proto) が Object型でないなら、
    1. ? GetFunctionRealm(constructor) を realm とする
    2. intrinsicDefaultProtoという名前のrealmの組み込みオブジェクト を proto にセットする
  5. protoを返す
constructor が[[Prototype]]値を提供しない場合、使用されるデフォルト値は、実行中の実行コンテキストからではなく、constructor関数のレルムから取得されます。

9.1.15 RequireInternalSlot ( O, internalSlot )

抽象演算RequireInternalSlotは、オブジェクトOが、指定された内部スロットを持たないとき、例外をスローします。

  1. Type(O) が Object型でないなら、 TypeError例外をスローする.
  2. OinternalSlotという内部スロットを持っていないなら、 TypeError例外をスローする

9.2 ECMAScript関数オブジェクト(ECMAScript Function Objects)

strict関数

非strict関数

ECMAScript関数オブジェクトは、レキシカル環境で閉じられパラメーター化されたECMAScriptコードをカプセル化し、そのコードの動的評価をサポートします。 ECMAScript関数オブジェクトは通常のオブジェクトであり、他の通常のオブジェクトと同じ内部スロットと内部メソッドを持っています。 ECMAScript関数オブジェクトのコードは、strict(厳密)モードコード(10.2.1)または非strictコードのいずれかです。 strictモードのコードであるECMAScript関数オブジェクトは、strict関数と呼ばれます。 strictモードのコードではないコードは、非strict関数と呼ばれます。

[[Extensible]]と[[Prototype]]に加えて、ECMAScript関数オブジェクトには、表27に示す内部スロットがあります。

表27: ECMAScript関数オブジェクトの内部スロット
内部スロット 内容
[[Environment]] レキシカル環境 関数で閉じられたレキシカル環境。 関数内のコードを評価するときに外部環境として使用されます。
[[FormalParameters]] パースノード 関数の仮パラメーターリストを定義するソーステキストのルートパースノード。
[[ECMAScriptCode]] パースノード 関数の本体を定義するソーステキストのルートパースノード。
[[ConstructorKind]] base | derived 関数が派生クラスコンストラクターかどうか。
[[Realm]] レルムレコード 関数が作成され、評価時にアクセスされる組み込みオブジェクトを提供するレルム。
[[ScriptOrModule]] スクリプトレコード または モジュールレコード 関数を作成したスクリプトまたはモジュール。
[[ThisMode]] lexical |
strict |
global
this参照が、関数の仮パラメーターとコード本体内でどのように解釈されるかを定義します。 lexicalは、thisが字句的に囲まれた関数のthis値を参照することを意味します。 strictは、this値が関数の呼び出しによって提供されたとおりに使用されることを意味します。 globalは、undefinedがグローバルオブジェクトへの参照として解釈されることを意味します。
[[Strict]] Boolean strict関数である場合はtrue非strict関数である場合はfalse
[[HomeObject]] Object 関数がsuperを使用する場合、[[HomeObject]]はsuperプロパティのルックアップが開始されるオブジェクトを[[GetPrototypeOf]]が提供するオブジェクトです。
[[SourceText]] Unicodeコードポイントのシーケンス 関数を定義するソーステキスト
[[IsClassConstructor]] Boolean 関数がクラスコンストラクタかどうかを示します。 (trueの場合、関数の[[Call]]を呼び出すとTypeError例外がスローされます。)

すべてのECMAScript関数オブジェクトには[[Call]]内部メソッドがあり、ここで定義しています。 さらにコンストラクタでもあるECMAScript関数には、[[Construct]]内部メソッドがあります。

9.2.1 [[Call]] ( thisArgument, argumentsList )

ECMAScript関数オブジェクトFの[[Call]]内部メソッドは、パラメーターthisArgumentargumentsList(ECMAScript言語値のリスト)で呼び出されます。 次の手順を実行します。

  1. Assert: F は ECMAScript関数オブジェクト
  2. F.[[IsClassConstructor]] が true なら、 TypeError例外をスローする.
  3. 実行中の実行コンテキストcallerContext とする
  4. PrepareForOrdinaryCall(F, undefined) を calleeContext とする
  5. Assert: calleeContext実行中の実行コンテキスト
  6. OrdinaryCallBindThis(F, calleeContext, thisArgument)を実行
  7. OrdinaryCallEvaluateBody(F, argumentsList) を result とする
  8. 実行コンテキストスタック からcalleeContext を削除し、callerContext実行中の実行コンテキスト として復元します
  9. result.[[Type]] が return なら、NormalCompletion(result.[[Value]])を返す
  10. ReturnIfAbrupt(result).
  11. NormalCompletion(undefined)を返す

手順8で実行コンテキストスタックから削除されたcalleeContextは、次のとき破棄しないでください。

  • アクセス可能なジェネレーターオブジェクトによって後で再開できるように中断および保持されている

9.2.1.1 PrepareForOrdinaryCall ( F, newTarget )

抽象操作PrepareForOrdinaryCallが関数オブジェクトFとECMAScript言語値newTargetで呼び出されると、次の手順が実行されます。

  1. Assert: Type(newTarget) は Undefined または Object型
  2. 実行中の実行コンテキストcallerContext とする
  3. 新しい ECMAScriptコード実行コンテキストcalleeContext とする
    非常に分かりにくいが、2は、callerContext 、 3は、calleeContext
  4. FcalleeContext関数コンポーネント にセットする
  5. F.[[Realm]] を calleeRealm とする
  6. calleeRealmcalleeContextレルムコンポーネント にセットする
  7. F.[[ScriptOrModule]] をcalleeContextScriptOrModuleコンポーネント にセットする
  8. NewFunctionEnvironment(F, newTarget) を localEnv とする
  9. localEnvcalleeContextLexicalEnvironmentコンポーネントにセットする
  10. localEnvcalleeContextVariableEnvironmentコンポーネント にセットする
  11. callerContext が 中断していないなら、callerContextを中断する
  12. calleeContext実行コンテキストスタック にプッシュする。 calleeContext実行中の実行コンテキスト になる。
  13. NOTE: これ以降に生成される例外オブジェクトは、calleeRealmに関連付けられる。
  14. calleeContextを返す

9.2.1.2 OrdinaryCallBindThis ( F, calleeContext, thisArgument )

抽象操作OrdinaryCallBindThisが関数オブジェクトF、実行コンテキストcalleeContext、およびECMAScript値thisArgumentで呼び出されると、次の手順が実行されます。

  1. F.[[ThisMode]] を thisMode とする
  2. thisModelexical なら、 NormalCompletion(undefined)を返す
  3. F.[[Realm]] を calleeRealm とする
  4. calleeContext の LexicalEnvironmentコンポーネントlocalEnv とする
  5. thisModestrict なら、 thisArgumentthisValue とする
  6. 5.でないなら
    1. thisArgumentundefinednullなら、
      1. calleeRealm.[[GlobalEnv]] を globalEnv とする
      2. globalEnvEnvironmentRecordglobalEnvRec とする
      3. Assert: globalEnvRecグローバル環境レコード
      4. globalEnvRec.[[GlobalThisValue]] を thisValue とする
    2. a.と異なるなら
      1. ! ToObject(thisArgument) を thisValue とする
      2. NOTE: ToObjectは、calleeRealmを使用してラッパーオブジェクトを生成する
  7. localEnv の EnvironmentRecordenvRec とする
  8. Assert: envRec関数環境レコード
  9. Assert: envRec.[[ThisBindingStatus]] が初期化されていないため、次のステップで突然の完了が返ることはない
  10. envRec.BindThisValue(thisValue)を返す

9.2.1.3 OrdinaryCallEvaluateBody ( F, argumentsList )

抽象操作OrdinaryCallEvaluateBodyが関数オブジェクトFargumentsListで呼び出されると、次の手順が実行されます。

  1. FargumentsListを引数として渡したF.[[ECMAScriptCode]]である解析済みコードのEvaluateBodyの結果を返します。

9.2.2 [[Construct]] ( argumentsList, newTarget )

ECMAScript関数オブジェクトFの[[Construct]]内部メソッドは、argumentsListおよびnewTargetパラメータを使用して呼び出されます。 argumentsListは、おそらく空のECMAScript言語値のリストです。 次の手順を実行します。

  1. Assert: F はECMAScript関数オブジェクト
  2. Assert: Type(newTarget) は Object型
  3. 実行中の実行コンテキストcallerContext とする
  4. F.[[ConstructorKind]] を kind とする
  5. kindbase なら、
    1. ? OrdinaryCreateFromConstructor(newTarget, "%Object.prototype%") を thisArgument とする
  6. PrepareForOrdinaryCall(F, newTarget) を calleeContext とする
  7. Assert: calleeContext実行中の実行コンテキスト
  8. kindbase なら、 OrdinaryCallBindThis(F, calleeContext, thisArgument)を実行する
  9. calleeContext の LexicalEnvironmentconstructorEnv とする
  10. constructorEnv の EnvironmentRecordenvRec とする
  11. OrdinaryCallEvaluateBody(F, argumentsList) を result とする
  12. 実行コンテキストスタック から calleeContext を削除し、実行中の実行コンテキスト として callerContext を復元する
  13. result.[[Type]] が return なら、
    1. Type(result.[[Value]]) が Object型なら、NormalCompletion(result.[[Value]])を返す
    2. kindbase なら、NormalCompletion(thisArgument)を返す
    3. result.[[Value]] が undefined でないなら、 TypeError例外をスローする
  14. 13.でないなら ReturnIfAbrupt(result)
  15. ? envRec.GetThisBinding()を返す

9.2.3 OrdinaryFunctionCreate ( functionPrototype, ParameterList, Body, thisMode, Scope )

抽象操作OrdinaryFunctionCreateは、5つの引数をとります。オブジェクトfunctionPrototype、パラメーターリストのパースノードParameterList、本文のパースノードBodylexical-thisまたはnon-lexical-thisthisMode、およびレキシカル環境Scope 。 OrdinaryFunctionCreateは、次の手順を実行します。

  1. Assert: Type(functionPrototype) は Object型
  2. 表27 の内部スロットのリスト を internalSlotsList とする
  3. ! OrdinaryObjectCreate(functionPrototype, internalSlotsList) を F とする
  4. 9.2.1 で定義しているコードを F.[[Call]] にセットする
  5. ParameterListF.[[FormalParameters]] にセットする
  6. BodyF.[[ECMAScriptCode]] にセットする
  7. Body一致するソーステキストがstrictモードコードなら true を、異なるなら false を strict とする
  8. StrictF.[[Strict]] にセットする
  9. thisModelexical-this なら、 lexicalF.[[ThisMode]] にセットする
  10. 9.ではなく Stricttrue なら、strictF.[[ThisMode]] にセットする
  11. 9. 10. ではないなら、 globalF.[[ThisMode]] にセットする
  12. falseF.[[IsClassConstructor]] にセットする
  13. ScopeF.[[Environment]] にセットする
  14. GetActiveScriptOrModule() を F.[[ScriptOrModule]] にセットする
  15. 現在のレルムレコードF.[[Realm]] にセットする
  16. undefinedF.[[HomeObject]] にセットする
  17. ParameterList の ExpectedArgumentCount を len とする
  18. ! SetFunctionLength(F, len)を実行
  19. Fを返す

9.2.4 AddRestrictedFunctionProperties ( F, realm )

抽象操作AddRestrictedFunctionPropertiesは、関数オブジェクトFレルムレコードrealmを引数として呼び出されます。 次の手順を実行します。

  1. Assert: realm.[[Intrinsics]].[[%ThrowTypeError%]] は存在し、初期化されている
  2. realm.[[Intrinsics]].[[%ThrowTypeError%]] を thrower とする
  3. ! DefinePropertyOrThrow(F, "caller", プロパティ記述子{ [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true })を実行
  4. ! DefinePropertyOrThrow(F, "arguments", プロパティ記述子{ [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true })を返す

9.2.4.1 %ThrowTypeError% ( )

%ThrowTypeError%組み込み関数は、レルムごとに1回定義される匿名の組み込み関数オブジェクトです。 %ThrowTypeError%が呼び出されると、次の手順を実行します。

  1. TypeError例外をスローする

%ThrowTypeError%関数の[[Extensible]]内部スロットの値はfalseです。

%ThrowTypeError%関数の"length"プロパティには、属性{[[Writable]]:false,[[Enumerable]]:false,[[Configurable]]:false}があります。

9.2.5 MakeConstructor ( F [ , writablePrototype [ , prototype ] ] )

抽象操作MakeConstructorには、関数の引数Fと、オプションでブール値writablePrototypeとオブジェクトprototypeが必要です。 prototypeが指定されている場合、値がFである"constructor"プロパティがすでに含まれていることが想定されます。この操作では、次の手順を実行してFをコンストラクターに変換します。

  1. Assert: F は ECMAScript関数オブジェクト
  2. Assert: IsConstructor(F) は false
  3. Assert: F は "prototype" 独自プロパティ を持っていない、かつ、拡張可能なオブジェクト
  4. 9.2.2 で定義しているコードを F.[[Construct]] にセットする
  5. baseF.[[ConstructorKind]] にセットする
  6. writablePrototype が存在しないなら、 truewritablePrototype にセットする
  7. prototype が存在しないなら、
    1. OrdinaryObjectCreate(%Object.prototype%) を prototype にセットする
    2. ! DefinePropertyOrThrow(prototype, "constructor", プロパティ記述子{ [[Value]]: F, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: true })を実行
  8. ! DefinePropertyOrThrow(F, "prototype", プロパティ記述子{ [[Value]]: prototype, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: false })を実行
  9. NormalCompletion(undefined)を返す

9.2.6 MakeClassConstructor ( F )

引数Fを持つ抽象操作MakeClassConstructorは、次の手順を実行します。

  1. Assert: F は ECMAScript関数オブジェクト
  2. Assert: F.[[IsClassConstructor]] は false
  3. trueF.[[IsClassConstructor]] にセットする
  4. NormalCompletion(undefined)を返す

9.2.7 MakeMethod ( F, homeObject )

引数FhomeObjectを持つ抽象操作MakeMethodは、次の手順を実行してFをメソッドとして構成します。

  1. Assert: F は ECMAScript関数オブジェクト
  2. Assert: Type(homeObject) は Object型
  3. homeObjectF.[[HomeObject]] にセットする
  4. NormalCompletion(undefined)を返す

9.2.8 SetFunctionName ( F, name [ , prefix ] )

抽象操作SetFunctionNameには、関数F、文字列またはシンボルname、およびオプションで文字列span class="t">prefixが必要です。 この操作では、次の手順を実行して、"name"プロパティをFに追加します。

  1. Assert: F"name" 独自プロパティを持っていない、かつ拡張可能なオブジェクト
  2. Assert: Type(name) は Symbol型 か String型
  3. Assert: prefix が存在するなら、 Type(prefix) は String型
  4. Type(name) が Symbol型なら、
    1. name の [[Description]]値 を description とする
    2. descriptionundefined なら、 空文字 を name にセットする
    3. b.でないなら、 "["、description、 "]" を順番につなげたものを name にセットする
  5. prefix が存在するなら、
    1. prefix、コードユニット0x0020(SPACE)、nameの順番につなげた文字列 を name にセットする
  6. ! DefinePropertyOrThrow(F, "name", プロパティ記述子 { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true })を返す

9.2.9 SetFunctionLength ( F, length )

抽象演算SetFunctionLengthには、関数Fと数値lengthが必要です。この操作では、次の手順を実行して、F"length"プロパティを追加します。

  1. Assert: F "length" 独自プロパティを持っていない、かつ拡張可能なオブジェクト
  2. Assert: Type(length) は Number型
  3. Assert: ! IsNonNegativeInteger(length) が true
  4. ! DefinePropertyOrThrow(F, "length", プロパティ記述子 { [[Value]]: length, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true })を返す

9.2.10 FunctionDeclarationInstantiation ( func, argumentsList )

ECMAScript関数を評価するための実行コンテキストが確立されると、新しい関数環境レコードが作成され、各仮パラメーターのバインディングがその環境レコードでインスタンス化されます。 関数本体の各宣言もインスタンス化されます。 関数の仮パラメーターにデフォルト初期化子が含まれていない場合、本体宣言はパラメーターと同じ環境レコードでインスタンス化されます。 デフォルトパラメータ初期化子が存在する場合、ボディ宣言用に2番目の環境レコードが作成されます。 仮パラメーターと関数は、FunctionDeclarationInstantiationの一部として初期化されます。 他のすべてのバインディングは、関数本体の評価中に初期化されます。

FunctionDeclarationInstantiationは、引数funcargumentsListを使用して次のように実行されます。 funcは、実行コンテキストが確立されている関数オブジェクトです。

  1. 実行中の実行コンテキストcalleeContext とする
  2. func.[[ECMAScriptCode]] を code とする
  3. func.[[Strict]] を strict とする
  4. func.[[FormalParameters]] を formals とする
  5. formals の BoundNames を parameterNames とする
  6. parameterNames に重複要素があるならtrue、そうでないなら falsehasDuplicates とする
  7. formals の IsSimpleParameterList を simpleParameterList とする
  8. formals の ContainsExpression を hasParameterExpressions とする
  9. code の VarDeclaredNames を varNames とする
  10. code の VarScopedDeclarations を varDeclarations とする
  11. code の LexicallyDeclaredNames を lexicalNames とする
  12. 空の新規ListfunctionNames とする
  13. 空の新規ListfunctionsToInitialize とする
  14. varDeclarationsの各dに対して、リストの逆順で、次を実行
    1. d が VariableDeclaration、ForBinding、BindingIdentifier 以外なら、
      1. Assert: dは、FunctionDeclaration、GeneratorDeclaration、AsyncFunctionDeclaration、AsyncGeneratorDeclarationのどれか
      2. d のBoundNamesの唯一の要素を fn とする
      3. fn が functionNames の要素でないなら、
        1. functionNames の先頭に fn を挿入する
        2. NOTE: 同名の関数宣言が複数ある場合は、最後の宣言が使用される
        3. functionsToInitialize の先頭に d を挿入する
  15. trueargumentsObjectNeeded とする
  16. func.[[ThisMode]] が lexical なら、
    1. NOTE: アロー関数は引数オブジェクトを持たない
    2. falseargumentsObjectNeeded にセットする
  17. 16.でなく "arguments"が parameterNames の要素なら、
    1. falseargumentsObjectNeeded にセットする
  18. 16. 17. でなく hasParameterExpressionsfalse なら、
    1. "arguments" が functionNames または、lexicalNames の要素なら、
      1. falseargumentsObjectNeeded にセットする
  19. stricttrue または hasParameterExpressionsfalse なら、
    1. NOTE: パラメータとトップレベルの変数に必要なレキシカル環境は1つだけです。
    2. calleeContextLexicalEnvironment を env とする
    3. envEnvironmentRecordenvRec とする
  20. 19. でないなら
    1. NOTE: 仮パラメーターリスト内のダイレクトeval呼び出しによって作成されたバインディングを、パラメーターが宣言されている環境の外部に確実にセットするには、別個の環境レコードが必要。
    2. calleeContextLexicalEnvironmentcalleeEnv とする
    3. NewDeclarativeEnvironment(calleeEnv) を env とする
    4. env の EnvironmentRecordenvRec とする
    5. Assert: calleeContext の VariableEnvironment は calleeEnv
    6. envcalleeContext の LexicalEnvironment にセットする
  21. parameterNames の各文字列paramNameに対して、
    1. envRec.HasBinding(paramName) を alreadyDeclared とする
    2. NOTE: 初期のエラーにより、パラメーター名の重複は、パラメーターのデフォルト値または残りのパラメーターを持たない非strict関数でのみ発生することが保証される
    3. alreadyDeclared が false なら、
      1. ! envRecCreateMutableBinding(paramName, false)を実行
      2. hasDuplicatestrue なら、
        1. ! envRec.InitializeBinding(paramName, undefined)を実行
  22. argumentsObjectNeededtrue なら、
    1. stricttrue または simpleParameterListfalse なら、
      1. CreateUnmappedArgumentsObject(argumentsList) を ao とする
    2. a.でないなら
      1. NOTE: マップされた引数オブジェクトは、restパラメーター、パラメーターのデフォルト値の初期化子、または非構造化パラメーターを持たない非strict関数に対してのみ提供される。
      2. CreateMappedArgumentsObject(func, formals, argumentsList, envRec) を ao とする
    3. stricttrue なら、
      1. ! envRec.CreateImmutableBinding("arguments", false)を実行
    4. c. でないなら
      1. ! envRec.CreateMutableBinding("arguments", false)を実行
    5. envRec.InitializeBinding("arguments", ao)を呼び出す
    6. "arguments" が追加された新しいparameterNamesのリストを parameterBindings とする
  23. 22. でないなら、
    1. parameterNamesparameterBindings とする
  24. CreateListIteratorRecord(argumentsList) を iteratorRecord とする
  25. hasDuplicatestrue なら、
    1. iteratorRecordundefined を引数としてformalsに対して? IteratorBindingInitializationを実行。
  26. Else,
    1. iteratorRecordenv を引数としてformalsに対して? IteratorBindingInitializationを実行。
  27. hasParameterExpressionsfalse なら、
    1. NOTE: パラメータとトップレベルの変数に必要なレキシカル環境は1つだけです。
    2. parameterBindingsのコピー を instantiatedVarNames とする
    3. varNamesの各nに対して、
      1. ninstantiatedVarNames の要素でないなら、
        1. instantiatedVarNames に n を追加
        2. ! envRec.CreateMutableBinding(n, false)を実行
        3. envRec.InitializeBinding(n, undefined)を呼び出す
    4. envvarEnv とする
    5. envRecvarEnvRec とする
  28. Else,
    1. NOTE: 仮パラメーターリスト内の式によって作成されたクロージャーが関数本体の宣言の可視性を持たないようにするには、別の環境レコードが必要です。
    2. NewDeclarativeEnvironment(env) を varEnv とする
    3. varEnv の EnvironmentRecordvarEnvRec とする
    4. varEnvcalleeContext の VariableEnvironment にセットする
    5. 空の新規ListinstantiatedVarNames とする
    6. varNames の各nに対して、
      1. ninstantiatedVarNamesの要素でないなら、
        1. instantiatedVarNames に n を追加
        2. ! varEnvRec.CreateMutableBinding(n, false)を実行
        3. n が parameterBindings の要素でない、または functionNames の要素なら、 undefinedinitialValue とする
        4. 3. でないなら
          1. ! envRec.GetBindingValue(n, false) を initialValue とする
        5. varEnvRec.InitializeBinding(n, initialValue)を呼び出す
        6. NOTE: 仮パラメーターと同名の変数は、最初は対応する初期化パラメーターと同じ値を持っています。
  29. NOTE: B.3.3.1では、この時点で追加の手順が提示されています。
  30. strictfalse なら、
    1. NewDeclarativeEnvironment(varEnv) を lexEnv とする
    2. NOTE: 非strict関数は、トップレベルのレキシカル宣言に個別のレキシカル環境レコードを使用します。そのため、ダイレクトevalは、evalコードによって導入されたvarスコープ宣言が既存のトップレベルのレキシカルスコープ宣言と競合するかどうかを判断できます。 strictなダイレクトevalはすべての宣言を新しい環境レコードに設定するため、strict関数にはこの処理は必要ありません。
  31. 31.でないなら varEnvlexEnv とする
  32. lexEnvEnvironmentRecordlexEnvRec とする
  33. lexEnvcalleeContext の LexicalEnvironment にセットする
  34. code の LexicallyScopedDeclarations を lexDeclarations とする
  35. lexDeclarations の各要素を d として、d に対して、
    1. NOTE: レキシカル的に宣言された名前は、関数/ジェネレーター宣言、仮パラメーター、またはvar名と同じにすることはできません。 レキシカル的に宣言された名前は、ここでのみインスタンス化され、初期化されません。
    2. d の BoundNames の各要素を dn として、dn に対して、
      1. d の IsConstantDeclaration が true なら、
        1. ! lexEnvRec.CreateImmutableBinding(dn, true)を実行
      2. Else,
        1. ! lexEnvRec.CreateMutableBinding(dn, false)を実行
  36. functionsToInitializeの各パースノードをfとし、fに対して、
    1. f の BoundNames の唯一の要素 を fn とする
    2. 引数lexEnvを指定したf の InstantiateFunctionObject を fo とする
    3. ! varEnvRec.SetMutableBinding(fn, fo, false)を実行
  37. NormalCompletion(empty)を返す
B.3.3は、ECMAScript 2015より前のWebブラウザー実装との下位互換性のために必要なアルゴリズムの拡張機能です。
パラメータ初期化子には、ダイレクトeval式が含まれる場合があります。 このようなevalのトップレベルの宣言は、evalコード(10.2)からのみ参照できます。 このような宣言のための環境の作成については、14.1.22で説明しています。

9.3 組み込み関数オブジェクト(Built-in Function Objects)

この仕様で定義している組み込み関数オブジェクトは、ECMAScriptコードで動作するECMAScript関数オブジェクト(9.2)として、または他の方法で提供される関数エキゾチックなオブジェクトとして実装できます。 どちらの場合も、関数を呼び出した結果は、それらの仕様に準拠している必要があります。 実装では、この仕様で定義していない追加の組み込み関数オブジェクトを提供する場合もあります。

組み込み関数オブジェクトがエキゾチックなオブジェクトとして実装されている場合、9.1で指定されている通常のオブジェクト動作が必要です。 そのようなすべての関数エキゾチックなオブジェクトには、[[Prototype]]、[[Extensible]]、[[Realm]]、および[[ScriptOrModule]]内部スロットもあります。

特に指定がない限り、すべての組み込み関数オブジェクトには、[[Prototype]]内部スロットの初期値として%Function.prototype%オブジェクトがあります。

アルゴリズムのステップまたは他の方法で指定された各組み込み関数の動作は、関数の[[Call]]と[[Construct]]呼び出しでの動作仕様です。ただし一部の関数は、[[Construct]]の呼び出しをサポートしていません。組み込み関数を[[Call]]で呼び出すと、thisArgumentthis値が、argumentsListは名前付きパラメーターが、NewTarget値はundefinedがセットされます。[[Construct]]で呼び出すと、this値は初期化されず、argumentsListは名前付きパラメーターを、newTargetはNewTarget値がセットされます。組み込み関数がECMAScript関数オブジェクトとして実装されている場合、指定された動作は、関数の本体であるECMAScriptコードによって実装される必要があります。ECMAScript関数オブジェクトである組み込み関数は、strict関数でなければなりません。組み込みコンストラクターTypeError例外をスローする以外の[[Call]]動作がある場合、実装は、関数の[[IsClassConstructor]]内部スロットの値がtrueにならないようにする必要があります。

コンストラクターとして識別されない組み込み関数オブジェクトは、特に指定されていない限り、[[Construct]]内部メソッドを実装しません。 組み込みコンストラクターがnew式の一部として呼び出されると、呼び出された[[Construct]]内部メソッドのargumentsListパラメーターは、組み込みコンストラクターの名前付きパラメーターの値を提供します。

コンストラクターではない組み込み関数には、特定の関数の説明で特に指定されていない限り、"prototype"プロパティーはありません。

組み込み関数オブジェクトがECMAScript関数として実装されていない場合、次の定義に準拠する[[Call]]および[[Construct]]内部メソッドを提供する必要があります。

9.3.1 [[Call]] ( thisArgument, argumentsList )

組み込み関数オブジェクトFの[[Call]]内部メソッドは、パラメーターthisArgumentおよびargumentsListで呼び出されます。 次の手順を実行します。

  1. 実行中の実行コンテキストcallerContext とする
  2. callerContext が中断さていないなら、callerContextを中断する
  3. 新規 実行コンテキストcalleeContext とする
  4. FcalleeContext関数コンポーネント にセットする
  5. F.[[Realm]] を calleeRealm とする
  6. calleeRealmcalleeContextレルムコンポーネントにセットする
  7. F.[[ScriptOrModule]] を calleeContextScriptOrModuleコンポーネントにセットする
  8. calleeContextの必要な実装定義の初期化をおこなう
  9. calleeContext実行コンテキストスタックにプッシュする。calleeContext実行中の実行コンテキストになる
  10. F を実行した結果の完了レコードを result とする。 thisArgumentthis値、argumentsListは名前付きパラメーター、 NewTargetundefined
  11. 実行コンテキストスタック から calleeContext を削除し、callerContext実行中の実行コンテキスト として復元する
  12. resultを返す
後で再開できるようにアクセス可能なジェネレーターオブジェクトによって中断および保持されている場合、calleeContextが実行コンテキストスタックから削除されても、破棄しないでください。

9.3.2 [[Construct]] ( argumentsList, newTarget )

組み込み関数オブジェクトFの[[Construct]]内部メソッドは、argumentsListおよびnewTargetパラメータを使用して呼び出されます。 実行されるステップは、[[Call]](9.3.1を参照)と同じですが、ステップ10が次のように置き換えられます。

  1. F を実行した結果の完了レコードを result とする。 this値 はundefinedargumentsListは名前付きパラメーター、 NewTargetは NewTarget値

9.3.3 CreateBuiltinFunction ( steps, internalSlotsList [ , realm [ , prototype ] ] )

抽象オペレーションCreateBuiltinFunctionは、stepsinternalSlotsListrealm、およびprototypeを取ります。 引数internalSlotsListは、オブジェクトの一部として定義する必要がある追加内部スロット名リストです。 CreateBuiltinFunctionは、次の手順で組み込み関数オブジェクト作成し、返します。

  1. Assert: steps は一連のアルゴリズムステップか、この仕様で提供される他の関数の動作定義です。
  2. realm が存在しないなら, 現在のレルムレコードrealm にセットする
  3. Assert: realmレルムレコード
  4. prototype が存在しないなら、 realm.[[Intrinsics]].[[%Function.prototype%]] を prototype にセットする
  5. 呼び出されるとstepsに記述されている動作を実行する新しい組み込み関数オブジェクトを func とする。新しい関数オブジェクトには、internalSlotsListの要素と同じ名前の内部スロットがある。
  6. realmfunc.[[Realm]] にセットする
  7. prototypefunc.[[Prototype]] にセットする
  8. truefunc.[[Extensible]] にセットする
  9. nullfunc.[[ScriptOrModule]] にセットする
  10. funcを返す

この仕様で定義されている各組み込み関数は、NewDeclarativeEnvironment抽象オペレーションを呼び出すことによって作成されます。

9.4 組み込みのエキゾチックオブジェクトの内部メソッドとスロット(Built-in Exotic Object Internal Methods and Slots)

この仕様は、いくつかの組み込みエキゾチックオブジェクトを定義しています。 これらのオブジェクトは、特定の状況を除いて、通常のオブジェクトと同様に動作します。 以下のエキゾチックなオブジェクトは、以下で明示的に指定されている場合を除き、通常のオブジェクト内部メソッドを使用します。

9.4.1 バインドされた関数エキゾチックオブジェクト(Bound Function Exotic Objects)

バウンド関数エキゾチックオブジェクト

バインドされた関数エキゾチックオブジェクトは、関数オブジェクトをラップするエキゾチックなオブジェクトです。 バインドされた関数エキゾチックオブジェクトは呼び出し可能です([[Call]]内部メソッドがあり、[[Construct]]内部メソッドがある場合があります)。 バインドされた関数のエキゾチックなオブジェクトを呼び出すと、通常、ラップされた関数が呼び出されます。

[[Call]]および、該当する場合、[[Construct]]内部メソッドが次の実装を使用し、その他の重要な内部メソッドが9.1にある定義を使用する場合、オブジェクトはバインドされた関数エキゾチックオブジェクトです。 これらのメソッドはBoundFunctionCreateでインストールされます。

バインドされた関数エキゾチックオブジェクトには、表27にリストされているECMAScript関数オブジェクトの内部スロットがありません。代わりに、[[Prototype]]と[[Extensible]]に加えて、表28にリストされている内部スロットがあります。

表28: バインドされた関数エキゾチックオブジェクトの内部スロット
内部スロット 内容
[[BoundTargetFunction]] 呼び出し可能なオブジェクト ラップされた関数オブジェクト。
[[BoundThis]] Any ラップされた関数呼び出し時、this値として渡される値。
[[BoundArguments]] List of Any ラップされた関数呼び出し時、最初の引数として使用される値のリスト。

9.4.1.1 [[Call]] ( thisArgument, argumentsList )

バインドされた関数のエキゾチックオブジェクトの[[Call]]内部メソッドFは、bind関数を使用して作成されます。[[Call]]がパラメーターthisArgumentおよびargumentsListで呼び出されると、次の手順が実行されます。

  1. F.[[BoundTargetFunction]] を target とする
  2. F.[[BoundThis]] を boundThis とする
  3. F.[[BoundArguments]] を boundArgs とする
  4. boundArgsの値を順番にargsにセットし、その後にargumentsListの値を順番にargsにセットする
  5. ? Call(target, boundThis, args)を返す

9.4.1.2 [[Construct]] ( argumentsList, newTarget )

bind関数を使用して作成されたバインドされた関数のエキゾチックなオブジェクトFの[[Construct]]内部メソッドが、argumentsListおよびnewTargetで呼び出されると、次の手順が実行されます。

  1. F.[[BoundTargetFunction]] を target とする
  2. Assert: IsConstructor(target) は true
  3. F.[[BoundArguments]] を boundArgs とする
  4. boundArgsの値を順番にargsにセットし、その後にargumentsListの値を順番にargsにセットする
  5. SameValue(F, newTarget) が true なら、 targetnewTarget にセットする
  6. ? Construct(target, args, newTarget)を返す

9.4.1.3 BoundFunctionCreate ( targetFunction, boundThis, boundArgs )

引数targetFunctionboundThis、およびboundArgsを持つ抽象オペレーションBoundFunctionCreateは、新しいバインドされた関数のエキゾチックオブジェクトの作成します。 次の手順を実行します。

  1. Assert: Type(targetFunction) は Object型
  2. ? targetFunction.[[GetPrototypeOf]]() を proto とする
  3. 表28の内部スロットと [[Prototype]]、[[Extensible]] を internalSlotsList とする
  4. ! MakeBasicObject(internalSlotsList) を obj とする
  5. protoobj.[[Prototype]] にセットする
  6. 9.4.1.1の処理をobj.[[Call]]にセット
  7. IsConstructor(targetFunction) が true なら、
    1. 9.4.1.2 の処理を obj.[[Construct]]にセット
  8. targetFunctionobj.[[BoundTargetFunction]] にセットする
  9. boundThisobj.[[BoundThis]] にセットする
  10. boundArgsobj.[[BoundArguments]] にセットする
  11. objを返す

9.4.2 Arrayエキゾチックオブジェクト(Array Exotic Objects)

Arrayエキゾチックオブジェクト

Arrayオブジェクトは、配列インデックスプロパティキーに特別な扱いをさせるエキゾチックなオブジェクトです(6.1.7を参照)。プロパティ名が配列インデックスであるプロパティは、要素とも呼ばれます。すべてのArrayオブジェクトには、設定不可能な"length"プロパティがあり、その値は232未満の負でない整数です。"length"プロパティの値は、配列インデックスとして評価できる独自プロパティ名よりも数値的に大きくなります。Arrayオブジェクトの独自のプロパティが作成または変更されると、この条件を維持するために他のプロパティが必要に応じて調整されます。特に、配列インデックスである独自のプロパティが追加されると、"length"プロパティの値は、必要に応じて、その配列インデックスの数値よりも1だけ大きくなるように変更されます。また、"length"プロパティの値が変更されると、"length"以上のすべての独自プロパティが削除されます。この制約は、Arrayオブジェクトの独自のプロパティにのみ適用され、プロトタイプから継承されている"length"または配列のインデックスプロパティの影響を受けません。

文字列プロパティ名Pは、ToStringToUint32P))がPに等しく、ToUint32P)が232-1に等しくない場合に限り、配列インデックスです。

[[DefineOwnProperty]]内部メソッドが次の実装を使用し、その他の重要な内部メソッドが9.1にある定義を使用する場合、オブジェクトはArrayエキゾチックオブジェクト(または単にArrayオブジェクト)です。 これらのメソッドはArrayCreateでインストールされます。

9.4.2.1 [[DefineOwnProperty]] ( P, Desc )

ArrayエキゾチックオブジェクトAの[[DefineOwnProperty]]内部メソッドがプロパティキーPとプロパティ記述子Descで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. P"length"なら、
    1. ? ArraySetLength(A, Desc)を返す
  3. 2.でなく P が 配列インデックスなら、
    1. OrdinaryGetOwnProperty(A, "length") を oldLenDesc とする
    2. Assert: 削除または再構成できない"length"データプロパティでArrayオブジェクトが作成されるため、oldLenDescが未定義またはアクセサ記述子になることはない
    3. oldLenDesc.[[Value]] を oldLen とする
    4. Assert: IsNonNegativeInteger(oldLen) は true
    5. ! ToUint32(P) を index とする
    6. indexoldLenoldLenDesc.[[Writable]] が false なら、 false を返す
    7. ! OrdinaryDefineOwnProperty(A, P, Desc) を succeeded とする
    8. succeededfalse なら、 false を返す
    9. indexoldLenなら、
      1. index + 1oldLenDesc.[[Value]] にセットする
      2. OrdinaryDefineOwnProperty(A, "length", oldLenDesc) を succeeded とする
      3. Assert: succeededtrue
    10. true を返す
  4. OrdinaryDefineOwnProperty(A, P, Desc)を返す

9.4.2.2 ArrayCreate ( length [ , proto ] )

length(0または正の整数)とオプションprotoを持つ抽象操作ArrayCreateは、新しい配列のエキゾチックオブジェクトを作成します。 次の手順を実行します。

  1. Assert: ! IsNonNegativeInteger(length) は true
  2. length-0 なら、 +0length にセットする
  3. If length > 232 - 1 なら RangeError例外をスローする
  4. proto が存在しないなら、 %Array.prototype%proto にセットする
  5. ! MakeBasicObject(« [[Prototype]], [[Extensible]] ») を A とする
  6. protoA.[[Prototype]] にセットする
  7. 9.4.2.1 の処理を A.[[DefineOwnProperty]] にセット
  8. ! OrdinaryDefineOwnProperty(A, "length", プロパティ記述子 { [[Value]]: length, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })を実行
  9. Aを返す

9.4.2.3 ArraySpeciesCreate ( originalArray, length )

引数originalArraylengthを持つ抽象操作ArraySpeciesCreateは、originalArrayから派生したコンストラクター関数を使用して、新しいArrayオブジェクトを作成します。 次の手順を実行します。

  1. Assert: ! IsNonNegativeInteger(length) は true
  2. length-0 なら、 +0length にセットする
  3. ? IsArray(originalArray) を isArray とする
  4. isArrayfalse なら、 ? ArrayCreate(length)を返す
  5. ? Get(originalArray, "constructor") を C とする
  6. IsConstructor(C) が true なら、
    1. 現在のレルムレコードthisRealm とする
    2. ? GetFunctionRealm(C) を realmC とする
    3. thisRealmrealmC が同じレルムレコードではないなら、
      1. SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) が true なら、undefinedC にセットする
  7. Type(C) が Object型なら、
    1. ? Get(C, @@species) を C にセットする
    2. Cnull なら、 undefinedC にセットする
  8. Cundefined なら、? ArrayCreate(length)を返す
  9. IsConstructor(C) が false なら、 TypeError例外をスローする
  10. ? Construct(C, « length »)を返す
実行中の実行コンテキストのレルムではないレルムの標準組み込み配列コンストラクターを使用してoriginalArrayが作成された場合、実行中の実行コンテキストのレルムを使用して新しい配列が作成されます。 これにより、これまでArraySpeciesCreateを使用して定義されたArray.prototypeメソッドに対してその動作を行っていたWebブラウザーとの互換性が維持されます。

9.4.2.4 ArraySetLength ( A, Desc )

抽象演算ArraySetLengthが配列エキゾチックオブジェクトAとプロパティ記述子Descを使用して呼び出されると、次の手順が実行されます。

  1. Desc.[[Value]] が 存在しないなら、
    1. OrdinaryDefineOwnProperty(A, "length", Desc)を返す
  2. Desc のコピーを newLenDesc とする
  3. ? ToUint32(Desc.[[Value]]) を newLen とする
  4. ? ToNumber(Desc.[[Value]]) を numberLen とする
  5. newLennumberLen なら RangeError例外をスローする
  6. newLennewLenDesc.[[Value]] にセットする
  7. OrdinaryGetOwnProperty(A, "length") を oldLenDesc とする
  8. Assert: 削除または再構成できないlengthデータプロパティでArrayオブジェクトが作成されるため、oldLenDescundefinedまたはアクセサ記述子になることはありません。
  9. oldLenDesc.[[Value]] を oldLen とする
  10. newLenoldLen なら、
    1. OrdinaryDefineOwnProperty(A, "length", newLenDesc)を返す
  11. oldLenDesc.[[Writable]] が false なら、 false を返す
  12. newLenDesc.[[Writable]] が存在しない、または値がtrueなら、truenewWritable とする
  13. 12.でないなら、
    1. 要素を削除できない場合に備えて、[[Writable]]属性をfalseへ設定するのを延期する必要がある
    2. falsenewWritable とする
    3. truenewLenDesc.[[Writable]] にセットする
  14. ! OrdinaryDefineOwnProperty(A, "length", newLenDesc) を succeeded とする
  15. succeededfalse なら、 false を返す
  16. Aの配列インデックスキーをPとし、各Pに対して数値がnewLen以上の数値インデックスの降順で、次をおこなう。
    1. ! A.[[Delete]](P) を deleteSucceeded とする
    2. deleteSucceededfalse なら、
      1. ! ToUint32(P) + 1newLenDesc.[[Value]] にセットする
      2. newWritablefalse なら、falsenewLenDesc.[[Writable]] にセットする
      3. ! OrdinaryDefineOwnProperty(A, "length", newLenDesc)を実行
      4. false を返す
  17. newWritablefalse なら、
    1. OrdinaryDefineOwnProperty(A, "length", プロパティ記述子 { [[Writable]]: false })を返す。 (この呼び出しは常にtrueを返す)
  18. true を返す
手順3と4で、Desc.[[Value]]がオブジェクトの場合、そのvalueOfメソッドが2回呼び出されます。 これは、この仕様の第2版以降、この効果で指定された従来の動作です。

9.4.3 Stringエキゾチックオブジェクト(String Exotic Objects)

Stringオブジェクトは、String値をカプセル化し、String値の個々のコードユニット要素に対応する仮想整数インデックスデータプロパティを公開するエキゾチックなオブジェクトです。 Stringエキゾチックオブジェクトには、常に"length" という名前のデータプロパティがあり、その値はカプセル化された文字列値のコードユニット要素の数です。 コード単位のデータプロパティと"length" プロパティの両方は、書き込みや構成ができません。

[[GetOwnProperty]]、[[DefineOwnProperty]]、および[[OwnPropertyKeys]]内部メソッドが以降の実装を使用し、その他の重要な内部メソッドが9.1にある定義を使用する場合、オブジェクトはStringエキゾチックオブジェクト(または単にStringオブジェクト)です。 これらのメソッドはStringCreateでインストールされます。

Stringエキゾチックなオブジェクトには、通常のオブジェクトと同じ内部スロットがあります。 また、[[StringData]]内部スロットもあります。

9.4.3.1 [[GetOwnProperty]] ( P )

StringエキゾチックオブジェクトSの[[GetOwnProperty]]内部メソッドがプロパティキーPで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. OrdinaryGetOwnProperty(S, P) を desc とする
  3. descundefined でないなら、 desc を返す
  4. ! StringGetOwnProperty(S, P)を返す

9.4.3.2 [[DefineOwnProperty]] ( P, Desc )

StringエキゾチックオブジェクトSの[[DefineOwnProperty]]内部メソッドがプロパティキーPとプロパティ記述子Descで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. ! StringGetOwnProperty(S, P) を stringDesc とする
  3. stringDescundefined でないなら、
    1. S.[[Extensible]] を extensible とする
    2. ! IsCompatiblePropertyDescriptor(extensible, Desc, stringDesc)を返す
  4. ! OrdinaryDefineOwnProperty(S, P, Desc)を返す

9.4.3.3 [[OwnPropertyKeys]] ( )

StringエキゾチックオブジェクトOの[[OwnPropertyKeys]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. 空の新規Listkeys とする
  2. O.[[StringData]] を str とする
  3. Assert: Type(str) は String型
  4. strの長さを len とする
  5. 0から始まり、ilen となる各整数iについて、昇順で、
    1. keysの最後に! ToString(i)の結果を追加
  6. 配列インデックスでToInteger(P) ≧ lenとなるOの各プロパティキーPに対して、数値インデックスの昇順で、
    1. keysの最後にPを追加
  7. Type(P)がString型で、配列インデックスではないOの独自のプロパティキーPごとに、プロパティ作成時系列の昇順で、
    1. keysの最後にPを追加
  8. Type(P)がSymbol型であるOの独自のプロパティキーPごとに、プロパティ作成時系列の昇順で、
    1. keysの最後にPを追加
  9. keysを返す

9.4.3.4 StringCreate ( value, prototype )

引数valueprototypeを持つ抽象操作StringCreateは、新しいStringエキゾチックオブジェクトを作成します。 次の手順を実行します。

  1. Assert: Type(value) は String型
  2. ! MakeBasicObject(« [[Prototype]], [[Extensible]], [[StringData]] ») を S とする
  3. prototypeS.[[Prototype]] にセットする
  4. valueS.[[StringData]] にセットする
  5. 9.4.3.1の処理を S.[[GetOwnProperty]] にセット
  6. 9.4.3.2の処理を S.[[DefineOwnProperty]] にセット
  7. 9.4.3.3の処理を S.[[OwnPropertyKeys]] にセット
  8. value のコード単位要素の数を length とする
  9. ! DefinePropertyOrThrow(S, "length",プロパティ記述子 { [[Value]]: length, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })を実行
  10. Sを返す

9.4.3.5 StringGetOwnProperty ( S, P )

引数SおよびPを指定して呼び出される抽象操作StringGetOwnPropertyは、次の手順を実行します。

  1. Assert: S は [[StringData]]内部スロットを持つオブジェクト
  2. Assert: IsPropertyKey(P) は true
  3. Type(P) がString型でないなら、 undefined を返す
  4. ! CanonicalNumericIndexString(P) を index とする
  5. indexundefined なら、 undefined を返す
  6. IsInteger(index) が false なら、 undefined を返す
  7. index = -0 なら undefined を返す
  8. S.[[StringData]] を str とする
  9. Assert: Type(str) は String型
  10. strの長さを len とする
  11. index0lenindexなら、 undefined を返す
  12. strのインデックスindexのコードユニットを含む長さ1の文字列値をresultStrとする
  13. PropertyDescriptor型 { [[Value]]: resultStr, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }を返す

9.4.4 Argumentsエキゾチックオブジェクト(Arguments Exotic Objects)

ほとんどのECMAScript関数は、引数オブジェクトをコードで使用できます。 その引数オブジェクトは通常のオブジェクトまたはArgumentsエキゾチックオブジェクトです。 Argumentsエキゾチックオブジェクトは、配列インデックスプロパティが、関連する関数呼び出しの仮パラメーターバインディングにマップされています。

内部メソッドに以降の実装を使用している場合、オブジェクトはArgumentsエキゾチックオブジェクトです。ここで指定されていないものは、9.1にある実装を使用します。 これらのメソッドはCreateMappedArgumentsObjectでインストールされます。

CreateUnmappedArgumentsObjectはこの項に記述されていますが、Argumentsエキゾチックオブジェクトではなく、通常のオブジェクトを作成します。

Argumentsエキゾチックオブジェクトには、通常のオブジェクトと同じ内部スロットがあります。 また、[[ParameterMap]]内部スロットがあります。 通常のArgumentsオブジェクトには、[[ParameterMap]]内部スロットもあり、その値は常に未定義です。 通常の引数オブジェクトの場合、[[ParameterMap]]内部スロットは、Object.prototype.toString19.1.3.6)によってそれらを識別するためにのみ使用されます。

関数オブジェクトの仮パラメーターよりも、Argumentsエキゾチックオブジェクト内の引数データが少ない場合、最初にArgumentsエキゾチックオブジェクトのデータプロパティの値を、関数の実行コンテキストの対応する引数バインディングと共有します。つまり、プロパティを変更すると、引数のバインドの対応する値が変更されます。その逆も同様です。プロパティが削除されてから再定義されたり、プロパティがアクセサプロパティに変更された場合は、この対応が失われます。引数オブジェクトが通常のオブジェクトである場合、そのプロパティの値は関数に渡された引数の単なるコピーであり、プロパティ値と仮パラメーター値の間に動的リンクはありません。
ParameterMapオブジェクトとそのプロパティ値は、引数バインディングと引数オブジェクトの対応を指定するためのデバイスとして使用されます。 ParameterMapオブジェクトとそのプロパティの値であるオブジェクトは、ECMAScriptコードから直接監視することはできません。 ECMAScript実装は、指定されたセマンティクスを実装するためにそのようなオブジェクトを実際に作成または使用する必要はありません。
通常の引数オブジェクトは、アクセス時にTypeError例外をスローする「callee」という名前の設定不可能なアクセサプロパティを定義します。 "callee"プロパティは、非strict関数の一部のクラスに対してのみ作成されるエキゾチックオブジェクトの引数に対してより具体的な意味を持っています。 通常のバリアントでのこのプロパティの定義は、ECMAScript実装に準拠することによって他の方法で定義されないようにするために存在します。
ArgumentsエキゾチックオブジェクトのECMAScript実装には、歴史的に「caller」という名前のアクセサプロパティが含まれていました。 ECMAScript 2017より前のバージョンでは、この仕様には通常の引数オブジェクトに対してスローする「呼び出し元」プロパティの定義が含まれていました。 実装にはこの拡張機能が含まれていないため、ECMAScript 2017はスローする「呼び出し元」アクセサーの要件を削除しました。

9.4.4.1 [[GetOwnProperty]] ( P )

プロパティキーPで呼び出されたときのArgumentsエキゾチックオブジェクトの[[GetOwnProperty]]内部メソッドは、次の手順を実行します。

  1. argumentsオブジェクト を args とする
  2. OrdinaryGetOwnProperty(args, P) を desc とする
  3. descundefined なら、descを返す
  4. args.[[ParameterMap]] を map とする
  5. ! HasOwnProperty(map, P) を isMapped とする
  6. isMappedtrue なら、
    1. Get(map, P) を desc.[[Value]] にセットする
  7. descを返す

9.4.4.2 [[DefineOwnProperty]] ( P, Desc )

プロパティキーPとプロパティ記述子Descを指定して呼び出されたときのArgumentsエキゾチックオブジェクトの[[DefineOwnProperty]]内部メソッドは、次の手順を実行します。

  1. argumentsオブジェクト を args とする
  2. args.[[ParameterMap]] を map とする
  3. HasOwnProperty(map, P) を isMapped とする
  4. DescnewArgDesc とする
  5. isMappedtrueIsDataDescriptor(Desc) が trueなら、
    1. Desc.[[Value]] が存在しない、かつ Desc.[[Writable]] が存在し値が false なら、
      1. Desc のコピーを newArgDesc にセットする
      2. Get(map, P) を newArgDesc.[[Value]] にセットする
  6. ? OrdinaryDefineOwnProperty(args, P, newArgDesc) を allowed とする
  7. allowedfalse なら、 false を返す
  8. isMappedtrue なら、
    1. IsAccessorDescriptor(Desc) が true なら、
      1. map.[[Delete]](P)を呼び出す
    2. a. でないなら、
      1. Desc.[[Value]] が存在するなら、
        1. Set(map, P, Desc.[[Value]], false) を setStatus とする
        2. Assert: setStatustrue(argumentオブジェクトによってマップされた仮パラメーターは常に書き込み可能であるため)
      2. Desc.[[Writable]] が存在し、値が false なら、
        1. map.[[Delete]](P)を呼び出す
  9. true を返す

9.4.4.3 [[Get]] ( P, Receiver )

プロパティキーPおよびECMAScript言語値Receiverで呼び出されたときのArgumentsエキゾチックオブジェクトの[[Get]]内部メソッドは、次の手順を実行します。

  1. argumentsオブジェクト を args とする
  2. args.[[ParameterMap]] を map とする
  3. ! HasOwnProperty(map, P) を isMapped とする
  4. isMappedfalse なら、
    1. ? OrdinaryGet(args, P, Receiver)を返す
  5. 4. でないなら
    1. Assert: mapは、Pの仮パラメータマッピングが含まれている
    2. Get(map, P)を返す

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

プロパティキーP、値V、およびECMAScript言語値Receiverで呼び出されたときのArgumentsエキゾチックオブジェクトの[[Set]]内部メソッドは、次の手順を実行します。

  1. argumentsオブジェクト を args とする
  2. SameValue(args, Receiver) が false なら、
    1. falseisMapped とする
  3. 2. でないなら、
    1. args.[[ParameterMap]] を map とする
    2. ! HasOwnProperty(map, P) を isMapped とする
  4. isMappedtrue なら、
    1. Set(map, P, V, false) を setStatus とする
    2. Assert: setStatustrue (argumentsオブジェクトによってマップされた仮パラメーターは常に書き込み可能であるため)
  5. ? OrdinarySet(args, P, V, Receiver)を返す

9.4.4.5 [[Delete]] ( P )

プロパティキーPで呼び出されたときの引数エキゾチックオブジェクトの[[Delete]]内部メソッドは、次の手順を実行します。

  1. argumentsオブジェクト を args とする
  2. args.[[ParameterMap]] を map とする
  3. ! HasOwnProperty(map, P) を isMapped とする
  4. ? OrdinaryDelete(args, P) を result とする
  5. resulttrueisMappedtrueなら、
    1. map.[[Delete]](P)を呼び出す
  6. resultを返す

9.4.4.6 CreateUnmappedArgumentsObject ( argumentsList )

引数argumentsListで呼び出される抽象操作CreateUnmappedArgumentsObjectは、次の手順を実行します。

  1. argumentsList の要素数を len とする
  2. OrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] ») を obj とする
  3. undefinedobj.[[ParameterMap]] にセットする
  4. DefinePropertyOrThrow(obj, "length",プロパティ記述子 { [[Value]]: len, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })を実行
  5. 0index とする
  6. indexlen の間繰り返し
    1. argumentsList[index] を val とする
    2. ! CreateDataPropertyOrThrow(obj, ! ToString(index), val)を実行
    3. index + 1index にセットする
  7. ! DefinePropertyOrThrow(obj, @@iterator,プロパティ記述子 { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })を実行
  8. ! DefinePropertyOrThrow(obj, "callee",プロパティ記述子 { [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false })を実行
  9. objを返す

9.4.4.7 CreateMappedArgumentsObject ( func, formals, argumentsList, env )

抽象操作CreateMappedArgumentsObjectは、オブジェクトfunc、パースノードformals、リストargumentsList、および環境レコードenvで呼び出されます。 次の手順が実行されます。

  1. Assert: formalsには、restパラメーター、バインディングパターン、初期化子は含まれていない。 識別子が重複している可能性がある。
  2. argumentsList の要素数を len とする
  3. ! MakeBasicObject(« [[Prototype]], [[Extensible]], [[ParameterMap]] ») を obj とする
  4. 9.4.4.1の処理を obj.[[GetOwnProperty]] にセット
  5. 9.4.4.2の処理を obj.[[DefineOwnProperty]] にセット
  6. 9.4.4.3の処理を obj.[[Get]] にセット
  7. 9.4.4.4の処理を obj.[[Set]] にセット
  8. 9.4.4.5の処理を obj.[[Delete]] にセット
  9. %Object.prototype%obj.[[Prototype]] にセットする
  10. OrdinaryObjectCreate(null) を map とする
  11. mapobj.[[ParameterMap]] にセットする
  12. formals のBoundNamesを parameterNames とする
  13. parameterNames の要素数を numberOfParameters とする
  14. 0index とする
  15. indexlen の間繰り返し
    1. argumentsList[index] を val とする
    2. ! CreateDataPropertyOrThrow(obj, ! ToString(index), val)を実行
    3. index + 1index にセットする
  16. ! DefinePropertyOrThrow(obj, "length",プロパティ記述子 { [[Value]]: len, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })を実行
  17. 空の新規ListmappedNames とする
  18. numberOfParameters - 1index とする
  19. index0 の間繰り返し
    1. parameterNames[index] を name とする
    2. namemappedNames の要素でないなら、
      1. mappedNames に name を追加
      2. indexlenなら
        1. MakeArgGetter(name, env) を g とする
        2. MakeArgSetter(name, env)) を p とする
        3. map.[[DefineOwnProperty]](! ToString(index),プロパティ記述子 { [[Set]]: p, [[Get]]: g, [[Enumerable]]: false, [[Configurable]]: true })を実行
    3. index - 1index にセットする
  20. ! DefinePropertyOrThrow(obj, @@iterator,プロパティ記述子 { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })を実行
  21. ! DefinePropertyOrThrow(obj, "callee",プロパティ記述子 { [[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })を実行
  22. objを返す
9.4.4.7.1 MakeArgGetter ( name, env )

文字列nameと環境レコード env で呼び出された抽象操作MakeArgGetterは、実行時にenv内のnameでバインドされた値を返す組み込み関数オブジェクトを作成します。 次の手順を実行します。

  1. 以下に指定されているArgGetter関数のステップ を steps とする
  2. ! CreateBuiltinFunction(steps, « [[Name]], [[Env]] ») を getter とする
  3. namegetter.[[Name]] にセットする
  4. envgetter.[[Env]] にセットする
  5. getterを返す

ArgGetter関数:

[[Name]]および[[Env]]内部スロットを持つ匿名の組み込み関数です。 引数を必要としないArgGetter関数が呼び出されると、次の手順が実行されます。

  1. アクティブ関数オブジェクトf とする
  2. f.[[Name]] を name とする
  3. f.[[Env]] を env とする
  4. env.GetBindingValue(name, false)を返す
ArgGetter関数はECMAScriptコードに直接アクセスできません。
9.4.4.7.2 MakeArgSetter ( name, env )

文字列nameと環境レコードenvで呼び出された抽象操作MakeArgSetterは、組み込み関数オブジェクトを作成します。この関数オブジェクトは、実行されると、env内のnameでバインドされた値を設定します。 次の手順を実行します。

  1. 以下に指定されているArgSetter関数のステップ を steps とする
  2. ! CreateBuiltinFunction(steps, « [[Name]], [[Env]] ») を setter とする
  3. namesetter.[[Name]] にセットする
  4. envsetter.[[Env]] にセットする
  5. setterを返す

ArgSetter関数:

[[Name]]および[[Env]]内部スロットを持つ匿名の組み込み関数です。 引数値を指定してArgSetter関数を呼び出すと、次の手順が実行されます。

  1. アクティブ関数オブジェクトf とする
  2. f.[[Name]] を name とする
  3. f.[[Env]] を env とする
  4. env.SetMutableBinding(name, value, false)を返す
ArgSetter関数はECMAScriptコードに直接アクセスできません。

9.4.5 Integer-Indexedエキゾチックオブジェクト(Integer-Indexed Exotic Objects)

Integer-Indexedエキゾチックオブジェクトは、整数インデックスプロパティキーの特別な処理を実行するエキゾチックなオブジェクトです。

Integer-Indexedエキゾチックオブジェクトには、通常のオブジェクトと同じ内部スロットがあり、さらに[[ViewedArrayBuffer]]、[[ArrayLength]]、[[ByteOffset]]、[[ContentType]]、および[[TypedArrayName]]内部スロットがあります。

この後に定義している[[GetOwnProperty]]、[[HasProperty]]、[[DefineOwnProperty]]、[[Get]]、[[Set]]、および[[OwnPropertyKeys]]内部メソッドと、9.1にあるその他の重要な内部メソッドを持つオブジェクトは、Integer-Indexedエキゾチックオブジェクトです。これらのメソッドは、IntegerIndexedObjectCreateによってインストールされます。

9.4.5.1 [[GetOwnProperty]] ( P )

Integer-IndexedエキゾチックオブジェクトOの[[GetOwnProperty]]内部メソッドがプロパティキーPで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. Assert: OInteger-Indexedエキゾチックオブジェクト
  3. Type(P) が String型なら、
    1. ! CanonicalNumericIndexString(P) を numericIndex とする
    2. numericIndexundefined でないなら、
      1. ? IntegerIndexedElementGet(O, numericIndex) を value とする
      2. valueundefined なら、 undefined を返す
      3. PropertyDescriptor型 { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }を返す
  4. OrdinaryGetOwnProperty(O, P)を返す

9.4.5.2 [[HasProperty]] ( P )

Integer-IndexedエキゾチックオブジェクトOの[[HasProperty]]内部メソッドがプロパティキーPで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. Assert: OInteger-Indexedエキゾチックオブジェクト
  3. Type(P) が String型なら、
    1. ! CanonicalNumericIndexString(P) を numericIndex とする
    2. numericIndexundefined でないなら、
      1. O.[[ViewedArrayBuffer]] を buffer とする
      2. IsDetachedBuffer(buffer) が true なら、 TypeError例外をスローする
      3. ! IsValidIntegerIndex(O, numericIndex) が false なら、 false を返す
      4. true を返す
  4. ? OrdinaryHasProperty(O, P)を返す

9.4.5.3 [[DefineOwnProperty]] ( P, Desc )

Integer-IndexedエキゾチックオブジェクトOの[[DefineOwnProperty]]内部メソッドがプロパティキーPとプロパティ記述子Descで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. Assert: OInteger-Indexedエキゾチックオブジェクト
  3. Type(P) が String型なら、
    1. ! CanonicalNumericIndexString(P) を numericIndex とする
    2. numericIndexundefined でないなら、
      1. ! IsValidIntegerIndex(O, numericIndex) が false なら、 false を返す
      2. IsAccessorDescriptor(Desc) が true なら、 false を返す
      3. Desc が [[Configurable]]フィールドを持っていて、Desc.[[Configurable]] が true なら、false を返す
      4. Desc が [[Enumerable]]フィールドを持っていて、 Desc.[[Enumerable]] が false なら、 false を返す
      5. Desc が [[Writable]]フィールドを持っていて、Desc.[[Writable]] が false なら、 false を返す
      6. Desc が [[Value]]フィールドを持っているなら、
        1. Desc.[[Value]] を value とする
        2. ? IntegerIndexedElementSet(O, numericIndex, value)を返す
      7. true を返す
  4. ! OrdinaryDefineOwnProperty(O, P, Desc)を返す

9.4.5.4 [[Get]] ( P, Receiver )

Integer-IndexedエキゾチックオブジェクトOの[[Get]]内部メソッドがプロパティキーPおよびECMAScript言語値Receiverで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. Type(P) が String型なら
    1. ! CanonicalNumericIndexString(P) を numericIndex とする
    2. numericIndexundefined でないなら、
      1. ? IntegerIndexedElementGet(O, numericIndex)を返す
  3. ? OrdinaryGet(O, P, Receiver)を返す

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

Integer-IndexedエキゾチックオブジェクトOの[[Set]]内部メソッドがプロパティキーP、値V、およびECMAScript言語値Receiverで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. If Type(P) が String型なら、
    1. ! CanonicalNumericIndexString(P) を numericIndex とする
    2. numericIndexundefined でないなら、
      1. ? IntegerIndexedElementSet(O, numericIndex, V)を返す
  3. ? OrdinarySet(O, P, V, Receiver)を返す

9.4.5.6 [[OwnPropertyKeys]] ( )

Integer-IndexedエキゾチックオブジェクトOの[[OwnPropertyKeys]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. 空の新規Listkeys とする
  2. Assert: OInteger-Indexedエキゾチックオブジェクト
  3. O.[[ArrayLength]] を len とする
  4. 0から始まり、ilen となる各整数iについて、昇順で、
    1. keysの最後に! ToString(i)の結果を追加
  5. Oの各独自プロパティPとし、Type(P)がString型、かつ、整数インデックスではないものについて、プロパティ作成時系列の昇順で、
    1. keysの最後にPを追加
  6. Oの各独自プロパティPとし、Type(P)がSymbol型のものについて、プロパティ作成時系列の昇順で、
    1. keysの最後にPを追加
  7. keysを返す

9.4.5.7 IntegerIndexedObjectCreate ( prototype )

抽象操作IntegerIndexedObjectCreateは、新しいInteger-Indexedエキゾチックオブジェクトを作成します。 IntegerIndexedObjectCreateは、次の手順を実行します。

  1. « [[Prototype]], [[Extensible]], [[ViewedArrayBuffer]], [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], [[ArrayLength]] »internalSlotsList とする
  2. ! MakeBasicObject(internalSlotsList) を A とする
  3. 9.4.5.1の処理を A.[[GetOwnProperty]] にセット
  4. 9.4.5.2の処理を A.[[HasProperty]] にセット
  5. 9.4.5.3の処理を A.[[DefineOwnProperty]] にセット
  6. 9.4.5.4の処理を A.[[Get]] にセット
  7. 9.4.5.5の処理を A.[[Set]] にセット
  8. 9.4.5.6の処理を A.[[OwnPropertyKeys]] as specified in
  9. prototypeA.[[Prototype]] にセットする
  10. Aを返す

9.4.5.8 IsValidIntegerIndex ( O, index )

引数Oindexを指定した抽象操作IsValidIntegerIndexは、次の手順を実行します。

  1. Assert: OInteger-Indexedエキゾチックオブジェクト
  2. Assert: Type(index) は Number型
  3. ! IsInteger(index) が false なら、false を返す
  4. index-0 なら、false を返す
  5. index0 または indexO.[[ArrayLength]] なら、 false を返す
  6. true を返す

9.4.5.9 IntegerIndexedElementGet ( O, index )

引数Oindexを指定した抽象操作IntegerIndexedElementGetは、次の手順を実行します。

  1. Assert: OInteger-Indexedエキゾチックオブジェクト
  2. Assert: Type(index) は Number型
  3. O.[[ViewedArrayBuffer]] を buffer とする
  4. IsDetachedBuffer(buffer) が true なら、TypeError例外をスローする
  5. ! IsValidIntegerIndex(O, index) が false なら、 undefined を返す
  6. O.[[ByteOffset]] を offset とする
  7. O.[[TypedArrayName]] の文字列値を arrayTypeName とする
  8. 表61arrayTypeName に対応する要素サイズを elementSize とする
  9. (index × elementSize) + offsetindexedPosition とする
  10. 表61arrayTypeName に対応する要素型 を elementType とする
  11. GetValueFromBuffer(buffer, indexedPosition, elementType, true, Unordered)を返す

9.4.5.10 IntegerIndexedElementSet ( O, index, value )

引数Oindex、およびvalueを持つ抽象操作IntegerIndexedElementSetは、次の手順を実行します。

  1. Assert: OInteger-Indexedエキゾチックオブジェクト
  2. Assert: Type(index) は Number型
  3. O.[[ContentType]] が BigInt なら、 ? ToBigInt(value) を numValue とする
  4. 3. でないなら、 ? ToNumber(value) を numValue とする
  5. O.[[ViewedArrayBuffer]] を buffer とする
  6. IsDetachedBuffer(buffer) が true なら、 TypeError例外をスローする
  7. ! IsValidIntegerIndex(O, index) が false なら、 false を返す
  8. O.[[ByteOffset]] を offset とする
  9. O.[[TypedArrayName]] の文字列値を arrayTypeName とする
  10. 表61arrayTypeName に対応する要素サイズ を elementSize とする
  11. (index × elementSize) + offsetindexedPosition とする
  12. 表61arrayTypeName に対応する要素型 を elementType とする
  13. SetValueInBuffer(buffer, indexedPosition, elementType, numValue, true, Unordered)を実行
  14. true を返す

9.4.6 モジュールネームスペースエキゾチックオブジェクト(Module Namespace Exotic Objects)

モジュールネームスペース(名前空間)エキゾチックオブジェクトは、ECMAScriptモジュールからエクスポートされたバインディングを公開するエキゾチックオブジェクトです(15.2.3を参照)。モジュールネームスペースエキゾチックオブジェクトの文字列キーの独自プロパティと、モジュールによってエクスポートされたバインディング名は1対1で対応しています。エクスポートされたバインディングには、export * exportアイテムを使用して間接的にエクスポートされたバインディングが含まれます。 各文字列値の独自のプロパティキーは、対応するエクスポートされたバインディング名のStringValueです。これらは、モジュールネームスペースエキゾチックオブジェクトの唯一の文字列キープロパティです。 そのような各プロパティには、属性{[[Writable]]:true,[[Enumerable]]:true,[[Configurable]]:false}があります。 モジュールネームスペースエキゾチックオブジェクトは拡張できません。

文字列キーの独自プロパティ:Symbolではないという意味だと思われる。

以下で定義している[[SetPrototypeOf]]、 [[IsExtensible]]、 [[PreventExtensions]]、 [[GetOwnProperty]]、 [[DefineOwnProperty]]、 [[HasProperty]]、 [[Get]]、 [[Set]]、 [[Delete]]、 および[[OwnPropertyKeys]]内部メソッドと、9.1にあるその他の重要な内部メソッドを持つオブジェクトはモジュールネームスペースエキゾチックオブジェクトです。これらのメソッドは、ModuleNamespaceCreateでインストールされます。

モジュールネームスペースエキゾチックオブジェクトには、表29で定義されている内部スロットがあります。

表29: モジュールネームスペースエキゾチックオブジェクトの内部スロット
内部スロット 内容
[[Module]] モジュールレコード 名前空間をエクスポートするモジュールレコード
[[Exports]] String型のList オブジェクトの独自のプロパティとして公開される、エクスポートされた名前の文字列値リスト。 リストは、引数comparefnundefinedを指定したArray.prototype.sortを使用してソートされたかのように順序付けられます。
[[Prototype]] Null このスロットの値は常にnullです(9.4.6.1を参照)。

モジュールネームスペースエキゾチックオブジェクトは、[[GetPrototypeOf]]を除くすべての内部メソッドの代替定義を提供します。これは、9.1.1で定義されたとおりに動作します。

9.4.6.1 [[SetPrototypeOf]] ( V )

モジュールネームスペースエキゾチックオブジェクトOの[[SetPrototypeOf]]内部メソッドが引数Vで呼び出されると、次の手順が実行されます。

  1. ? SetImmutablePrototype(O, V)を返す

9.4.6.2 [[IsExtensible]] ( )

モジュールネームスペースエキゾチックオブジェクトOの[[IsExtensible]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. false を返す

9.4.6.3 [[PreventExtensions]] ( )

モジュールネームスペースエキゾチックオブジェクトOの[[PreventExtensions]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. true を返す

9.4.6.4 [[GetOwnProperty]] ( P )

モジュールネームスペースエキゾチックオブジェクトOの[[GetOwnProperty]]内部メソッドがプロパティキーPで呼び出されると、次の手順が実行されます。

  1. Type(P) が Symbol型なら、OrdinaryGetOwnProperty(O, P)を返す
  2. O.[[Exports]] を exports とする
  3. Pexports の要素でないなら、 undefined を返す
  4. ? O.[[Get]](P, O) を value とする
  5. プロパティ記述子{ [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }を返す

9.4.6.5 [[DefineOwnProperty]] ( P, Desc )

モジュールネームスペースエキゾチックオブジェクトOの[[DefineOwnProperty]]内部メソッドがプロパティキーPとプロパティ記述子Descで呼び出されると、次の手順が実行されます。

  1. Type(P) が Symbol型なら、OrdinaryDefineOwnProperty(O, P, Desc)を返す
  2. ? O.[[GetOwnProperty]](P) を current とする
  3. currentundefined なら、 false を返す
  4. IsAccessorDescriptor(Desc) が true なら、 false を返す
  5. Desc.[[Writable]] が存在し、値が false なら、 false を返す
  6. Desc.[[Enumerable]] が存在し、値が false なら、 false を返す
  7. Desc.[[Configurable]] が存在し、値が true なら、 false を返す
  8. Desc.[[Value]] が存在するなら、 SameValue(Desc.[[Value]], current.[[Value]])を返す
  9. true を返す

9.4.6.6 [[HasProperty]] ( P )

モジュールネームスペースエキゾチックオブジェクトOの[[HasProperty]]内部メソッドがプロパティキーPで呼び出されると、次の手順が実行されます。

  1. Type(P) が Symbol型なら、 OrdinaryHasProperty(O, P)を返す
  2. O.[[Exports]] を exports とする
  3. Pexports の要素なら、 true を返す
  4. false を返す

9.4.6.7 [[Get]] ( P, Receiver )

モジュールネームスペースエキゾチックオブジェクトOの[[Get]]内部メソッドがプロパティキーPおよびECMAScript言語値Receiverで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. Type(P) が Symbol型なら、
    1. ? OrdinaryGet(O, P, Receiver)を返す
  3. O.[[Exports]] を exports とする
  4. Pexports の要素でないなら、 undefined を返す
  5. O.[[Module]] を m とする
  6. ! m.ResolveExport(P) を binding とする
  7. Assert: bindingResolvedBindingレコード
  8. binding.[[Module]] を targetModule とする
  9. Assert: targetModuleundefined ではない
  10. binding.[[BindingName]] が "*namespace*" なら
    1. ? GetModuleNamespace(targetModule)を返す
  11. targetModule.[[Environment]] を targetEnv とする
  12. targetEnvundefined なら、ReferenceError例外をスローする
  13. targetEnvEnvironmentRecordtargetEnvRec とする
  14. ? targetEnvRec.GetBindingValue(binding.[[BindingName]], true)を返す
ResolveExportには副作用はありません。 この操作が特定のexportNameresolveSetペアを引数として呼び出されるたびに、同じ結果を返す必要があります。 実装は、各モジュールネームスペースエキゾチックオブジェクトで[[Exports]]のResolveExportを実行した結果を事前計算またはキャッシュすることを選択することができます。

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

モジュールネームスペースエキゾチックオブジェクトOの[[Set]]内部メソッドがプロパティキーP、値V、およびECMAScript言語値Receiverで呼び出されると、次の手順が実行されます。

  1. false を返す

9.4.6.9 [[Delete]] ( P )

モジュールネームスペースエキゾチックオブジェクトOの[[Delete]]内部メソッドがプロパティキーPで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. If Type(P) Symbol型なら、
    1. ? OrdinaryDelete(O, P)を返す
  3. O.[[Exports]] を exports とする
  4. Pexports の要素なら、 false を返す
  5. true を返す

9.4.6.10 [[OwnPropertyKeys]] ( )

モジュールネームスペースエキゾチックオブジェクトOの[[OwnPropertyKeys]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. O.[[Exports]] のコピーを exports とする
  2. ! OrdinaryOwnPropertyKeys(O) を symbolKeys とする
  3. symbolKeys のすべての要素を exports の最後に追加する
  4. exportsを返す

9.4.6.11 ModuleNamespaceCreate ( module, exports )

引数moduleexportsで抽象操作ModuleNamespaceCreateを呼び出すと、新しいモジュールネームスペースエキゾチックオブジェクトを作成します。 次の手順を実行します。

  1. Assert: moduleモジュールレコード
  2. Assert: module.[[Namespace]] は undefined
  3. Assert: exports は 文字列値のリスト
  4. 表29の内部スロットを internalSlotsList とする
  5. ! MakeBasicObject(internalSlotsList) を M とする
  6. 9.4.6の内部メソッドを M の重要な内部メソッドとしてセットする
  7. nullM.[[Prototype]] にセットする
  8. moduleM.[[Module]] にセットする
  9. exportsと同じ値を含む新規リストを sortedExports とする。ただし、仮引数comparefnundefinedを指定したArray.prototype.sortでソートしたときと同じ順番で順位付ける。
  10. sortedExportsM.[[Exports]] にセットする
  11. 26.3の定義に対応する独自プロパティを M に作成する
  12. Mmodule.[[Namespace]] にセットする
  13. Mを返す

9.4.7 イミュータブルプロトタイプエキゾチックオブジェクト(Immutable Prototype Exotic Objects)

イミュータブル(不変)プロトタイプエキゾチックオブジェクトは、[[Prototype]]内部スロットを持ち、一度初期化すると変更されないエキゾチックオブジェクトです。

[[SetPrototypeOf]]内部メソッドがこの後定義している実装を使用する場合、オブジェクトはイミュータブルプロトタイプエキゾチックオブジェクトです。 個々のイミュータブルプロトタイプエキゾチックオブジェクトに応じて、他の重要な内部メソッドは任意の実装を使用できます。

他のエキゾチックなオブジェクトとは異なり、イミュータブルプロトタイプエキゾチックオブジェクトは専用の作成抽象操作がありません。 これは、%ObjectPrototype%およびホスト環境でのみ使用されますが、ホスト環境では、関連するオブジェクトが他の方法で作成されたエキゾチックオブジェクトである可能性があるため、専用の作成操作が必要になるからです。

9.4.7.1 [[SetPrototypeOf]] ( V )

イミュータブルプロトタイプエキゾチックオブジェクトOの[[SetPrototypeOf]]内部メソッドが引数Vで呼び出されると、次の手順が実行されます。

  1. ? SetImmutablePrototype(O, V)を返す

9.4.7.2 SetImmutablePrototype ( O, V )

引数OおよびVを指定してSetImmutablePrototype抽象操作が呼び出されると、次の手順が実行されます。

  1. Assert: Type(V) は Object型か Null
  2. ? O.[[GetPrototypeOf]]() を current とする
  3. SameValue(V, current) が true なら、 true を返す
  4. false を返す

9.5 プロキシオブジェクトの内部メソッドと内部スロット(Proxy Object Internal Methods and Internal Slots)

Proxyエキゾチックオブジェクト

プロキシオブジェクトはエキゾチックなオブジェクトであり、その基本的な内部メソッドはECMAScriptコードを使用して部分的に実装されています。 すべてのプロキシオブジェクトには、[[ProxyHandler]]という内部スロットがあります。 [[ProxyHandler]]の値は、プロキシのハンドラオブジェクトと呼ばれるオブジェクト、またはnullです。 ハンドラーオブジェクトのメソッド(表30を参照)を使用して、1つ以上のプロキシオブジェクトの内部メソッドの実装を強化できます。 すべてのプロキシオブジェクトには、[[ProxyTarget]]という内部スロットもあり、その値はオブジェクトまたはnull値です。 このオブジェクトは、プロキシのターゲットオブジェクトと呼ばれます。

重要な内部メソッド([[Call]]と該当する場合は[[Construct]]を含む)がこのセクションの定義を使用する場合、オブジェクトはプロキシエキゾチックオブジェクトです。 これらの内部メソッドはProxyCreateでインストールされます。

表30: プロキシハンドラーメソッド
内部メソッド ハンドラーメソッド
[[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

プロキシオブジェクトの内部メソッドの実装を提供するハンドラメソッドが呼び出されると、ハンドラーメソッドにプロキシーのターゲットオブジェクトがパラメーターとして渡されます。

ハンドラーメソッドを呼び出してプロキシオブジェクトの内部メソッドを実装すると、ハンドラーメソッドにプロキシーのターゲットオブジェクトがパラメーターとして渡されます。 プロキシのハンドラオブジェクトには、必ずしもすべての必須内部メソッドに対応するメソッドがあるとは限りません。 ハンドラーオブジェクトに内部トラップに対応するメソッドがない場合、プロキシのターゲットオブジェクトに対応する内部メソッドが呼び出されます。

プロキシオブジェクトの[[ProxyHandler]]および[[ProxyTarget]]内部スロットは、オブジェクト作成時に常に初期化され、その後の変更は通常できません。 一部のプロキシオブジェクトは、後で取り消されるように作成されます。 プロキシが取り消されると、その[[ProxyHandler]]および[[ProxyTarget]]内部スロットがnullに設定され、後でプロキシオブジェクトの内部メソッドを呼び出すとTypeError例外がスローされます。

プロキシオブジェクトは、内部メソッドの実装を任意のECMAScriptコードで提供できます。そのためプロキシオブジェクトに、6.1.7.3で定義されている不変条件に違反するハンドラメソッドを定義することが可能です。 6.1.7.3で定義されている内部メソッド不変式の一部は、本質的な完全性不変式です。 これらの不変条件は、このセクションで指定されたプロキシオブジェクトの内部メソッドによって明示的に適用されます。 ECMAScript実装は、起こり得るすべての不変の違反が存在する場合でも堅牢でなければなりません。

次のアルゴリズムの説明では、OがECMAScriptプロキシオブジェクト、Pがプロパティキー値、Vが任意のECMAScript言語値、Descがプロパティ記述子レコードであると想定しています。

9.5.1 [[GetPrototypeOf]] ( )

プロキシエキゾチックオブジェクトOの[[GetPrototypeOf]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. O.[[ProxyHandler]] を handler とする
  2. handlernull なら、 TypeError例外をスローする
  3. Assert: Type(handler) は Object型
  4. O.[[ProxyTarget]] を target とする
  5. ? GetMethod(handler, "getPrototypeOf") を trap とする
  6. trapundefined なら、
    1. ? target.[[GetPrototypeOf]]()を返す
  7. ? Call(trap, handler, « target ») を handlerProto とする
  8. Type(handlerProto) が Object型 または Null以外なら、 TypeError例外をスローする
  9. ? IsExtensible(target) を extensibleTarget とする
  10. extensibleTargettrue なら、 handlerProto を返す
  11. ? target.[[GetPrototypeOf]]() を targetProto とする
  12. SameValue(handlerProto, targetProto) が false なら、 TypeError例外をスローする
  13. handlerProtoを返す
プロキシオブジェクトの[[GetPrototypeOf]]は、次の不変条件を適用します。

  • [[GetPrototypeOf]]の結果は、Objectまたはnullのいずれかである必要があります。
  • ターゲットオブジェクトが拡張可能でない場合、プロキシオブジェクトに適用された[[GetPrototypeOf]]は、プロキシオブジェクトのターゲットオブジェクトに適用された[[GetPrototypeOf]]と同じ値を返す必要があります。

9.5.2 [[SetPrototypeOf]] ( V )

引数Vを指定してProxyエキゾチックオブジェクトOの[[SetPrototypeOf]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. Assert: Type(V) は Object型か Null
  2. O.[[ProxyHandler]] を handler とする
  3. handlernull なら、TypeError例外をスローする
  4. Assert: Type(handler) は Object型
  5. O.[[ProxyTarget]] を target とする
  6. ? GetMethod(handler, "setPrototypeOf") を trap とする
  7. trapundefined なら、
    1. ? target.[[SetPrototypeOf]](V)を返す
  8. ! ToBoolean(?Call(trap, handler, « target, V »)) を booleanTrapResult とする
  9. booleanTrapResultfalse なら、 false を返す
  10. ? IsExtensible(target) を extensibleTarget とする
  11. extensibleTargettrue なら、 true を返す
  12. ? target.[[GetPrototypeOf]]() を targetProto とする
  13. SameValue(V, targetProto) が false なら、TypeError例外をスローする
  14. true を返す
プロキシオブジェクトの[[SetPrototypeOf]]は、次の不変条件を適用します。

  • [[SetPrototypeOf]]の結果はブール値です。
  • ターゲットオブジェクトが拡張可能でない場合、引数値は、ターゲットオブジェクトに適用された[[GetPrototypeOf]]の結果と同じでなければなりません。

9.5.3 [[IsExtensible]] ( )

プロキシエキゾチックオブジェクトOの[[IsExtensible]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. O.[[ProxyHandler]] を handler とする
  2. handlernull なら、TypeError例外をスローする
  3. Assert: Type(handler) は Object型
  4. O.[[ProxyTarget]] を target とする
  5. ? GetMethod(handler, "isExtensible") を trap とする
  6. trapundefined なら、
    1. ? IsExtensible(target)を返す
  7. ! ToBoolean(?Call(trap, handler, « target »)) を booleanTrapResult とする
  8. ? IsExtensible(target) を targetResult とする
  9. SameValue(booleanTrapResult, targetResult) が false なら、TypeError例外をスローする
  10. booleanTrapResultを返す
プロキシオブジェクトの[[IsExtensible]]は、次の不変条件を適用します。

  • [[IsExtensible]]の結果はブール値です。
  • プロキシオブジェクトに適用される[[IsExtensible]]は、同じ引数でプロキシオブジェクトのターゲットオブジェクトに適用される[[IsExtensible]]と同じ値を返す必要があります。

9.5.4 [[PreventExtensions]] ( )

プロキシエキゾチックオブジェクトOの[[PreventExtensions]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. O.[[ProxyHandler]] を handler とする
  2. handlernull なら、TypeError例外をスローする
  3. Assert: Type(handler) は Object型
  4. O.[[ProxyTarget]] を target とする
  5. ? GetMethod(handler, "preventExtensions") を trap とする
  6. trapundefined なら、
    1. ? target.[[PreventExtensions]]()を返す
  7. ! ToBoolean(?Call(trap, handler, « target »)) を booleanTrapResult とする
  8. booleanTrapResulttrue なら、
    1. ? IsExtensible(target) を extensibleTarget とする
    2. extensibleTargettrue なら、TypeError例外をスローする
  9. booleanTrapResultを返す
プロキシオブジェクトの[[PreventExtensions]]は、次の不変条件を適用します。

  • [[PreventExtensions]]の結果はブール値です。
  • プロキシオブジェクトに適用された[[PreventExtensions]]は、プロキシオブジェクトのターゲットオブジェクトに適用された[[IsExtensible]]がfalseの場合にのみtrueを返します。

9.5.5 [[GetOwnProperty]] ( P )

プロキシエキゾチックオブジェクトOの[[GetOwnProperty]]内部メソッドがプロパティキーPで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. O.[[ProxyHandler]] を handler とする
  3. handlernull なら、TypeError例外をスローする
  4. Assert: Type(handler) は Object型
  5. O.[[ProxyTarget]] を target とする
  6. ? GetMethod(handler, "getOwnPropertyDescriptor") を trap とする
  7. trapundefined なら、
    1. ? target.[[GetOwnProperty]](P)を返す
  8. ?Call(trap, handler, « target, P ») を trapResultObj とする
  9. Type(trapResultObj) が Object型またはUndefined以外なら、 TypeError例外をスローする
  10. ? target.[[GetOwnProperty]](P) を targetDesc とする
  11. trapResultObjundefined なら、
    1. targetDescundefined なら、 undefined を返す
    2. targetDesc.[[Configurable]] が false なら、TypeError例外をスローする
    3. ? IsExtensible(target) を extensibleTarget とする
    4. extensibleTargetfalse なら、TypeError例外をスローする
    5. undefined を返す
  12. ? IsExtensible(target) を extensibleTarget とする
  13. ? ToPropertyDescriptor(trapResultObj) を resultDesc とする
  14. CompletePropertyDescriptor(resultDesc)を呼び出す
  15. IsCompatiblePropertyDescriptor(extensibleTarget, resultDesc, targetDesc) を valid とする
  16. validfalse なら、TypeError例外をスローする
  17. resultDesc.[[Configurable]] が false なら、
    1. targetDescundefined または targetDesc.[[Configurable]] が true なら、
      1. TypeError例外をスローする
    2. resultDescが [[Writable]]フィールドを持っていて、resultDesc.[[Writable]] が false なら、
      1. targetDesc.[[Writable]] が true なら、TypeError例外をスローする
  18. resultDescを返す
プロキシオブジェクトの[[GetOwnProperty]]は、次の不変条件を適用します。

  • [[GetOwnProperty]]の結果は、オブジェクトかundefinedでなければなりません。
  • プロパティが、ターゲットオブジェクトの構成不可能な独自のプロパティとして存在する場合、"プロパティが存在しない"と報告できません。
  • ターゲットオブジェクトが拡張可能でなく、ターゲットオブジェクトの独自プロパティとして存在しない限り、"プロパティが存在しない"と報告できません。
  • ターゲットオブジェクトが拡張可能でなく、ターゲットオブジェクトの独自プロパティとして存在しない限り、"プロパティが存在する"として報告できません。
  • プロパティが、ターゲットオブジェクトの設定不可能な独自プロパティとして存在しない限り、"設定不可"として報告できません。
  • プロパティが、ターゲットオブジェクトの設定および書き込みができない独自プロパティとして存在しない限り、"設定および書き込みができない"と報告することはできません。

9.5.6 [[DefineOwnProperty]] ( P, Desc )

プロキシエキゾチックオブジェクトOの[[DefineOwnProperty]]内部メソッドがプロパティキーPとプロパティ記述子Descで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. O.[[ProxyHandler]] を handler とする
  3. handlernull なら、TypeError例外をスローする
  4. Assert: Type(handler) は Object型
  5. O.[[ProxyTarget]] を target とする
  6. ? GetMethod(handler, "defineProperty") を trap とする
  7. trapundefined なら、
    1. ? target.[[DefineOwnProperty]](P, Desc)を返す
  8. FromPropertyDescriptor(Desc) を descObj とする
  9. ! ToBoolean(?Call(trap, handler, « target, P, descObj »)) を booleanTrapResult とする
  10. booleanTrapResultfalse なら、 false を返す
  11. ? target.[[GetOwnProperty]](P) を targetDesc とする
  12. ? IsExtensible(target) を extensibleTarget とする
  13. Desc が [[Configurable]]フィールドを持っていて、Desc.[[Configurable]] が false なら、
    1. truesettingConfigFalse とする
  14. 13.でないなら falsesettingConfigFalse とする
  15. targetDescundefined なら、
    1. extensibleTargetfalse なら、TypeError例外をスローする
    2. settingConfigFalsetrue なら、TypeError例外をスローする
  16. 15. でないなら、
    1. IsCompatiblePropertyDescriptor(extensibleTarget, Desc, targetDesc) が false なら、TypeError例外をスローする
    2. settingConfigFalsetruetargetDesc.[[Configurable]] が true なら、TypeError例外をスローする
    3. IsDataDescriptor(targetDesc) が truetargetDesc.[[Configurable]] が false で、targetDesc.[[Writable]] が true なら、
      1. Desc が [[Writable]]フィールドを持っていて、 Desc.[[Writable]] が false なら、TypeError例外をスローする
  17. true を返す
プロキシオブジェクトの[[DefineOwnProperty]]は、次の不変条件を適用します。

  • [[DefineOwnProperty]]の結果はブール値です。
  • ターゲットオブジェクトが拡張可能でない場合、プロパティを追加できません。
  • ターゲットオブジェクトに対応する設定不可能な独自プロパティが存在しない限り、プロパティを設定不可にすることはできません。
  • ターゲットオブジェクトに対応する設定不可能で書き込み不可能な独自プロパティが存在しない限り、設定不可能なプロパティは書き込み不可にすることはできません。
  • プロパティに対応するターゲットオブジェクトプロパティがある場合、[[DefineOwnProperty]]を使用してプロパティのプロパティ記述子をターゲットオブジェクトに適用しても、例外はスローされません。

9.5.7 [[HasProperty]] ( P )

プロキシエキゾチックオブジェクトOの[[HasProperty]]内部メソッドがプロパティキーPで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. O.[[ProxyHandler]] を handler とする
  3. handlernull なら、TypeError例外をスローする
  4. Assert: Type(handler) は Object型
  5. O.[[ProxyTarget]] を target とする
  6. ? GetMethod(handler, "has") を trap とする
  7. trapundefined なら、
    1. ? target.[[HasProperty]](P)を返す
  8. ! ToBoolean(?Call(trap, handler, « target, P »)) を booleanTrapResult とする
  9. booleanTrapResultfalse なら、
    1. ? target.[[GetOwnProperty]](P) を targetDesc とする
    2. targetDescundefined でないなら、
      1. targetDesc.[[Configurable]] が false なら、TypeError例外をスローする
      2. ? IsExtensible(target) を extensibleTarget とする
      3. extensibleTargetfalse なら、TypeError例外をスローする
  10. booleanTrapResultを返す
[[HasProperty]]プロキシオブジェクトの場合、次の不変条件が適用されます。

  • [[HasProperty]]の結果はブール値です。
  • プロパティは、ターゲットオブジェクトの構成不可能な独自プロパティとして存在する場合、存在しないと報告できません。
  • プロパティは、ターゲットオブジェクトの独自プロパティとして存在し、ターゲットオブジェクトが拡張可能でない場合、存在しないと報告できません。

9.5.8 [[Get]] ( P, Receiver )

プロキシエキゾチックオブジェクトOの[[Get]]内部メソッドがプロパティキーPおよびECMAScript言語値Receiverで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. O.[[ProxyHandler]] を handler とする
  3. handlernull なら、TypeError例外をスローする
  4. Assert: Type(handler) は Object型
  5. O.[[ProxyTarget]] を target とする
  6. ? GetMethod(handler, "get") を trap とする
  7. trapundefined なら、
    1. ? target.[[Get]](P, Receiver)を返す
  8. ?Call(trap, handler, « target, P, Receiver ») を trapResult とする
  9. ? target.[[GetOwnProperty]](P) を targetDesc とする
  10. targetDescundefined ではなく、 targetDesc.[[Configurable]] が false なら、
    1. IsDataDescriptor(targetDesc) が truetargetDesc.[[Writable]] が false なら、
      1. SameValue(trapResult, targetDesc.[[Value]]) が false なら、TypeError例外をスローする
    2. IsAccessorDescriptor(targetDesc) が true で、 targetDesc.[[Get]] が undefined なら、
      1. trapResultundefined でないなら、TypeError例外をスローする
  11. trapResultを返す
プロキシオブジェクトの[[Get]]は、次の不変条件を適用します。

  • プロパティについて報告される値は、ターゲットオブジェクトプロパティが書き込みおよび設定ができない独自データプロパティである場合、対応するターゲットオブジェクトプロパティの値と同じでなければなりません。
  • 対応するターゲットオブジェクトプロパティが、[[Get]]属性としてundefinedの設定不可能な独自アクセサープロパティである場合、プロパティについて報告される値はundefinedでなければなりません。

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

プロキシエキゾチックオブジェクトOの[[Set]]内部メソッドがプロパティキーP、値V、およびECMAScript言語値Receiverで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. O.[[ProxyHandler]] を handler とする
  3. handlernull なら、TypeError例外をスローする
  4. Assert: Type(handler) は Object型
  5. O.[[ProxyTarget]] を target とする
  6. ? GetMethod(handler, "set") を trap とする
  7. trapundefined なら、
    1. ? target.[[Set]](P, V, Receiver)を返す
  8. ! ToBoolean(?Call(trap, handler, « target, P, V, Receiver »)) を booleanTrapResult とする
  9. booleanTrapResultfalse なら、 false を返す
  10. ? target.[[GetOwnProperty]](P) を targetDesc とする
  11. targetDescundefined ではなく、targetDesc.[[Configurable]] が false なら、
    1. IsDataDescriptor(targetDesc) が true で targetDesc.[[Writable]] が false なら、
      1. SameValue(V, targetDesc.[[Value]]) が false なら、TypeError例外をスローする
    2. IsAccessorDescriptor(targetDesc) が true なら、
      1. targetDesc.[[Set]] が undefined なら、TypeError例外をスローする
  12. true を返す
プロキシオブジェクトの[[Set]]は、次の不変条件を適用します。

  • [[Set]]の結果はブール値です。
  • 対応するターゲットオブジェクトプロパティが、書き込み不可の構成可能な独自のデータプロパティである場合、プロパティの値を、対応するターゲットオブジェクトプロパティの値と異なる値に変更することはできません。
  • 対応するターゲットオブジェクトプロパティが [Set] 属性として定義されていない、構成可能でない独自のアクセサープロパティである場合は、プロパティの値を設定できません。

9.5.10 [[Delete]] ( P )

プロキシエキゾチックオブジェクトOの[[Delete]]内部メソッドがプロパティキーPで呼び出されると、次の手順が実行されます。

  1. Assert: IsPropertyKey(P) は true
  2. O.[[ProxyHandler]] を handler とする
  3. handler が null なら、TypeError例外をスローする
  4. Assert: Type(handler) は Object型
  5. O.[[ProxyTarget]] を target とする
  6. ? GetMethod(handler, "deleteProperty") を trap とする
  7. trapundefined なら、
    1. ? target.[[Delete]](P)を返す
  8. ! ToBoolean(?Call(trap, handler, « target, P »)) を booleanTrapResult とする
  9. booleanTrapResultfalse なら、 false を返す
  10. ? target.[[GetOwnProperty]](P) を targetDesc とする
  11. targetDescundefined なら、 true を返す
  12. targetDesc.[[Configurable]] が false なら、TypeError例外をスローする
  13. ? IsExtensible(target) を extensibleTarget とする
  14. extensibleTargetfalse なら、TypeError例外をスローする
  15. true を返す
プロキシオブジェクトの[[Delete]]は、次の不変式を強制します。

  • [[Delete]]の結果はブール値です。
  • プロパティが、ターゲットオブジェクトの構成不可能な独自プロパティとして存在する場合、削除済みとして報告することはできません。
  • プロパティがターゲットオブジェクトの独自プロパティとして存在し、ターゲットオブジェクトが拡張不可能である場合、プロパティを削除済みとして報告することはできません。

9.5.11 [[OwnPropertyKeys]] ( )

プロキシエキゾチックオブジェクトOの[[OwnPropertyKeys]]内部メソッドが呼び出されると、次の手順が実行されます。

  1. O.[[ProxyHandler]] を handler とする
  2. handlernull なら、TypeError例外をスローする
  3. Assert: Type(handler) は Object型
  4. O.[[ProxyTarget]] を target とする
  5. ? GetMethod(handler, "ownKeys") を trap とする
  6. trapundefined なら、
    1. ? target.[[OwnPropertyKeys]]()を返す
  7. ?Call(trap, handler, « target ») を trapResultArray とする
  8. ? CreateListFromArrayLike(trapResultArray, « String, Symbol ») を trapResult とする
  9. trapResult に重複するエントリが含まれている場合 TypeError例外をスローする
  10. ? IsExtensible(target) を extensibleTarget とする
  11. ? target.[[OwnPropertyKeys]]() を targetKeys とする
  12. Assert: targetKeys は、文字列とシンボルの値のみを含むリスト
  13. Assert: targetKeys には、重複エントリがない
  14. 空の新規ListtargetConfigurableKeys とする
  15. 空の新規ListtargetNonconfigurableKeys とする
  16. targetKeysの要素をkeyとして、keyごとに、
    1. ? target.[[GetOwnProperty]](key) を desc とする
    2. descundefined でなく desc.[[Configurable]] が false なら、
      1. targetNonconfigurableKeysの要素としてkeyを追加する
    3. b. でないなら、
      1. targetConfigurableKeysの要素としてkeyを追加する
  17. extensibleTarget が truetargetNonconfigurableKeysempty なら、
    1. trapResultを返す
  18. trapResultのコピーである新しいリスト を uncheckedResultKeys とする
  19. targetNonconfigurableKeysの要素をkeyとして、各keyに対して、
    1. keyuncheckedResultKeysの要素ではないなら、 TypeError例外をスローする
    2. uncheckedResultKeysから、keyを削除する
  20. extensibleTargettrue なら、trapResultを返す
  21. targetConfigurableKeysの要素をkeyとして、各keyに対して、
    1. keyuncheckedResultKeysの要素ではないなら、 TypeError例外をスローする
    2. uncheckedResultKeysから、keyを削除する
  22. uncheckedResultKeysempty でないなら、 TypeError例外をスローする
  23. trapResultを返す
プロキシオブジェクトの[[OwnPropertyKeys]]は、次の不変条件を適用します。

  • [[OwnPropertyKeys]] の結果はリストです。
  • 返されたリストには重複するエントリはありません。
  • 各結果リストの要素の型はStringまたはSymbolです。
  • 結果リストには、ターゲットオブジェクトのすべての構成不可能な独自プロパティのキーが含まれている必要があります。
  • ターゲット オブジェクトが拡張できない場合、結果リスト には、ターゲットオブジェクトの独自プロパティのすべてのキーが含まれ、その他の値は含まれていない必要があります。

9.5.12 [[Call]] ( thisArgument, argumentsList )

プロキシエキゾチックオブジェクトOの[[Call]]内部メソッドは、パラメーターthisArgumentおよびargumentsListで呼び出されます。 次の手順を実行します。

  1. O.[[ProxyHandler]] を handler とする
  2. handlernull なら、TypeError例外をスローする
  3. Assert: Type(handler) は Object型
  4. O.[[ProxyTarget]] を target とする
  5. ? GetMethod(handler, "apply") を trap とする
  6. trapundefined なら、
    1. ?Call(target, thisArgument, argumentsList)を返す
  7. ! CreateArrayFromList(argumentsList) を argArray とする
  8. ?Call(trap, handler, « target, thisArgument, argArray »)を返す
プロキシエキゾチックオブジェクトは、[[ProxyTarget]]内部スロットの初期値が[[Call]]内部メソッドを持つオブジェクトである場合にのみ、[[Call]]内部メソッドを持ちます。

9.5.13 [[Construct]] ( argumentsList, newTarget )

プロキシエキゾチックオブジェクトOの[[Construct]]内部メソッドは、ECMAScript言語値の空のリストである可能性のあるargumentsListnewTargetで呼び出されます。 次の手順を実行します。

  1. O.[[ProxyHandler]] を handler とする
  2. handlernull なら、TypeError例外をスローする
  3. Assert: Type(handler) は Object型
  4. O.[[ProxyTarget]] を target とする
  5. Assert: IsConstructor(target) は true
  6. ? GetMethod(handler, "construct") を trap とする
  7. trapundefined なら、
    1. ? Construct(target, argumentsList, newTarget)を返す
  8. ! CreateArrayFromList(argumentsList) を argArray とする
  9. ?Call(trap, handler, « target, argArray, newTarget ») を newObj とする
  10. Type(newObj) が Object型でないなら、TypeError例外をスローする
  11. newObjを返す
プロキシエキゾチックオブジェクトは、[[ProxyTarget]]内部スロットの初期値が[[Construct]]内部メソッドを持つオブジェクトである場合にのみ、[[Construct]]内部メソッドを持ちます。
プロキシオブジェクトの[[Construct]]は、次の不変式を適用します。

  • [[Construct]]の結果はオブジェクトでなければなりません。

9.5.14 ProxyCreate ( target, handler )

引数targethandlerを持つ抽象操作ProxyCreateは、新しいプロキシエキゾチックオブジェクトを作成します。 次の手順を実行します。

  1. Type(target) が Object型でないなら、TypeError例外をスローする
  2. target が プロキシエキゾチックオブジェクトで、 target.[[ProxyHandler]] が null なら、TypeError例外をスローする
  3. Type(handler) が Object型でないなら、TypeError例外をスローする
  4. handler が プロキシエキゾチックオブジェクトで、 handler.[[ProxyHandler]] が null なら、TypeError例外をスローする
  5. ! MakeBasicObject(« [[ProxyHandler]], [[ProxyTarget]] ») を P とする
  6. [[Call]]と[[Construct]]を除いて、9.5で定義されているメソッドを、Pの重要な内部メソッドとして設定する
  7. IsCallable(target) が true なら、
    1. 9.5.12の処理を P.[[Call]] にセット
    2. IsConstructor(target) が true なら、
      1. 9.5.13の処理を P.[[Construct]] にセット
  8. targetP.[[ProxyTarget]] にセットする
  9. handlerP.[[ProxyHandler]] にセットする
  10. Pを返す