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

これらの操作はECMAScript言語の一部ではありません。ここでは、ECMAScript言語のセマンティクスの仕様を支援する目的で定義されています。その他の、より専門的な抽象操作は、この仕様全体で定義しています。

7.1 型変換(Type Conversion)

ECMAScript言語は、必要に応じて暗黙的に自動型変換を実行します。特定の構造のセマンティクスを明確にするには、一連の変換抽象演算を定義します。 変換の抽象操作は多態的です。 ECMAScript言語型の値を受け入れることができます。 ただし、これらの操作では他の仕様型は使用されません。

BigInt型には、ECMAScript言語での暗黙的な変換はありません。 プログラマーはBigIntを明示的に呼び出して、他の型から値を変換する必要があります。

7.1.1 ToPrimitive ( input [ , PreferredType ] )

抽象演算ToPrimitiveは、引数inputとオプション引数PreferredTypeを取ります。 抽象演算ToPrimitiveは、そのinputを非オブジェクト型に変換します。 オブジェクトが複数のプリミティブ型に変換できる場合は、オプションのヒントPreferredTypeを使用してその型を優先することができます。 次のアルゴリズムに従って変換が行われます。

  1. Assert: inputECMAScript言語値
  2. Type(input)がオブジェクトなら
    1. PreferredType がないなら、"default"hint とする。
    2. PreferredType ヒントStringなら、"string"hint とする。
    3. a,b以外なら、
      1. Assert: ヒントNumber
      2. "number"hint とする
    4. ? GetMethod(input, @@toPrimitive)の結果をexoticToPrimとする
    5. exoticToPrimundefinedでないなら
      1. ? Call(exoticToPrim, input, « hint »)の結果をresultとする
      2. Type(result)がオブジェクトでないなら、resultを返す
      3. TypeError例外をスローする
    6. hint"default"なら、"number"hintにセットする
    7. ? OrdinaryToPrimitive(input, hint)の結果を返す
  3. inputを返す
ヒントなしでToPrimitiveを呼び出すと、通常はヒントがNumberであるかのように動作します。 ただし、@@ toPrimitiveメソッドを定義することで、オブジェクトがこの動作をオーバーライドできます。 この仕様で定義されているオブジェクトのうち、Dateオブジェクト(20.4.4.45を参照)とSymbolオブジェクト(19.4.3.5を参照)のみがデフォルトのToPrimitive動作をオーバーライドしています。 Dateオブジェクトは、ヒントStringをStringとして扱いません。

7.1.1.1 OrdinaryToPrimitive ( O, hint )

抽象操作OrdinaryToPrimitiveが引数Oとヒントhintを指定して呼び出されると、次の手順が実行されます。

  1. Assert: Type(O)がオブジェクト
  2. Assert: Type(hint)が文字列で、"string""number"のどちらか
  3. hint"string"なら
    1. « "toString", "valueOf" »methodNamesとする
  4. 3と異なるなら
    1. « "valueOf", "toString" »methodNamesとする
  5. methodNamesから順番に取り出した値をnameとし、For eachする
    1. ? Get(O, name)の結果をmethodとする
    2. IsCallable(method)の結果がtrueなら
      1. ? Call(method, O)の結果をresultとする
      2. Type(result)がオブジェクトでないなら、resultを返す
  6. TypeErrorをスローする

7.1.2 ToBoolean ( argument )

抽象演算ToBooleanは、表10に従ってargumentをBoolean型の値に変換します。

表10: ToBoolean変換
Argumentの型 変換結果
Undefined falseを返す
Null falseを返す
Boolean Argumentを返す
Number Argument+0-0NaNなら、falseを、そ例外はtrueを返す
String Argumentが長さ0の空文字ならfalseを、それ以外ならtrueを返す
Symbol trueを返す
BigInt Argument0nならfalseを、それ以外ならtrueを返す
Object trueを返す

7.1.3 ToNumeric ( value )

抽象演算ToNumericは、数値型またはBigInt型の数値に変換した値を返します。この抽象操作は次のように機能します。

  1. ? ToPrimitive(value, ヒントNumber)の結果を primValueとする
  2. Type(primValue)がBigIntなら、primValueを返す
  3. ? ToNumber(primValue)の結果を返す

7.1.4 ToNumber ( argument )

抽象演算ToNumberは、表11に従ってargumentを数値型の値に変換します。

表11: ToNumber変換
Argumentの型 変換結果
Undefined NaNを返す
Null +0を返す
Boolean Argumenttrueなら1を、falseなら+0を返す
Number Argumentをそのまま返す
String 以下の文法と変換アルゴリズムを参照してください。(7.1.4.1)
Symbol TypeError例外をスロー
BigInt TypeError例外をスロー
Object 次の手順をおこなう

  1. ? ToPrimitive(argument, ヒントNumber)の結果をprimValueとする
  2. ? ToNumber(primValue)の結果を返す

7.1.4.1 ToNumberに文字列型を適用する(ToNumber Applied to the String Type)

ToNumberに文字列型を適用する場合、UTF-16エンコードされたコードポイントのシーケンスとして解釈される入力文字列に次の文法を適用します(6.1.4)。
文法が文字列をStringNumericLiteralの拡張として解釈できない場合、ToNumberの結果はNaNになります。

UTF-16エンコードされたコードポイントのシーケンスとして解釈される入力文字列:ようするにスクリプト上での文字列
この文法の終端記号はすべて、Unicode Basic Multilingual Plane(BMP)の文字で構成されています。したがって、ペアにされているかどうかにかかわらず、文字列に上位サロゲートまたは下位サロゲートユニットが含まれている場合、ToNumberの結果はNaNになります。

上記で定義されていないすべての文法記号は、数値リテラルのレキシカル文法で定義されています(11.8.3

StringNumericLiteralNumericLiteralの構文にはいくつかの違いがあります。

7.1.4.1.1 実行時セマンティクス:MV(Runtime Semantics: MV)

文字列から数値への変換は、数値リテラルから実際の数値に変換(11.8.3を参照)と似ています。しかし詳細の一部が異なるため、ここでは文字列数値リテラルを数値型の値に変換するプロセスを示します。
この値は2つのステップで決定されます。最初に、文字列数値リテラルが数学的数値MV)に変換されます。 次に、変換した値を以下の方法で丸められます。以下に記載されていない文法記号のMVは、11.8.3.1で定義されています。

文字列数値リテラルの正確なMVが決定されると、数値型の値に丸められます。MVが0で、文字列数値リテラルの最初の非空白コードポイントが-でないなら、丸めた値は+0です。-なら、丸めた値は-0です。

MVが0でないなら、丸めた値はMVの数値(6.1.6.1参照)です。

ただし、リテラルにStrUnsignedDecimalLiteralが含まれ、リテラルの有効数字20桁以上の場合、 リテラルの20文字以降は0に置き換える、または0に置き換えて20番目を+1して得たリテラルをMVの数値とします。
数字がExponentPartの一部ではなく0でない、または(0のとき)、左方向にゼロ以外の数字があり、右方向にExponentPartではないゼロ以外の数字があるとき、その数字は有効です。

StrUnsignedDecimalLiteralは、浮動小数点表記

7.1.5 ToInteger ( argument )

抽象演算ToIntegerは、argumentを整数の数値に変換します。 この抽象操作は次のように処理します。

  1. ? ToNumber(argument)の結果をnumberとする
  2. numberが、 NaN+0-0なら、+0を返す
  3. numberが、 +∞ -∞なら、numberを返す
  4. floor(abs(number))の結果にnumberと同じ符号を付加した数値integerとする
  5. integerが、 -0なら、+0を返す
  6. integerを返す

7.1.6 ToInt32 ( argument )

抽象演算ToInt32は、argumentを-231~231-1の範囲の232個の整数値のいずれかに変換します。 この抽象操作は次のように処理します。

  1. ? ToNumber(argument)の結果をnumberとする
  2. numberが、 NaN+0-0+∞ -∞なら、+0を返す
  3. floor(abs(number))の結果にnumberと同じ符号を付加した数値intとする
  4. int modulo 232int32bitとする
  5. int32bit ≧2 31 なら、int32bit - 232を、それ以外なら、int32bitを返す

上記のToInt32の定義を前提とします。

  • ToInt32抽象操作はべき等です。生成された値は、2回目の呼び出しで変更されません。
  • ToInt32( ToUint32( x ) )は、xのすべての値でToInt32( x )と等しくなります。(+∞と-∞が+0にマッピングされるのは、この後者のプロパティを保持するためです。)
  • ToInt32は-0~+0をマッピングします。
べき等:冪等性。何回やっても結果が同じこと。

7.1.7 ToUint32 ( argument )

抽象演算ToUint32は、argumentを0~232-1の範囲の232個の整数値のいずれかに変換します。 この抽象操作は次のように処理します。

  1. ? ToNumber(argument)の結果をnumberとする
  2. numberが、 NaN+0-0+∞ -∞なら、+0を返す
  3. floor(abs(number))の結果にnumberと同じ符号を付加した数値intとする
  4. int modulo 232int32bitとする
  5. int32bitを返す

上記のToUint32の定義より、

  • ToUint32とToInt32は手順5が異なります。
  • ToUint32抽象操作はべき等です。生成された値は、2回目の呼び出しで変更されません。
  • ToUint32( ToUint32( x ) )は、xのすべての値でToUint32( x )と等しくなります。(+∞と-∞が+0にマッピングされるのは、この後者のプロパティを保持するためです。)
  • ToUint32は-0~+0をマッピングします。

7.1.8 ToInt16 ( argument )

抽象演算ToInt16は、argumentを-32768~32767の範囲の216個の整数値のいずれかに変換します。この抽象操作は次のように処理します。

  1. ? ToNumber(argument)の結果をnumberとする
  2. numberが、 NaN+0-0+∞ -∞なら、+0を返す
  3. floor(abs(number))の結果にnumberと同じ符号を付加した数値intとする
  4. int modulo 216int16bitとする
  5. int16bit ≧ 2 15 なら、int16bit - 216を、それ以外なら、int16bitを返す

7.1.9 ToUint16 ( argument )

抽象演算ToUint16は、argumentを0〜216-1の範囲の216個の整数値のいずれかに変換します。この抽象操作は次のように処理します。

  1. ? ToNumber(argument)の結果をnumberとする
  2. numberが、 NaN+0-0+∞ -∞なら、+0を返す
  3. floor(abs(number))の結果にnumberと同じ符号を付加した数値intとする
  4. int modulo 216int16bitとする
  5. int16bitを返す

上記のToUint16の定義を前提とします。

  • ToUint32とToUint16の違いは、手順4の232を216に置き換えた点だけです。
  • ToUint16は-0~+0をマッピングします。

7.1.10 ToInt8 ( argument )

抽象演算ToInt8は、argumentを-128から127までの範囲の28個の整数値のいずれかに変換します。 この抽象操作は次のように処理します。

  1. ? ToNumber(argument)の結果をnumberとする
  2. numberが、 NaN+0-0+∞ -∞なら、+0を返す
  3. floor(abs(number))の結果にnumberと同じ符号を付加した数値intとする
  4. int modulo 28int8bitとする
  5. int8bit ≧ 2 7 なら、int8bit - 28を、それ以外なら、int8bitを返す

7.1.11 ToUint8 ( argument )

抽象演算ToUint8は、argumentを0〜255の範囲の28の整数値のいずれかに変換します。 この抽象操作は次のように処理します。

  1. ? ToNumber(argument)の結果をnumberとする
  2. numberが、 NaN+0-0+∞ -∞なら、+0を返す
  3. floor(abs(number))の結果にnumberと同じ符号を付加した数値intとする
  4. int modulo 28int8bitとする
  5. int8bitを返す

7.1.12 ToUint8Clamp ( argument )

抽象演算ToUint8Clampは、argumentを0〜255の範囲の28の整数値のいずれかに変換します。 この抽象操作は次のように機能します。

  1. ? ToNumber(argument)の結果をnumberとする
  2. numberが、 NaNなら、+0を返す
  3. number0 なら、+0を返す
  4. number255 なら、255を返す
  5. floor( number )の結果をfとする
  6. f + 0.5number なら、f + 1 を返す
  7. numberf + 0.5 なら、f を返す
  8. f が奇数 なら、f + 1 を返す
  9. f を返す
他の整数に関するECMAScript変換抽象操作とは異なり、ToUint8Clampは非整数値を丸め、+∞を0に変換しません(他の関数は切り捨てます)。ToUint8Clampは「半分から偶数に丸める」タイブレークを行います。 これは、Math.roundとは異なります。

number:3.6 => f:3 => (3 + 0.5 < 3.6) なので、4を返す
number:3.4 => f:3 => (3.4 < 3 + 0.5) なので、3を返す

number の小数が.5のとき、6.と7.は一致しない。

このとき8.は、

number:3.5 => f:3 => 奇数なので4を返す
number:2.5 => f:2 => 偶数なので2を返す

7.1.13 ToBigInt ( argument )

抽象演算ToBigIntは、argumentをBigInt値に変換するか、Numberからの暗黙的な変換が必要な場合にスローします。

  1. ? ToPrimitive(argument , ヒント Number ) の結果を prim とする
  2. 表12に対応する値を返します。
表12: BigInt変換
argumentの型 結果
Undefined TypeError例外をスロー
Null TypeError例外をスロー
Boolean primtrue なら 1n を、false なら 0n を返す
BigInt primを返す
Number TypeError例外をスロー
String
  1. ! StringToBigInt(prim) の結果を n とする
  2. nNaN なら、SyntaxError例外をスロー
  3. nを返す
Symbol TypeError例外をスロー

7.1.14 StringToBigInt ( argument )

7.1.4.1のアルゴリズムに次の変更を加えて処理します。

  • StrUnsignedDecimalLiteral
    プロダクションをDecimalDigitsに置き換まる。これにより無限大、小数点、指数が除外される。
  • MVNaNのとき、NaNを返す。それ以外の場合、数値に丸めるのではなく、MVに正確に対応するBigIntを返す。

7.1.15 ToBigInt64 ( argument )

抽象演算ToBigInt64は、引数を-263から263-1までの範囲の264個の整数値の1つに変換します。 この抽象操作は次のように処理します。

  1. ? ToBigInt(argument)の結果を n とする
  2. n modulo 264int64bitとする
  3. int64bit ≧ 2 63 なら、int64bit - 264を、それ以外なら、int64bitを返す

7.1.16 ToBigUint64 ( argument )

抽象演算ToBigUint64は、引数を0から264-1までの範囲の264個の整数値のひとつに変換します。 この抽象操作は次のように処理します。

  1. ? ToBigInt(argument)の結果を n とする
  2. n modulo 264int64bitとする
  3. int64bitを返す

7.1.17 ToString ( argument )

抽象演算ToStringは、表13に従ってargumentをString型の値に変換します。

表13: ToString変換
argumentの型 結果
Undefined "Undefined"を返す
Null "Null"を返す
Boolean argumenttrue なら "true" を、false なら "false" を返す
Number ! Number::toString(argument) の結果を返す
String argumentを返す
Symbol TypeError例外を返す
BigInt ! BigInt::toString(argument) の結果を返す
Object 次の手順を適用します。

  1. ? ToPrimitive(argument, ヒント String)の結果をprimValueとする
  2. ToString (primValue)の結果を返す

7.1.18 ToObject ( argument )

抽象演算ToObjectは、表14に従ってargumentをObject型の値に変換します。

表14: ToObject変換
argumentの型 結果
Undefined TypeError例外をスローする
Null TypeError例外をスローする
Boolean [[BooleanData]]内部スロットにargumentが設定されている、新しいブールオブジェクトを返す。ブール型オブジェクトの説明については、19.3を参照。
Number [[NumberData]]内部スロットにargumentが設定されている、新しいNumberオブジェクトを返す。Numberオブジェクトの説明については、20.1を参照。
String [[StringData]]内部スロットにargumentが設定されている、新しいStringオブジェクトを返す。 Stringオブジェクトの説明については、21.1を参照。
Symbol [[SymbolData]]内部スロットにargumentが設定されている、新しいSymbolオブジェクトを返す。 Symbolオブジェクトの説明については、19.4を参照。
BigInt [[BigIntData]]内部スロットにargumentが設定されている、新しいBigIntオブジェクトを返す。 BigIntオブジェクトの説明については、20.2を参照。
Object argumentを返す

7.1.19 ToPropertyKey ( argument )

抽象操作ToPropertyKeyは、次の手順を実行して、argumentをプロパティキーとして使用できる値に変換します。

  1. ? ToPrimitive(argument, ヒント String)の結果を keyとする
  2. Type(key)が Symbolなら
    1. keyを返す
  3. ! ToString(key)の結果を返す

7.1.20 ToLength ( argument )

抽象演算ToLengthは、argumentを配列のようなオブジェクトの長さとして使用するのに適した整数に変換します。 次の手順を実行します。

  1. ? ToInteger(argument)の結果を lenとする
  2. len ≦ +0 なら、+0を返す
  3. min(len, 253 - 1)

7.1.21 CanonicalNumericIndexString ( argument )

抽象演算CanonicalNumericIndexStringは、argumentToStringによって生成される数値の文字列表現である場合、または文字列 "-0"の場合、argumentを数値に変換した値を返します。 それ以外の場合は、undefinedを返します。 この抽象操作は次のように処理します。

  1. Assert: Type(argument) はString
  2. argument"-0"なら、-0を返す
  3. ! ToNumber(argument)の結果をnとする
  4. SameValue(! ToString(n), argument)の結果がfalseなら、undefinedを返す
  5. nを返す

正規の数値文字列は、CanonicalNumericIndexString抽象操作がundefinedを返さない文字列値です。

7.1.22 ToIndex ( value )

抽象演算ToIndexは、valueが有効な整数インデックスである場合、valueを負でない整数に変換して返します。この抽象操作は次のように処理します。

  1. valueundefinedなら、
    1. 0indexとする
  2. 1.と異なるなら
    1. ? ToInteger(value)の結果をintegerIndexとする
    2. integerIndex0 なら、RangeError例外をスロー
    3. ! ToLength(integerIndex)の結果をindexとする
    4. ! SameValue(integerIndex, index) の結果がfalseなら、RangeError例外をスロー
  3. indexを返す

7.2 テストと比較の操作(Testing and Comparison Operations)

7.2.1 RequireObjectCoercible ( argument )

argumentToObjectを使用してオブジェクトに変換できない値である場合、抽象操作RequireObjectCoercibleはエラーをスローします。 これは、表15で定義されています。

表15: RequireObjectCoercibleの結果
argumentの型 結果
Undefined TypeError例外をスロー
Null TypeError例外をスロー
Boolean argumentを返す
Number argumentを返す
String argumentを返す
Symbol argumentを返す
BigInt argumentを返す
Object argumentを返す

7.2.2 IsArray ( argument )

抽象演算IsArrayは引数argumentを取り、次の手順を実行します。

  1. Type(argument)がObjectでないなら、falseを返す
  2. argumentArrayエキゾチックオブジェクトなら、trueを返す
  3. argumentProxyエキゾチックオブジェクトなら
    1. argument.[[ProxyHandler]]がnullなら、TypeError 例外をスロー
    2. argument.[[ProxyTarget]]をtargetとする
    3. ? IsArray(target)の結果を返す
  4. falseを返す

7.2.3 IsCallable ( argument )

抽象操作IsCallableは、ECMAScript言語値であるargumentが、[[Call]]内部メソッドを持つ呼び出し可能な関数であるかどうかを判別します。

  1. Type(argument)がObjectでないなら、falseを返す
  2. argumentが[[Call]]内部メソッドを持っているなら、trueを返す
  3. falseを返す

7.2.4 IsConstructor ( argument )

抽象演算IsConstructorは、ECMAScript言語値であるargumentが、[[Construct]]内部メソッドを持つ関数オブジェクトであるかどうかを判別します。

  1. Type(argument)がObjectでないなら、falseを返す
  2. argumentが[[Construct]]内部メソッドを持っているなら、trueを返す
  3. falseを返す

7.2.5 IsExtensible ( O )

抽象演算IsExtensibleは、あるオブジェクトOにプロパティを追加できるかどうかを判別します。ブール値が返されます。 この抽象操作は、次の手順を実行します。

  1. Assert: Type(O)はObject型
  2. ? O.[[IsExtensible]]()の実行結果を返す

7.2.6 IsInteger ( argument )

抽象演算IsIntegerは、argumentが有限整数の数値であるかどうかを判別します。

  1. Type(argument)がNumber型でないなら、falseを返す
  2. argumentNaN+∞-∞なら、falseを返す
  3. floor(abs(argument)) ≠ abs(argument)なら、falseを返す
  4. trueを返す

7.2.7 IsNonNegativeInteger ( argument )

抽象演算IsNonNegativeIntegerは、argumentが負でない整数の数値であるかどうかを判別します。

  1. ! IsInteger(argument)の結果がtrueで、argument ≧ 0 なら、trueを返す
  2. falseを返す

7.2.8 IsPropertyKey ( argument )

抽象操作IsPropertyKeyは、ECMAScript言語値である引数argumentが、プロパティキーとして使用できる値であるかどうかをを判別します。

  1. Type(argument)がString型なら、trueを返す
  2. Type(argument)がSymbol型なら、trueを返す
  3. falseを返す

7.2.9 IsRegExp ( argument )

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

  1. Type(argument)がObjectでないなら、falseを返す
  2. ? Get(argument, @@match)の結果をmatcherとする
  3. matcherundefinedでないなら、! ToBoolean(matcher)の結果を返す
  4. argumentが[[RegExpMatcher]] 内部スロットを持っているなら、trueを返す
  5. falseを返す

7.2.10 IsStringPrefix ( p, q )

抽象演算IsStringPrefixは、文字列pが文字列qのプレフィックス(接頭辞)であるかどうかを判別します。

  1. Assert: Type(p)はString型
  2. Assert: Type(q)はString型
  3. qpと他の文字列rの文字列連結である場合、trueを返す。 それ以外の場合は、falseを返す。
rは空の文字列になる可能性があるため、任意の文字列はそれ自体のプレフィックスです。

7.2.11 SameValue ( x, y )

内部比較抽象演算SameValue(xy)(xとyはECMAScript言語値)は、trueまたはfalseを返します。 次のように実行されます。

  1. Type(x)とType(y)が異なるなら、falseを返す
  2. Type(x)がNumber型またはBigInt型なら、
    1. ! Type(x)::sameValue(x, y)の結果を返す
  3. ! SameValueNonNumeric(x, y)の結果を返す
このアルゴリズムは、符号付きゼロとNaNの扱いが厳密等値比較アルゴリズムとは異なります。
2.a は、Number::sameValueBigInt::sameValueのどちらかが呼び出される

7.2.12 SameValueZero ( x, y )

内部比較抽象演算SameValueZero(x, y)(xyはECMAScript言語値)は、trueまたはfalseを返します。 この比較は次のように実行されます。

  1. Type(x)とType(y)が異なるなら、falseを返す
  2. Type(x)がNumber型またはBigInt型なら、
    1. ! Type(x)::sameValueZero(x, y)の結果を返す
  3. ! SameValueNonNumeric(x, y)の結果を返す
SameValueZeroは、+0および-0の扱いのみがSameValueと異なります。

7.2.13 SameValueNonNumeric ( x, y )

内部比較抽象演算SameValueNonNumeric(x, y)は、xy共に数値型の値ではないとき、trueまたはfalseを返します。 この比較は次のように実行されます。

  1. Assert: Type(x)はNumber型またはBigInt型ではない
  2. Assert: Type(x)とType(y)は同じ型
  3. Type(x)が Undefined型なら、trueを返す
  4. Type(x)が Null型なら、trueを返す
  5. Type(x)が String型なら、
    1. xyがまったく同じコード単位のシーケンスである場合(対応するインデックスで同じ長さと同じコード単位)、trueを返す。 それ以外は、falseを返す。
  6. Type(x)が Boolean型なら、
    1. xyが両方ともtrueまたはfalseなら、trueを返す。 それ以外は、falseを返す。
  7. Type(x)が Symbol型なら、
    1. xyが同じSymbol 値なら、trueを返す。 それ以外は、falseを返す。
  8. xyが同じObject値なら、trueを返す。 それ以外は、falseを返す。

7.2.14 抽象関係比較(Abstract Relational Comparison)

x < yxyは値)の比較では、truefalse、またはundefined(少なくとも1つのオペランドがNaNであることを示します)が生成されます。

アルゴリズム上では xyに加えて、LeftFirstという名前のブールフラグをパラメーターとして受け取ります。フラグは、潜在的に目に見える副作用を伴う操作がxおよびyに対して実行される順序を制御するために使用されます。 ECMAScriptは式の左から右への評価を指定するため、これは必要です。 LeftFirstのデフォルト値はtrueであり、xパラメーターが、yパラメーターの対応する式の左側にある式に対応することを示します。 LeftFirstfalseの場合は、その逆であり、xの前にyに対して操作を実行する必要があります。 このような比較は次のように実行されます。

  1. LeftFirsttrueなら、
    1. ? ToPrimitive(x, ヒント Number)の結果をpxとする
    2. ? ToPrimitive(y, ヒント Number)の結果をpyとする
  2. 1.と異なるなら、
    1. 注:評価の順序を逆にして、左から右への評価を維持する必要があります。
    2. ? ToPrimitive(y, ヒント Number)の結果をpyとする
    3. ? ToPrimitive(x, ヒント Number)の結果をpxとする
  3. Type(px)と Type(py)ともにString型なら、
    1. IsStringPrefix(py, px)の結果がtrueなら、falseを返す
    2. IsStringPrefix(px, py)の結果がtrueなら、trueを返す
    3. pxとpyの同じインデックスのコード値が異なる負でない最小の整数を、kとする。(どちらのStringも他方の接頭辞ではないため、このようなkが必要です。)
    4. pxのインデックスkのコード値を、mとする。
    5. pyのインデックスkのコード値を、nとする。
    6. mnならtrue、それ以外ならfalseを返す
  4. 3.と異なるなら
    1. Type(px)がBigInt型、 Type(py)がString型なら、
      1. ! StringToBigInt(py)の結果をnyとする
      2. nyNaNなら、undefinedを返す
      3. BigInt::lessThan(px, ny)の結果を返す
    2. Type(px)がString型、 Type(py)がBigInt型なら、
      1. ! StringToBigInt(px)の結果をnxとする
      2. nxNaNなら、undefinedを返す
      3. BigInt::lessThan(bx, py)の結果を返す
    3. 注:pxpyはプリミティブ値であるため、評価順序は重要ではありません。
    4. ? ToNumeric(px)の結果をnxとする
    5. ? ToNumeric(py)の結果をnyとする
    6. Type(nx)とType(ny)の型が同じなら、Type(nx)::lessThan(nx, ny)の結果を返す
    7. Assert: Type(nx)がBigInt型でType(ny)がNumber型、またはType(nx)がNumber型でType(ny)がBigInt型
    8. nxまたはnyNaNなら、undefinedを返す
    9. nx-∞ または ny+∞ なら、trueを返す
    10. nx+∞ または ny-∞ なら、falseを返す
    11. nx数学的数値ny数学的数値より小さいならtrueを、それ以外ならfalseを返す
4.f:Type(nx)::lessThan(nx, ny)
BigInt::lessThanまたはNumber::lessThan
ステップ3は、論理OR演算の代わりに論理AND演算を使用している点が、加算演算子+(12.8.3)のアルゴリズムのステップ7と異なります。
論理AND演算って何のこと???

ステップ3:Type(px)とType(py)ともにString型
加算演算子のステップ7:Type(lprim)とType(rprim)どちらかがString型

文字列の比較では、コードユニット値のシーケンスに対して単純な辞書式順序を使用します。Unicode仕様で定義されている文字または文字列の等価性と照合順序の、より複雑で意味論的な方向の定義は使用しません。 したがって、Unicode標準に従って標準的に等しい文字列値は、等しくないとしてテストできます。 実際、このアルゴリズムは、両方の文字列がすでに正規化された形式であることを前提としています。 また、補助文字を含む文字列の場合、UTF-16コードユニット値のシーケンスの辞書式順序は、コードポイント値のシーケンスの辞書順とは異なることに注意してください。

7.2.15 抽象等値比較(Abstract Equality Comparison)

比較x == yxyは値)は、trueまたはfalseを生成します。 この比較は次のように実行されます。

  1. Type(x)とType(y)が同じ型なら、
    1. 厳密等値比較 x === yの結果を返す
  2. xnullyundefinedなら、trueを返す
  3. xundefinedynullなら、trueを返す
  4. Type(x)がNumber型で、Type(y)がString型なら、x == ! ToNumber(y)の比較結果を返す
  5. Type(x)がString型で、Type(y)がNumber型なら、! ToNumber(x) == y の比較結果を返す
  6. Type(x)がBigInt型で、Type(y)がString型なら
    1. ! StringToBigInt(y)の結果をnとする
    2. nNaNなら、falseを返す
    3. x == nの比較結果を返す
  7. Type(x)がString型で、Type(y)がBigInt型なら、y == xの比較結果を返す
  8. Type(x)がBoolean型なら、! ToNumber(x) == y の比較結果を返す
  9. Type(y)がBoolean型なら、x == ! ToNumber(y) の比較結果を返す
  10. Type(x)が String、Number、BigInt、Symbolのどれかで、Type(y)がObjectなら、x == ToPrimitive(y)の比較結果を返す
  11. Type(x)がObjectで、Type(y)がString、Number、BigInt、Symbolのどれかなら、ToPrimitive(x) == yの比較結果を返す
  12. Type(x)が BigInt型で、Type(y)がNumber型、またはその逆なら、
    1. xまたはyNaN+∞-∞のどれかなら、falseを返す。
    2. xy数学的数値が同じ値ならtrueを、異なるならfalseを返す
  13. falseを返す

7.2.16 厳密等値比較(Strict Equality Comparison)

比較x === yxyは値)は、trueまたはfalseを生成します。 この比較は次のように実行されます。

  1. Type(x)とType(y)の型が異なるなら、falseを返す
  2. Type(x)がNumberまたはBigInt型なら、
    1. ! Type(x)::equal(x, y)の結果を返す
  3. ! SameValueNonNumeric(x, y)の結果を返す
Type(x)::equal(x, y)
BigInt::equalNumber::equal
このアルゴリズムは、符号付きゼロとNaNの扱いがSameValueと異なります。

7.3 オブジェクト操作(Operations on Objects)

7.3.1 MakeBasicObject ( internalSlotsList )

抽象操作MakeBasicObjectは、通常のオブジェクトエキゾチックなオブジェクトの両方を含む、アルゴリズムによって作成されるすべてのECMAScriptオブジェクトの中核となるもので、オブジェクトの作成を一元化します。

  1. Assert: internalSlotsListは、内部スロット名のListです。
  2. internalSlotsList内の全ての名前を内部スロットとして持つ、新しく作成されたオブジェクトをobjとします
  3. 9.1で指定されている、通常のオブジェクトのデフォルトメソッド定義を、objの基本的な内部メソッドとしてセットします。
  4. Assert: 呼び出し元がobjの[[GetPrototypeOf]][[SetPrototypeOf]] の両方の必須内部メソッドをオーバーライドしない場合、internalSlotsListには[[Prototype]]が含まれます。
  5. Assert: 呼び出し元がobjのすべての[[SetPrototypeOf]][[IsExtensible]]、および[[PreventExtensions]]の必須内部メソッドをオーバーライドしない場合、internalSlotsListには[[Extensible]]が含まれます。
  6. internalSlotsListに[[Extensible]]が含まれるなら、trueobj.[[Extensible]]にセットします
  7. objを返します
この仕様では、エキゾチックなオブジェクトArrayCreateBoundFunctionCreateなどの抽象的な操作内でMakeBasicObjectを呼び出して基本的な基礎オブジェクトを取得し、次に取得したオブジェクトの内部メソッドの一部またはすべてをオーバーライドしています。
エキゾチックなオブジェクトの作成をカプセル化するために、オブジェクトの基本的な内部メソッドは、これらの操作以外では変更されません。

7.3.2 Get ( O, P )

抽象操作Getは、オブジェクトの特定のプロパティの値を取得します。操作は引数OPで呼び出されます。Oはオブジェクト、Pはプロパティキーです。 この抽象操作は、次の手順を実行します。

  1. Assert: Type(O)はObject型
  2. Assert: IsPropertyKey(P)の結果がtrue
  3. ? O.[[Get]](P, O)の結果を返す

7.3.3 GetV ( V, P )

抽象操作GetVは、ECMAScript言語値の特定のプロパティの値を取得します。 値がオブジェクトでない場合、プロパティの検索は、値の型に適したラッパーオブジェクトを使用して実行されます。操作は引数VPで呼び出されます。Vは値で、Pはプロパティキーです。 この抽象操作は、次の手順を実行します。

  1. Assert: IsPropertyKey(P)の結果がtrue
  2. ? ToObject(V)の結果をOとする
  3. ? O.[[Get]](P, V)の結果を返す

7.3.4 Set ( O, P, V, Throw )

抽象操作Setは、オブジェクトの特定のプロパティの値を設定します。 操作は引数OPV、およびThrowで呼び出されます。ここで、Oはオブジェクト、Pはプロパティキー、Vはプロパティの新しい値、Throwはブールフラグです。 この抽象操作は、次の手順を実行します。

  1. Assert: Type(O)はObject型
  2. Assert: IsPropertyKey(P)はtrue
  3. Assert: Type(Throw)は Boolean型
  4. ? O.[[Set]](P, V, O)の結果をsuccessとする
  5. successfalseThrowtrueなら、TypeError例外をスロー
  6. successを返す

7.3.5 CreateDataProperty ( O, P, V )

抽象操作CreateDataPropertyは、オブジェクトに独自プロパティを作成します。 この操作は、引数Oはオブジェクト、Pはプロパティキー、Vはプロパティの値です。 この抽象操作は、次の手順を実行します。

  1. Assert: Type(O)はObject型
  2. Assert: IsPropertyKey(P)はtrue
  3. PropertyDescriptor型{ [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }を、newDescとする
  4. ? O.[[DefineOwnProperty]] (P, newDesc)の結果を返す
この抽象操作は、ECMAScript言語の割り当て演算子が作成するプロパティと同じデフォルト属性が設定されたプロパティを作成します。通常は、プロパティが存在していない状態で呼び出されます。しかし存在していて構成できなかったり、Oが拡張できない場合、[[DefineOwnProperty]]falseを返します。

7.3.6 CreateMethodProperty ( O, P, V )

抽象操作CreateMethodPropertyは、オブジェクトに独自プロパティを作成します。 引数Oはオブジェクト、Pはプロパティキー、Vはプロパティの値です。 この抽象操作は、次の手順を実行します。

  1. Assert: Type(O)はObject型
  2. Assert: IsPropertyKey(P)はtrue
  3. PropertyDescriptor型{ [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }を、newDescとする
  4. ? O.[[DefineOwnProperty]] (P, newDesc)の結果を返す
この抽象操作は、組み込みメソッドおよびクラス宣言構文を使用して定義されたメソッドで使用されるものと同じデフォルト属性が設定されているプロパティを作成します。通常は、プロパティが存在していない状態で呼び出されます。しかし存在していて構成できなかったり、Oが拡張できない場合、[[DefineOwnProperty]]falseを返します。
CreateMethodPropertyとCreateDataPropertyは、 3.の[[Enumerable]]の値のみ異なる。
CreateMethodPropertyは[[Enumerable]]がfalseのため、for-inで列挙されない

7.3.7 CreateDataPropertyOrThrow ( O, P, V )

抽象操作CreateDataPropertyOrThrowは、オブジェクトに独自プロパティを作成します。プロパティの更新を実行できない場合は、TypeError例外をスローします。 引数Oはオブジェクト、Pはプロパティキー、Vはプロパティの値です。 この抽象操作は、次の手順を実行します。

  1. Assert: Type(O)はObject型
  2. Assert: IsPropertyKey(P)はtrue
  3. ? CreateDataProperty(O, P, V)の結果をsuccessとする
  4. successfalseなら、TypeError例外をスローする
  5. successを返す
この抽象操作は、ECMAScript言語の割り当て演算子が作成するプロパティと同じデフォルト属性が設定されたプロパティを作成します。通常は、プロパティが存在していない状態で呼び出されます。しかし存在していて構成できなかったり、Oが拡張できない場合、[[DefineOwnProperty]]falseを返し、この操作によってTypeError例外がスローされます。

7.3.8 DefinePropertyOrThrow ( O, P, desc )

抽象操作DefinePropertyOrThrowは、オブジェクトの[[DefineOwnProperty]]内部メソッドを呼び出し要求されたプロパティを更新します。更新できない場合はTypeError例外をスローします。 引数Oはオブジェクト、Pはプロパティキー、descはプロパティのプロパティ記述子です。 この抽象操作は、次の手順を実行します。

  1. Assert: Type(O)はObject型
  2. Assert: IsPropertyKey(P)はtrue
  3. ? O.[[DefineOwnProperty]] (P, desc)の結果をsuccessとする
  4. successfalseなら、TypeError例外をスローする
  5. successを返す

7.3.9 DeletePropertyOrThrow ( O, P )

抽象操作DeletePropertyOrThrowは、オブジェクトの特定の独自プロパティを削除します。プロパティを削除できない場合は、例外がスローされます。 引数Oはオブジェクト、Pはプロパティキーです。 この抽象操作は、次の手順を実行します。

  1. Assert: Type(O)はObject型
  2. Assert: IsPropertyKey(P)はtrue
  3. ? O.[[Delete]] (P, newDesc)の結果をsuccessとする
  4. successfalseなら、TypeError例外をスローする
  5. successを返す

7.3.10 GetMethod ( V, P )

抽象操作GetMethodは、特定のプロパティの値が関数のとき、プロパティの値を取得します。 引数VはECMAScript言語値、Pはプロパティキーです。 この抽象操作は、次の手順を実行します。

  1. Assert: IsPropertyKey(P)はtrue
  2. ? GetV(V, P)の結果をfuncとする
  3. funcundefinedまたはnullなら、undefinedを返す
  4. IsCallable(func)がfalseなら、TypeError例外をスロー
  5. funcを返す

7.3.11 HasProperty ( O, P )

抽象操作HasPropertyは、オブジェクトが指定されたキーを持つプロパティがあるかどうかを判断します。 プロパティは、独自プロパティだけでなく継承プロパティも対象です。 ブール値が返されます。 操作は引数OとPで呼び出されます。Oはオブジェクト、Pはプロパティキーです。 この抽象操作は、次の手順を実行します。

  1. Assert: Type(O)はObject型
  2. Assert: IsPropertyKey(P)はtrue
  3. ? O.[[HasProperty]](P)の結果を返す

7.3.12 HasOwnProperty ( O, P )

抽象演算HasOwnPropertyは、オブジェクトが指定されたキーに対応する独自プロパティがあるかどうかを判断します。 引数Oはオブジェクト、Pはプロパティキーです。 この抽象操作は、次の手順を実行します。

  1. Assert: Type(O)はObject型
  2. Assert: IsPropertyKey(P)はtrue
  3. ? O.[[GetOwnProperty]] (P)の結果をdescとする
  4. descundefinedなら、false例を返す
  5. trueを返す

7.3.13 Call ( F, V [ , argumentsList ] )

抽象操作Callは、関数オブジェクト[[Call]] 内部メソッドを呼び出します。 引数Fは関数オブジェクト、Vは[[Call]]のthis値であるECMAScript言語値、argumentsListはオプションで、[[Call]] 内部メソッドに渡される値です。 argumentsListが存在しない場合、空のListが渡されます。この抽象操作は、次の手順を実行します。

  1. argumentsList が存在しないなら、空のListargumentsListにセットする
  2. IsCallable(F)がfalseなら、TypeError例外をスロー
  3. ? F.[[Call]] (V, argumentsList)の結果を返す

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

抽象操作Constructは、関数オブジェクトの[[Construct]] 内部メソッドを呼び出します。 引数Fは関数オブジェクト、 argumentsListおよびnewTargetは、[[Construct]] 内部メソッドに引数として渡される値です。 argumentsListが存在しない場合、新しい空のListが使用されます。 newTargetが存在しない場合、Fが使用されます。 この抽象操作は、次の手順を実行します。

  1. newTargetが存在しないなら、FnewTargetにセットする
  2. argumentsListが存在しないなら、空のListargumentsListにセットする
  3. Assert: IsConstructor(F)はtrue
  4. Assert: IsConstructor(newTarget)はtrue
  5. ? F.[[Construct]] (argumentsList, newTarget)の結果を返す
newTargetが存在しない場合、この操作は次と同等です:new F(... argumentsList)

7.3.15 SetIntegrityLevel ( O, level )

抽象操作SetIntegrityLevelは、levelの値に応じてオブジェクトOが持っている独自プロパティの[[Writable]]および[[Configurable]]属性を更新します。この抽象操作は、次の手順を実行します。

  1. Assert: Type(O) は Object型
  2. Assert: levelsealedまたはfrozen
  3. ? O.[[PreventExtensions]]()の結果をstatusとする
  4. statusfalseなら、falseを返す
  5. ? O.[[OwnPropertyKeys]] ()の結果をkeysとする
  6. levelsealedなら
    1. keysから取り出した値をkとして、それぞれ次を実行
      1. ? DefinePropertyOrThrow(O, k, PropertyDescriptor型{ [[Configurable]]: false })を実行
  7. 6.でないなら
    1. Assert: levelfrozen
    2. keysから取り出した値をkとして、それぞれ次を実行
      1. ? O.[[GetOwnProperty]](k)の結果をcurrentDescとする
      2. currentDescundefinedでないなら、
        1. IsAccessorDescriptor(currentDesc)がtrueなら、
          1. PropertyDescriptor型{ [[Configurable]]: false }をdescとする
        2. 上と異なるなら
          1. PropertyDescriptor型{ [[Configurable]]: false, [[Writable]]: false }をdescとする
        3. ? DefinePropertyOrThrow(O, k, desc)を実行する
  8. trueを返す

7.3.16 TestIntegrityLevel ( O, level )

抽象演算TestIntegrityLevelは、オブジェクトの一連の独自のプロパティが修正されているかどうかを判断します。この抽象操作は、次の手順を実行します。

  1. Assert: Type(O) は Object型
  2. Assert: levelsealedまたはfrozen
  3. ? [[IsExtensible]](O)の結果をextensibleとする
  4. extensibletrueなら、falseを返す
  5. 注:オブジェクトが拡張可能な場合、そのプロパティは検査されません。
  6. ? O.[[OwnPropertyKeys]]()の結果を keysとする
  7. keysから取り出した値をkとして、それぞれ次を実行
    1. ? O.[[GetOwnProperty]](k)の結果をcurrentDescとする
    2. currentDescundefinedでないなら
      1. currentDesc.[[Configurable]]trueなら、falseを返す
      2. levelfrozen で、IsDataDescriptor(currentDesc) がtrueなら、
        1. currentDesc.[[Writable]]trueなら、falseを返す
  8. trueを返す

7.3.17 CreateArrayFromList ( elements )

抽象操作CreateArrayFromListは、リストelementsからArrayオブジェクトを作成します。 この抽象操作は、次の手順を実行します。

  1. Assert: elementsは、すべての要素がECMAScript言語値であるList
  2. ! ArrayCreate(0)の結果を array とする
  3. 0n とする
  4. elementsから取り出した値を e として、それぞれ次を実行
    1. ! CreateDataPropertyOrThrow(array, ! ToString(n), e)を実行
    2. n + 1n にセット
  5. array を返す

7.3.18 LengthOfArrayLike ( obj )

抽象操作LengthOfArrayLikeは、配列のようなオブジェクトの「length」プロパティの値を返します。

  1. Assert: Type(obj)はObject型
  2. ? ToLength(? Get( obj, "length") ) の結果を返す

配列のようなオブジェクト(array-like object)

配列のようなオブジェクト(array-like object)とは、この操作で突然の完了で終了せずに、整数を返すオブジェクトです。

通常、配列のようなオブジェクトには、整数のインデックス名を持ついくつかのプロパティもあります。 ただし、これはこの定義の要件ではありません。
この定義の要件ではありません?
オブジェクトが整数のインデックスを持っていなくても、LengthOfArrayLikeが整数を返せばarray-likeということ
ArrayオブジェクトとStringオブジェクトは、配列のようなオブジェクトの一例です。

7.3.19 CreateListFromArrayLike ( obj [ , elementTypes ] )

抽象オペレーションCreateListFromArrayLikeは、配列のようなオブジェクトobjのインデックス付きプロパティの一連の値をListで取得します。 オプションの引数elementTypesは、取得対象となる型名のリストです。 この抽象操作は、次の手順を実行します。

  1. elementTypesが存在しないなら、« Undefined, Null, Boolean, String, Symbol, Number, BigInt, Object »elementTypes にセット
  2. Type(obj)がObject型でないなら、TypeError例外をスロー
  3. ? LengthOfArrayLike(obj)の結果を len とする
  4. 空のListlistとする
  5. 0をindexとする
  6. 以下を indexlen の間繰り返す
    1. ! ToString(index) の結果を indexName とする
    2. ? Get(obj, indexName) の結果を next とする
    3. Type(next) がelementTypes内の型と一致しないなら、TypeError例外をスロー
    4. nextlistの最後に追加
    5. index + 1index にセット
  7. listを返す

7.3.20 Invoke ( V, P [ , argumentsList ] )

抽象演算Invokeは、ECMAScript言語値のメソッドプロパティを呼び出します。 引数Vはプロパティのルックアップポイントであり、Callメソッドにthis値として渡されます。Pはプロパティキー、argumentsListCallメソッドに渡される引数値のリストです。 argumentsListが存在しない場合、新しい空のリストが使用されます。この抽象操作は、次の手順を実行します。

  1. Assert: IsPropertyKey(P) は true
  2. argumentsList がないなら、空のリストをargumentsListにセット
  3. ? GetV(V, P)をfuncとする
  4. ? Call(func, V, argumentsList) の結果を返す

7.3.21 OrdinaryHasInstance ( C, O )

抽象オペレーションOrdinaryHasInstanceは、オブジェクトOがコンストラクターCから継承されているかどうかを判断する規定のアルゴリズムです。判定はプロトタイプチェーンを辿ります。この抽象オペレーションは、次の手順を実行します。

  1. IsCallable(C)がfalseなら、falseを返す
  2. C が [[BoundTargetFunction]]内部スロットを持っているなら
    1. C.[[BoundTargetFunction]] を BC とする
    2. ? InstanceofOperator(O, BC) の結果を返す
  3. Type(O) がObject型でないなら、 false を返す
  4. ? Get(C, "prototype") の結果を P とする
  5. Type(P) がObject型でないなら、 TypeError をスロー
  6. 以下を繰り返す
    1. ? O.[[GetPrototypeOf]] () の結果を O とする
    2. Onullなら、falseを返す
    3. SameValue(P, O)の結果がtrueなら 、trueを返す

7.3.22 SpeciesConstructor ( O, defaultConstructor )

抽象演算SpeciesConstructorは、オブジェクトOから新しいオブジェクトを作成するために必要なコンストラクターを取得します。defaultConstructor引数は、コンストラクターが見つからない場合の規定値です。 抽象操作は次の手順を実行します。

  1. Assert: Type(O) は Object型
  2. ? Get(O, "constructor") の結果を C とする
  3. Cundefined なら、defaultConstructorを返す
  4. Assert: Type(C) が Object型でないなら、 TypeError例外をスロー
  5. ? Get(O, @@species) の結果を S とする
  6. Sundefinedまたはnull なら、defaultConstructorを返す
  7. IsConstructor(S) が trueなら、Sを返す
  8. TypeError例外をスロー

7.3.23 EnumerableOwnPropertyNames ( O, kind )

抽象演算EnumerableOwnPropertyNamesは、オブジェクトOと、keyvaluekey+valueのいずれかの値であるkindで呼び出されると、次の手順が実行されます。

  1. Assert: Type(O) は Object型
  2. ? O.[[OwnPropertyKeys]]() の結果をownKeysとする
  3. 空のリストをpropertiesとする
  4. ownKeysから順番に値を取り出しkeyとし、それぞれ次の処理をおこなう
    1. Type(key)が、String型なら
      1. ? O.[[GetOwnProperty]] (key) の結果を desc とする
      2. descundefined ではなく、desc.[[Enumerable]]true なら、
        1. kindkey なら、properties に keyを追加
        2. 異なるなら
          1. ? Get(O, key) の結果を value とする
          2. kindvalue なら、properties に valueを追加
          3. 異なるなら
            1. Assert: kindkey+value
            2. ! CreateArrayFromList(« key, value ») の結果を entry とする
            3. properties に entryを追加
  5. properties を返す

7.3.24 GetFunctionRealm ( obj )

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

  1. Assert: ! IsCallable(obj) は true
  2. obj が [[Realm]]内部スロットを持っているなら
    1. obj.[[Realm]] を返す
  3. objバインド関数エキゾチックオブジェクトなら
    1. obj.[[BoundTargetFunction]] を target とする
    2. ? GetFunctionRealm(target) を返す
  4. objProxyエキゾチックオブジェクトなら
    1. obj.[[ProxyHandler]] が null なら、TypeError例外をスローする
    2. obj.[[ProxyTarget]] を proxyTarget とする
    3. ? GetFunctionRealm(proxyTarget) を返す
  5. 現在のレルムレコードを返す
ステップ5に到達するのは、objが[[Realm]]内部スロットを持たない非標準関数のエキゾチックオブジェクトである場合のみです。

7.3.25 CopyDataProperties ( target, source, excludedItems )

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

  1. Assert: Type(target) は Object型
  2. Assert: excludedItems は プロパティキーのリスト
  3. source が undefined または null なら、 target を返す
  4. ! ToObject(source) を from とする
  5. ? from.[[OwnPropertyKeys]] () を keys とする
  6. keys から値を取り出して nextKey とし、それぞれ次を処理する
    1. falseexcluded とする
    2. excludedItems から値を取り出して  e とし、それぞれ次を処理する
      1. SameValue(e, nextKey) が true なら
        1. true を excluded にセット
    3. excluded が false なら
      1. ? from.[[GetOwnProperty]](nextKey) の結果を desc とする
      2. descundefined でなく、 desc.[[Enumerable]]true なら
        1. ? Get(from, nextKey) の結果を propValue とする
        2. ! CreateDataPropertyOrThrow(target, nextKey, propValue) を実行する
  7. target を返す
この操作に渡されるtargetは常に、新しく作成されたオブジェクトであり、エラーがスローされた場合に直接アクセスすることはできません。

7.4 イテレータオブジェクトの操作(Operations on Iterator Objects)

Common Iteration Interfaces(25.1)を参照してください。

7.4.1 GetIterator ( obj [ , hint [ , method ] ] )

抽象操作GetIteratorは、引数objとオプション引数hintおよびmethodを受け取り、次の手順を実行します。

  1. hintが指定されなかったら、sync を hint とする
  2. Assert: hintsync または async
  3. method が指定されなかったら、
    1. hintasyncなら
      1. ? GetMethod(obj, @@asyncIterator) の結果を method とする
      2. methodundefined なら
        1. ? GetMethod(obj, @@iterator) の結果をsyncMethodとする
        2. ? GetIterator(obj, sync, syncMethod) の結果を syncIteratorRecord とする
        3. ! CreateAsyncFromSyncIterator(syncIteratorRecord) の結果を返す
    2. a.でなければ ? GetMethod(obj, @@iterator) の結果を method にセット
  4. ? Call(method, obj) の結果を iterator とする
  5. Type(iterator) が Object型でないなら, TypeError例外をスローする
  6. ? GetV(iterator, "next") の結果を nextMethod とする
  7. Record型 { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false } を iteratorRecord とする
  8. iteratorRecordを返す

7.4.2 IteratorNext ( iteratorRecord [ , value ] )

抽象操作IteratorNextは引数iteratorRecordとオプションの引数valueで呼び出されると、次の手順を実行します。

  1. value が指定されていないなら
    1. ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]) の結果を result とする
  2. 1.でないなら
    1. ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « value ») の結果を result とする
  3. Type(result) Object型でないなら, TypeError例外をスローする
  4. resultを返す

7.4.3 IteratorComplete ( iterResult )

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

  1. Assert: Type(iterResult) は Object型
  2. ! ToBoolean(? Get(iterResult, "done")) の結果を返す

7.4.4 IteratorValue ( iterResult )

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

  1. Assert: Type(iterResult) は Object型
  2. ? Get(iterResult, "value") の結果を返す

7.4.5 IteratorStep ( iteratorRecord )

抽象オペレーションIteratorStepは、引数iteratorRecordで呼び出されます。
手順ではiteratorRecord.[[NextMethod]]を呼び出すことにより、iteratorRecord.[[Iterator]]の次の値を要求します。
イテレータが最後に到達するとfalseを、次の値が利用可能な場合はIteratorResultオブジェクトを返します。
IteratorStepは次の手順を実行します。

  1. ? IteratorNext(iteratorRecord) の結果を result とする
  2. ? IteratorComplete(result) の結果を done とする
  3. done が true なら false を返す
  4. result を返す

7.4.6 IteratorClose ( iteratorRecord, completion )

引数iteratorRecordcompletionを持つ抽象オペレーションIteratorCloseは、完了時に通常実行するアクションを実行する必要があることをイテレータに通知します。

  1. Assert: Type(iteratorRecord.[[Iterator]]) は Object型
  2. Assert: completion完了レコード
  3. iteratorRecord.[[Iterator]] を iterator とする
  4. ? GetMethod(iterator, "return") の結果を return とする
  5. "return"undefined なら Completion(completion) を返す
  6. Call(return, iterator) の結果を innerResult とする
  7. completion.[[Type]] が throw なら Completion(completion) を返す
  8. innerResult.[[Type]] が throw なら return Completion(innerResult) を返す
  9. IType(innerResult.[[Value]]) がObject型でないなら TypeError例外をスローする.
  10. Completion(completion) を返す

7.4.7 AsyncIteratorClose ( iteratorRecord, completion )

引数iteratorRecordcompletionを持つ抽象操作AsyncIteratorCloseは、完了状態に達したときに通常実行するアクションを実行する必要があることを非同期イテレーターに通知します。

  1. Assert: Type(iteratorRecord.[[Iterator]]) が Object型
  2. Assert: completion完了レコード
  3. iteratorRecord.[[Iterator]] を iterator とする
  4. ? GetMethod(iterator, "return") の結果を return とする
  5. Ireturnundefined なら Completion(completion) を返す
  6. Call(return, iterator) を innerResult  とする
  7. innerResult.[[Type]] が normal なら Await(innerResult.[[Value]]) の結果を innerResult にセット
  8. completion.[[Type]] が throw なら Completion(completion) を返す
  9. innerResult.[[Type]] が throw なら Completion(innerResult) を返す
  10. If Type(innerResult.[[Value]]) Object型でないなら TypeError例外をスローする.
  11. Completion(completion) を返す

7.4.8 CreateIterResultObject ( value, done )

引数valuedoneを指定して実行する抽象操作CreateIterResultObjectは、次の手順を実行して、IteratorResultインターフェースをサポートするオブジェクトを作成します。

  1. Assert: Type(done) は Boolean型
  2. OrdinaryObjectCreate(%Object.prototype%) の結果を obj とする
  3. ! CreateDataPropertyOrThrow(obj, "value", value) を実行する
  4. ! CreateDataPropertyOrThrow(obj, "done", done) を実行する
  5. obj を返す

7.4.9 CreateListIteratorRecord ( list )

引数listで呼び出される抽象操作CreateListIteratorRecordは、次のメソッドがlistの連続する要素を返すIterator(25.1.1.2)オブジェクトレコードを作成します。 次の手順を実行します。

  1. OrdinaryObjectCreate(%IteratorPrototype%, « [[IteratedList]], [[ListNextIndex]] ») の結果を iterator とする
  2. list を iterator.[[IteratedList]] にセット
  3. Set iterator.[[ListNextIndex]] to 0.
  4. ListIteratorNext Functionsで定義しているアルゴリズムステップを steps とする
  5. ! CreateBuiltinFunction(steps, « ») の結果を next とする
  6. Record型{ [[Iterator]]: iterator, [[NextMethod]]: next, [[Done]]: false } を返す

7.4.9.1 ListIteratorNext Functions

ListIteratorNext関数は、匿名の組み込み関数です。 引数なしで呼び出されると、次の手順を実行します。

  1. this値を O とする
  2. Assert: Type(O) は Object型
  3. Assert: O は [[IteratedList]]内部スロットを持っている
  4. O.[[IteratedList]] を list とする
  5. O.[[ListNextIndex]] を index とする
  6. list の要素数を len とする
  7. indexlen なら
    1. CreateIterResultObject(undefined, true) の結果を返す
  8. index + 1 を O.[[ListNextIndex]] にセット
  9. CreateIterResultObject(list[index], false) の結果を返す

ListIteratorNext関数の「length」プロパティは0です。