Web IDL

現行標準 — 最終更新

参加方法:
GitHub whatwg/webidl新しい課題未解決の課題
Matrixでチャット
コミット履歴:
GitHub whatwg/webidl/commits
このコミット時点のスナップショット
@webidl
テスト:
web-platform-tests webidl/進行中の作業
翻訳 (参考):
日本語
简体中文
한국어

概要

この標準は、Webブラウザーで実装されることを目的としたインターフェースを記述するためのインターフェース定義言語であるWeb IDLを定義します。

1. はじめに

この節は参考情報です。

この現行標準は、Webブラウザーで実装されることを目的としたインターフェースを記述するためのインターフェース定義言語、Web IDLを定義します。Web IDLは、Webプラットフォームにおける一般的なスクリプトオブジェクトの振る舞いをより容易に指定できるようにする、さまざまな機能を備えたIDLのバリエーションです。Web IDLで記述されたインターフェースがJavaScript実行環境内の構造にどのように対応するかも、ここで詳述します。

具体的には、Web IDLはWebプラットフォームオブジェクトの表面APIを定義するための構文と、APIがJavaScriptの構造としてどのように現れるかを詳細に定義するJavaScriptバインディングを提供します。これにより、グローバルプロパティの追加、数値入力の処理、イテレーション動作の公開などの一般的な作業が、Webプラットフォーム仕様間で一貫性を保てるようになります。各仕様はWeb IDLでインターフェースを記述し、API固有の詳細は文章で規定します。

「JavaScript」という用語は、公式のECMAScriptという名称ではなく、より広く知られているECMA-262を指すために使用しています。

2. インターフェース定義言語

この節では、Web IDLという言語について説明します。これはWebプラットフォームのAPIのインターフェースを定義するために使用できます。Web APIを定義する仕様は、定義しているAPIのインターフェース(オブジェクトが持つ状態や振る舞い)を記述するIDLフラグメントを1つ以上含めることができます。 IDLフラグメントは、Definitions文法記号に一致する定義の列です。 実装がサポートするIDLフラグメントの集合に順序はありません。 完全な文法と記法の説明についてはIDL文法を参照してください。

IDLフラグメントに現れることができる 定義の種類は以下の通りです: インターフェースパーシャルインターフェース定義インターフェースミックスインパーシャルミックスイン定義コールバック関数コールバックインターフェース名前空間パーシャル名前空間定義辞書パーシャル辞書定義型定義includes文です。 これらはすべて以下の節で定義されています。

定義Definitionに一致するもの)は、 拡張属性ExtendedAttributeListに一致するもの)のリストを前置することができ、 言語バインディングでの定義の扱い方を制御します。 この仕様で定義されている言語バインディング非依存の拡張属性については§ 2.14 拡張属性で、 JavaScriptバインディング固有のものについては§ 3.3 拡張属性で説明します。

[extended_attributes]
interface identifier {
  /* interface_members... */
};
Definitions ::
    ExtendedAttributeList Definition Definitions
    ε
Definition ::
    CallbackOrInterfaceOrMixin
    Namespace
    Partial
    Dictionary
    Enum
    Typedef
    IncludesStatement

以下はIDLフラグメントの例です。

[Exposed=Window]
interface Paint { };

[Exposed=Window]
interface SolidColor : Paint {
  attribute double red;
  attribute double green;
  attribute double blue;
};

[Exposed=Window]
interface Pattern : Paint {
  attribute DOMString imageURL;
};

[Exposed=Window]
interface GraphicalWindow {
  constructor();
  readonly attribute unsigned long width;
  readonly attribute unsigned long height;

  attribute Paint currentPaint;

  undefined drawRectangle(double x, double y, double width, double height);

  undefined drawText(double x, double y, DOMString text);
};

ここでは4つのインターフェースが定義されています。 GraphicalWindowインターフェースには、 2つの読み取り専用 属性、 1つの書き込み可能属性、および2つの操作が定義されています。 GraphicalWindowインターフェースを実装するオブジェクトは、使用する言語に応じて、これらの属性と操作を適切な形で公開します。

JavaScriptでは、IDLインターフェースの属性はアクセサプロパティとして、操作はプロトタイプオブジェクト上の組み込み関数オブジェクトとしてデータプロパティとして公開されます。GraphicalWindowを実装する各JavaScriptオブジェクトは、そのプロトタイプオブジェクトをプロトタイプチェーン上に持ちます。

GraphicalWindowに現れるコンストラクター操作によって、JavaScript実装ではコンストラクターが存在し、new GraphicalWindow()と呼び出すことでそのインターフェースを実装する新しいオブジェクトが返されます。

すべてのインターフェースは、[Exposed] 拡張属性を持ち、この属性によってインターフェースがWindowオブジェクトであるレルムグローバルオブジェクトでのみ利用可能となります。

2.1. 名前

すべてのインターフェースパーシャルインターフェース定義名前空間パーシャル名前空間定義辞書パーシャル辞書定義列挙型コールバック関数コールバックインターフェースおよび 型定義(まとめて名前付き定義と呼ぶ)、 そしてすべての定数属性辞書メンバーには 識別子があり、一部の 操作にも識別子がある。 識別子は宣言内のどこかにidentifierトークンとして現れることで決まる:

注: 操作は、getterやsetterなど特殊な操作を宣言する際には識別子を持たない場合がある。

これらすべての構造において、識別子identifierトークンの値から 先頭のU+005F(_)を除いたものとなる。

注: 先頭のU+005F(_)は、識別子が予約語のように見えるのを回避するために使用される。たとえば「interface」という名前のインターフェースを定義できるようにするためである。識別子を元に戻すために先頭のU+005F(_)は削除される。

操作の引数は識別子としてやや広い範囲を取ることができる。操作宣言において、引数の識別子は型の直後に指定され、identifierトークンか、 ArgumentNameKeyword記号に一致するキーワードのいずれかで与えられる。これらのキーワードが使われる場合、先頭のアンダースコアでエスケープする必要はない。

interface interface_identifier {
  return_type operation_identifier(argument_type argument_identifier /* , ... */);
};
ArgumentNameKeyword ::
    attribute
    callback
    const
    constructor
    deleter
    dictionary
    enum
    getter
    includes
    inherit
    interface
    iterable
    maplike
    mixin
    namespace
    partial
    readonly
    required
    setlike
    setter
    static
    stringifier
    typedef
    unrestricted

もしidentifierトークンが使われた場合、 操作引数の識別子はそのトークンの値から 先頭のU+005F(_)を除いたものとなる。 代わりにArgumentNameKeywordキーワードトークンが使われた場合、 操作引数の識別子はそのトークンそのものとなる。

上記IDL構造の識別子(操作引数以外)は "constructor"、"toString" であってはならず、 またU+005F(_)で始まってはならない。これらは予約済み識別子と呼ばれる。

toJSON識別子予約済み識別子ではないが、 通常の操作でのみ、 オブジェクトをJSON型に変換するために使用しなければならない。 詳細は§ 2.5.3.1 toJSONで説明する。

注: 特定の構造に対する識別子名のさらなる制限は後続の節で規定される場合がある。

ある実装がサポートするIDLフラグメント集合内では、 すべてのインターフェース名前空間辞書列挙型コールバック関数コールバックインターフェース型定義の識別子は、 他のインターフェース名前空間辞書列挙型コールバック関数コールバックインターフェース型定義の識別子と同じであってはならない。

IDLフラグメント内では、 定義への参照は 参照先定義の宣言より後に現れる必要はない。参照はIDLフラグメントをまたいで行うこともできる。

したがって、次のIDLフラグメントは有効です:

[Exposed=Window]
interface B : A {
  undefined f(SequenceOfLongs x);
};

[Exposed=Window]
interface A {
};

typedef sequence<long> SequenceOfLongs;

次のIDLフラグメントは 定義やインターフェースメンバーへの識別子の付与方法を示しています。

// 型定義の識別子: "number"
typedef double number;

// インターフェースの識別子: "System"
[Exposed=Window]
interface System {

  // 操作の識別子:          "createObject"
  // 操作引数の識別子: "interface"
  object createObject(DOMString _interface);

  // 操作引数の識別子: "interface"
  sequence<object> getObjects(DOMString interface);

  // 操作は識別子なし; getterを宣言
  getter DOMString (DOMString keyName);
};

// インターフェースの識別子: "TextField"
[Exposed=Window]
interface TextField {

  // 属性の識別子: "const"
  attribute boolean _const;

  // 属性の識別子: "value"
  attribute DOMString? _value;
};

なお、TextFieldインターフェース上の2番目の属性は(IDL文法のキーワードではないため)アンダースコアでエスケープする必要はありませんが、 識別子として属性の識別子を得るためにはアンダースコアが除去されます。

2.2. インターフェース

IDLフラグメントはオブジェクト指向システムの記述に用いられます。このようなシステムでは、オブジェクトは同一性を持ち、状態と振る舞いのカプセル化である実体です。 インターフェースは (interface InterfaceRestに一致)、 そのインターフェースを実装するオブジェクトが公開する状態と振る舞いを宣言する定義です。

[extended_attributes]
interface identifier {
  /* interface_members... */
};

インターフェースは インターフェースメンバーInterfaceMembersに一致)として 一連のメンバーを仕様します。これらはインターフェース宣言の中括弧内に現れるメンバーです。

Web IDLのインターフェースは、そのインターフェースを実装するオブジェクトがどのように振る舞うかを記述します。オブジェクト指向言語のバインディングでは、特定のIDLインターフェースを実装するオブジェクトは、その状態の参照・変更、およびインターフェースで記述された振る舞いの呼び出し手段を提供することが期待されます。

インターフェースは他のインターフェースを継承するよう定義できます。 インターフェースの識別子の後に U+003A(:)と識別子が続く場合、 その識別子が継承元インターフェースです。 あるインターフェースが別のインターフェースを継承している場合、そのオブジェクトは継承元インターフェースも実装します。したがって、継承元インターフェースのメンバーも備えます。

interface identifier : identifier_of_inherited_interface {
  /* interface_members... */
};

メンバーの出現順はJavaScriptバインディングのプロパティ列挙に影響します。

インターフェースは、継承元インターフェースと同じ名前のメンバーを指定することもできます。派生インターフェースを実装するオブジェクトは、派生インターフェース上のそのメンバーを公開します。言語バインディングによっては、上書きされたメンバーがオブジェクト上でアクセス可能かどうかは異なります。

次の2つのインターフェースを考えます。

[Exposed=Window]
interface A {
  undefined f();
  undefined g();
};

[Exposed=Window]
interface B : A {
  undefined f();
  undefined g(DOMString x);
};

JavaScriptバインディングでは、Bのインスタンスのプロトタイプチェーンは以下のようになります:

[Object.prototype: the Object prototype object]
     ↑
[A.prototype: interface prototype object for A]
     ↑
[B.prototype: interface prototype object for B]
     ↑
[instanceOfB]

JavaScriptでinstanceOfB.f()を呼び出すと、Bで定義されたfが呼び出されます。ただし、AのfもA.prototype.f.call(instanceOfB)によって呼び出すことが可能です。

あるインターフェースA継承インターフェースは、 Aが直接または間接的に継承するすべてのインターフェースの集合です。Aが他のインターフェースを継承しない場合、その集合は空です。そうでなければ、その集合にはA継承するインターフェースBと、B継承インターフェースすべてが含まれます。

インターフェースの継承階層に循環があってはなりません。つまり、インターフェースAは自分自身を継承できず、 またAを継承するBを継承することもできません(そしてその先も同様)。

リストとしての 包含的継承インターフェースは、インターフェースIについて次のように定義されます:
  1. resultを« »とする。

  2. interfaceIとする。

  3. interfaceがnullでない間:

    1. resultinterfaceを追加する。

    2. interfaceを、もしあればI継承するインターフェースに、なければnullに設定する。

  4. resultを返す。

一般的なインターフェースの多重継承はサポートされません。また、オブジェクトが任意のインターフェース集合を実装することもできません。オブジェクトは単一のインターフェースAを実装すると定義でき、その場合A継承インターフェースすべても実装します。 さらに、includes文を用いることで、 インターフェースAを実装するオブジェクトが、 Aincludeする インターフェースミックスインのメンバーも常に含むものとできます。

各インターフェースメンバーには、拡張属性ExtendedAttributeListに一致)のリストを 前置することができ、言語バインディングでの扱い方を制御します。

[extended_attributes]
interface identifier {

  [extended_attributes]
  const type constant_identifier = 42;

  [extended_attributes]
  attribute type identifier;

  [extended_attributes]
  return_type identifier(/* arguments... */);
};

インターフェースのIDLは、 パーシャルインターフェース 定義(partial interface PartialInterfaceRestに一致)によって複数の部分に分割できます。 パーシャルインターフェース定義の識別子は、 インターフェース定義の識別子と一致しなければなりません。各パーシャルインターフェース上のメンバーはすべて、そのインターフェース自体のメンバーとみなされます。

interface SomeInterface {
  /* interface_members... */
};

partial interface SomeInterface {
  /* interface_members... */
};

注: パーシャルインターフェース定義は、仕様の編集上の補助として意図されており、インターフェース定義を文書の複数箇所や複数文書に分割するために利用されます。

インターフェース定義とそのパーシャルインターフェース定義の出現順は問いません。

注: パーシャルインターフェース定義では他のインターフェースの継承を指定できません。継承は元のインターフェース定義で指定します。

インターフェースが言語の構造にどう対応するかは、該当言語バインディングで定まります。

インターフェースに適用可能な拡張属性は以下の通りです: [CrossOriginIsolated]、 [Exposed]、 [Global]、 [LegacyFactoryFunction]、 [LegacyNoInterfaceObject]、 [LegacyOverrideBuiltIns]、 [LegacyWindowAlias]、 [SecureContext]。

パーシャルインターフェースに適用可能な拡張属性は以下の通りです: [CrossOriginIsolated]、 [Exposed]、 [LegacyOverrideBuiltIns]、 [SecureContext]。

インターフェースは必ず[Exposed] 拡張属性で注釈されていなければなりません。

インターフェース interface修飾名は以下のように定義されます:

  1. identifierinterface識別子とする。

  2. interfaceが[LegacyNamespace] 拡張属性を持つ場合:

    1. namespaceを[LegacyNamespace] 拡張属性の識別子引数とする。

    2. « namespace, identifier »をU+002E(.)区切りで連結したものを返す。

  3. identifierを返す。

CallbackOrInterfaceOrMixin ::
    callback CallbackRestOrInterface
    interface InterfaceOrMixin
InterfaceOrMixin ::
    InterfaceRest
    MixinRest
InterfaceRest ::
    identifier Inheritance { InterfaceMembers } ;
Partial ::
    partial PartialDefinition
PartialDefinition ::
    interface PartialInterfaceOrPartialMixin
    PartialDictionary
    Namespace
PartialInterfaceOrPartialMixin ::
    PartialInterfaceRest
    MixinRest
PartialInterfaceRest ::
    identifier { PartialInterfaceMembers } ;
InterfaceMembers ::
    ExtendedAttributeList InterfaceMember InterfaceMembers
    ε
InterfaceMember ::
    PartialInterfaceMember
    Constructor
PartialInterfaceMembers ::
    ExtendedAttributeList PartialInterfaceMember PartialInterfaceMembers
    ε
PartialInterfaceMember ::
    Const
    Operation
    Stringifier
    StaticMember
    Iterable
    AsyncIterable
    ReadOnlyMember
    ReadWriteAttribute
    ReadWriteMaplike
    ReadWriteSetlike
    InheritAttribute
Inheritance ::
    : identifier
    ε

次のIDLフラグメントは、相互参照する2つのインターフェースの定義例です。 HumanDogはどちらもAnimalを継承します。これらいずれかのインターフェースを実装するオブジェクトはname属性を持ちます。

[Exposed=Window]
interface Animal {
  attribute DOMString name;
};

[Exposed=Window]
interface Human : Animal {
  attribute Dog? pet;
};

[Exposed=Window]
interface Dog : Animal {
  attribute Human? owner;
};

次のIDLフラグメントは、 DOMのインターフェースコールバックインターフェースの簡易版を定義しています。

[Exposed=Window]
interface Node {
  readonly attribute DOMString nodeName;
  readonly attribute Node? parentNode;
  Node appendChild(Node newChild);
  undefined addEventListener(DOMString type, EventListener listener);
};

callback interface EventListener {
  undefined handleEvent(Event event);
};

プレーンなオブジェクトは、EventListenerのようなコールバックインターフェースを実装することができます:

var node = getNode();                                // Nodeのインスタンス取得

var listener = {
  handleEvent: function(event) {
    // ...
  }
};
node.addEventListener("click", listener);            // これは動作する。

node.addEventListener("click", function() { ... });  // これも同様に動作する。

しかし、このようなオブジェクトはNodeのようなインターフェースを実装することはできません:

var node = getNode();  // Nodeのインスタンス取得

var newNode = {
  nodeName: "span",
  parentNode: null,
  appendChild: function(newchild) {
    // ...
  },
  addEventListener: function(type, listener) {
    // ...
  }
};
node.appendChild(newNode);  // これはTypeError例外になる。

2.3. インターフェースミックスイン

インターフェースミックスインは (interface MixinRestに一致する)定義であり、 1つ以上のインターフェースincludeされることができる状態や振る舞いを宣言し、 そのミックスインをincludeしたインターフェースを実装するオブジェクトによって公開されます。

interface mixin identifier {
  /* mixin_members... */
};

注: インターフェースミックスインパーシャルインターフェース同様、 仕様の編集補助として意図されており、機能のまとまりをグループ化し、複数のインターフェース(場合によっては複数文書)にincludeできるようにします。 これらは言語バインディングを介して公開されることを目的としたものではありません。 § 2.3.1 ミックスインとパーシャルの利用で、 パーシャルインターフェースインターフェースミックスインパーシャルインターフェースミックスイン の使い分けについて案内しています。

インターフェースミックスインは、 インターフェースミックスインメンバーMixinMembersに一致)を定義します。 これらは、定数通常の操作通常の属性ストリギファイア であり、ミックスイン宣言の中括弧内に現れます。

これらの定数通常の操作通常の属性ストリギファイアは、 それらをincludeした インターフェース上に定義された場合と同様に、 オブジェクトが持つ振る舞いを記述します。

静的属性静的操作特殊操作イテラブル宣言非同期イテラブル宣言Maplike宣言Setlike宣言 は、インターフェースミックスイン宣言には現れません。

インターフェース同様、インターフェースミックスインのIDLは、 パーシャルインターフェースミックスイン 定義(partial interface MixinRestに一致)によって複数部分に分割できます。 パーシャルインターフェースミックスイン定義の識別子は、 インターフェースミックスイン定義の 識別子と一致しなければなりません。 各パーシャルインターフェースミックスイン定義に現れるメンバーは、インターフェースミックスイン自体のメンバーとみなされ、 さらにそれをincludeするインターフェースのメンバーともみなされます。

interface mixin SomeMixin {
  /* mixin_members... */
};

partial interface mixin SomeMixin {
  /* mixin_members... */
};

メンバーの出現順はJavaScriptバインディングのプロパティ列挙に影響します。

なお、インターフェース辞書とは異なり、 インターフェースミックスインは型を生成しません。

この仕様で定義されている拡張属性のうち、 インターフェースミックスインに適用できるのは [CrossOriginIsolated]、 [Exposed]、 [SecureContext] のみです。

includes文は (IncludesStatementに一致)定義であり、 すべてのインターフェースI (最初の識別子で特定)を実装するオブジェクトが インターフェースミックスインメンバーを 追加で含むことを宣言するために使われます。 インターフェースIインターフェースミックスインMincludeすると言います。

interface_identifier includes mixin_identifier;

最初の識別子インターフェースIを参照しなければなりません。 2番目の識別子はインターフェースミックスインMを参照しなければなりません。

Mの各メンバーは、 Mincludeするすべての インターフェースIJK…の メンバーとみなされ、 まるで各メンバーのコピーが作られたかのように扱われます。 つまり、Mのメンバーmについて、インターフェースImIという メンバーを持ち、 インターフェースJmJを、 インターフェースKmKを持つことになります。 ホストインターフェースは、 mImJmKに対して、それぞれIJKです。

注: JavaScriptでは、メンバーとして宣言された通常の操作は、 それぞれのインターフェースプロトタイプオブジェクトごとに インターフェースMincludeしている場合、 異なる組み込み関数オブジェクトとして データプロパティで公開されます。 属性についても、各アクセサプロパティのgetterやsetterも異なる組み込み関数オブジェクトとなります。

includes文の出現順は、ホストインターフェースがどの順で インターフェースミックスインincludeするかに影響します。

メンバーの順序は明確に規定されていません。 特にインターフェースミックスインが複数文書で定義される場合は未定義です。 issue #432で議論されています。

この仕様で定義される拡張属性のうち、includes文に適用できるものはありません。

次のIDLフラグメントインターフェースEntryと、 インターフェースミックスインObservableを定義しています。 includes文によって、 Entryを実装するオブジェクトは常にObservableメンバーを持つことが指定されています。

interface Entry {
  readonly attribute unsigned short entryType;
  // ...
};

interface mixin Observable {
  undefined addEventListener(DOMString type,
                        EventListener listener,
                        boolean useCapture);
  // ...
};

Entry includes Observable;

JavaScript実装では、すべてのEntryのプロトタイプチェーン上に addEventListenerプロパティが存在します:

var e = getEntry();          // Entryのインスタンス取得
typeof e.addEventListener;   // "function"になる
CallbackOrInterfaceOrMixin ::
    callback CallbackRestOrInterface
    interface InterfaceOrMixin
InterfaceOrMixin ::
    InterfaceRest
    MixinRest
Partial ::
    partial PartialDefinition
PartialDefinition ::
    interface PartialInterfaceOrPartialMixin
    PartialDictionary
    Namespace
MixinRest ::
    mixin identifier { MixinMembers } ;
MixinMembers ::
    ExtendedAttributeList MixinMember MixinMembers
    ε
MixinMember ::
    Const
    RegularOperation
    Stringifier
    OptionalReadOnly AttributeRest
IncludesStatement ::
    identifier includes identifier ;

2.3.1. ミックスインとパーシャルの利用

この節は参考情報です。

インターフェースミックスインは、属性定数操作複数インターフェース間で共有できます。 単一のインターフェースのみ拡張する予定なら、 パーシャルインターフェースの利用を検討してください。

例えば、次のような方法の代わりに:

interface mixin WindowSessionStorage {
  readonly attribute Storage sessionStorage;
};
Window includes WindowSessionStorage;

こうしてください:

partial interface Window {
  readonly attribute Storage sessionStorage;
};

さらに、他の仕様で公開されているインターフェースミックスインを拡張することで、ウィンドウやワーカーなど共通のユースケースに対応した属性・定数・操作のセットをターゲットにできます。

例えば、よくある冗長な方法の代わりに:

interface mixin GlobalCrypto {
  readonly attribute Crypto crypto;
};

Window includes GlobalCrypto;
WorkerGlobalScope includes GlobalCrypto;

WindowOrWorkerGlobalScope インターフェースミックスインパーシャルインターフェースミックスインで拡張できます:

partial interface mixin WindowOrWorkerGlobalScope {
  readonly attribute Crypto crypto;
};

2.4. コールバックインターフェース

コールバックインターフェースは、定義であり、 callback interface identifier { CallbackInterfaceMembers } ;に一致します。 § 2.12 インターフェースを実装するオブジェクトで述べるように、どんなオブジェクトでも実装できます。

注: コールバックインターフェースインターフェースではありません。名前や構文は、以前の規格バージョンでこれらの概念がより共通していた名残です。

コールバックインターフェースコールバックインターフェースメンバーCallbackInterfaceMembersに一致)を仕様します。 これはインターフェース宣言の中括弧内に現れるメンバーです。

callback interface identifier {
  /* interface_members... */
};

注: よく似た名前のコールバック関数定義も参照してください。

コールバックインターフェースは、正確に1つの通常の操作を定義しなければなりません。

仕様策定者は、既存APIの要件記述に必要な場合以外は コールバックインターフェース を定義しないようにしてください。 代わりにコールバック関数を使うべきです。

EventListenerコールバックインターフェースとして定義するのは、 既存APIで特定のプロパティ(この場合handleEvent)を持つオブジェクトがそのインターフェースを実装したものとして扱える必要がある例です。 新しいAPIや互換性の問題がないAPIでは、 コールバック関数を使うことで (JavaScriptバインディングでは)関数オブジェクトのみ許可できます。

コールバックインターフェース定数を宣言する場合は、必ず[Exposed] 拡張属性で注釈しなければなりません。

CallbackRestOrInterface ::
    CallbackRest
    interface identifier { CallbackInterfaceMembers } ;
CallbackInterfaceMembers ::
    ExtendedAttributeList CallbackInterfaceMember CallbackInterfaceMembers
    ε
CallbackInterfaceMember ::
    Const
    RegularOperation

2.5. メンバー

インターフェースインターフェースミックスイン名前空間は、それぞれ メンバー (それぞれInterfaceMembersMixinMembersNamespaceMembersに一致)を仕様します。 これらは中括弧内に現れる定数属性操作やその他の宣言です。 属性は、その インターフェースインターフェースミックスイン名前空間を実装するオブジェクトが公開する状態を記述し、 操作はオブジェクト上で呼び出せる振る舞いを記述します。 定数は、システムのオブジェクト利用者に便宜的に公開される名前付き定数値を宣言します。

あるインターフェースインターフェースミックスインをincludeすると、 ミックスインの各メンバーはそのインターフェースのメンバーとみなされます。 対照的に、継承されたインターフェースメンバーは そのインターフェースのメンバーとはみなされません。

各種インターフェースインターフェースミックスインで定義されるメンバーコンストラクタ手順getter手順setter手順メソッド手順は、 this値(そのメンバーが宣言されるインターフェース型、またはそのメンバーが宣言されるミックスインをincludeするインターフェース型のIDL値)にアクセスできます。

setter手順は、 与えられた値にもアクセスでき、 これは属性が宣言された型のIDL値です。

インターフェースインターフェースミックスインコールバックインターフェース名前空間は それぞれ異なるセットのメンバーをサポートします。 詳細は§ 2.2 インターフェース§ 2.3 インターフェースミックスイン§ 2.4 コールバックインターフェース§ 2.6 名前空間で規定されており、次の参考表にまとめます:

インターフェース コールバックインターフェース インターフェースミックスイン 名前空間
定数
通常の属性 読み取り専用属性のみ
静的属性
通常の操作
ストリギファイア
特殊操作
静的操作
イテラブル宣言
非同期イテラブル宣言
Maplike宣言
Setlike宣言

2.5.1. 定数

定数は、 (Constに一致)名前に定数値を束縛するための宣言です。 定数はインターフェースコールバックインターフェース上に現れます。

定数はこれまで主に、列挙型スタイルの名前付き整数コードの定義に使われてきましたが、Webプラットフォームではこの設計パターンから文字列の利用へと移行しています。 この機能を使用したい編集者は、進める前に issueを提出 して議論することが強く推奨されます。

const type constant_identifier = 42;

定数識別子は、 同じインターフェースメンバーコールバックインターフェースメンバーの識別子と重複してはなりません(同じインターフェース、 またはコールバックインターフェース上)。 また、"length"、"name"、"prototype"であってはなりません。

注: これら3つの名前はJavaScriptバインディングのインターフェースオブジェクト上のプロパティ名です。

定数の型(ConstTypeに一致)は、 プリミティブ型以外であってはなりません。 識別子が使われる場合、それはプリミティブ型の型を持つ型定義を参照しなければなりません。

定数宣言のConstValue部分は定数値を与えます。値は 2つのbooleanリテラルトークン(truefalse)、 integerトークン、 decimalトークン、 もしくは3つの浮動小数点定数値(-InfinityInfinityNaN)のいずれかです。

注: これらの値(文字列と空のシーケンスも含む)は、辞書メンバーのデフォルト値オプション引数のデフォルト値にも使えます。 ただし、文字列、空のシーケンス[]、デフォルト辞書{}は定数値にはできません。

booleanリテラルトークンtruefalseの値はIDLのbooleantruefalseです。

integerトークンの値は、以下の通り決まる整数です:

  1. Sintegerトークンで一致したスカラー値の列とする。

  2. SがU+002D(-)で始まる場合signは−1、そうでなければ1。

  3. 先頭のU+002D(-)後に続くスカラー値によって基数baseを決める:

    U+0030 (0), U+0058 (X)
    U+0030 (0), U+0078 (x)

    基数は16。

    U+0030 (0)

    基数は8。

    その他

    基数は10。

  4. 残りの全てのスカラー値を 基数baseの整数として解釈した結果をnumberとする。

  5. sign × numberを返す。

integerトークンの型は、定数・辞書メンバー・オプション引数の型と同じです。 integerトークンの値は、§ 2.13 型に示される型の有効範囲を外れてはなりません。

decimalトークンの値は、 使われる型(定数・辞書メンバー・オプション引数)に応じてIEEE 754単精度/倍精度浮動小数点数のいずれかです:
  1. Sdecimalトークンで一致したスカラー値の列とする。

  2. SをJavaScriptのNumericLiteralとしてパースした結果をresultとする。

  3. 型がfloatまたはunrestricted floatの場合、 resultに最も近いIEEE 754単精度浮動小数点数が値となる。

  4. それ以外の場合(型がdoubleまたはunrestricted double)、 resultに最も近いIEEE 754倍精度浮動小数点数が値となる。[IEEE-754]

定数値としてInfinity-InfinityNaNを指定した場合も、 型に応じてIEEE 754単精度/倍精度浮動小数点値となります:

unrestricted float、値Infinity

値はIEEE 754単精度正の無限大。

unrestricted double、値Infinity

値はIEEE 754倍精度正の無限大。

unrestricted float、値-Infinity

値はIEEE 754単精度負の無限大。

unrestricted double、値-Infinity

値はIEEE 754倍精度負の無限大。

unrestricted float、値NaN

値はIEEE 754単精度NaN(ビットパターン0x7fc00000)。

unrestricted double、値NaN

値はIEEE 754倍精度NaN(ビットパターン0x7ff8000000000000)。

decimalトークンの型は、使われる定数・辞書メンバー・オプション引数の型と同じです。 decimalトークンの値は型の有効範囲を超えてはならず(§ 2.13 型参照)、 Infinity-InfinityNaNfloatdoubleの値として使えません。

nullトークンの値は、nullというヌラブル型の特別な値です。 nullトークンの型は、使われる定数・辞書メンバー・オプション引数の型と同じです。

定数に割り当てる値の型VTと、定数・辞書メンバー・オプション引数自体の型DTについて、型が互換でなければなりません。 互換とは、DTVTが一致するか、DTVTを内包するヌラブル型であり、その内側の型VTである場合です。

定数は、現れるインターフェースコールバックインターフェースの特定インスタンスとは関連付けられません。インスタンス上で定数が公開されるかは言語バインディング依存です。

ただしJavaScriptバインディングでは、定数はそのIDLインターフェースを実装するオブジェクトを通してアクセスできます。 例えば、次のIDLでは:

[Exposed=Window]
interface A {
  const short rambaldi = 47;
};

JavaScriptでは定数値はA.rambaldiまたはinstanceOfA.rambaldiでアクセスできます。

定数に適用可能な拡張属性は以下の通りです: [CrossOriginIsolated]、 [Exposed]、 [SecureContext]。

Const ::
    const ConstType identifier = ConstValue ;
ConstValue ::
    BooleanLiteral
    FloatLiteral
    integer
BooleanLiteral ::
    true
    false
FloatLiteral ::
    decimal
    -Infinity
    Infinity
    NaN
ConstType ::
    PrimitiveType
    identifier

次のIDLフラグメントは、 上記型の定数の定義例です。

[Exposed=Window]
interface Util {
  const boolean DEBUG = false;
  const octet LF = 10;
  const unsigned long BIT_MASK = 0x0000fc00;
  const double AVOGADRO = 6.022e23;
};

2.5.2. 属性

属性は、 インターフェースメンバーまたは 名前空間メンバーinherit AttributeReststatic OptionalReadOnly AttributeReststringifier OptionalReadOnly AttributeRestOptionalReadOnly AttributeRest、 またはAttributeRestに一致)であり、 指定された型と識別子を持つデータフィールドを宣言するために使われます。その値は取得でき、(場合によっては)変更できます。属性には2種類あります:

  1. 通常の属性:オブジェクトがそのインターフェースを実装する際、指定された識別子のデータフィールドメンバーを持つことを宣言します。

    interface interface_identifier {
      attribute type identifier;
    };
    
  2. 静的属性:インターフェースを実装する特定のオブジェクトとは関連しない属性を宣言するために使われます。

    interface interface_identifier {
      static attribute type identifier;
    };
    

属性にstaticキーワードがなければ 通常の属性を宣言し、ある場合は静的属性となります。 また、インターフェースメンバーだけでなく、 読み取り専用通常の属性名前空間メンバーにもなり得ます。

属性attrgetter手順は、「attr getter手順は次の通り:」という文+リスト、または「attr getter手順は...」という文+インライン説明で記述します。

属性attrsetter手順は、「attr setter手順は次の通り:」という文+リスト、または「attr setter手順は...」という文+インライン説明で記述します。

注: getter手順を定義するときは、暗黙的にthisにアクセスできます。 setter手順の場合は、暗黙的にthis与えられた値にアクセスできます。

属性識別子は、 同じインターフェース上の他のインターフェースメンバーと重複してはなりません。 静的属性の識別子は"prototype"であってはなりません。

属性の型は、attributeキーワードの後に現れる型(Typeに一致)で指定されます。 Type識別子か、識別子+?の場合、 その識別子はインターフェース列挙型コールバック関数コールバックインターフェース型定義を識別しなければなりません。

typedefを解決した後の属性の型は、以下のいずれかの型(ヌラブル/非ヌラブル)であってはなりません:

readonlyキーワードがattributeキーワードの前に現れる場合、その属性は読み取り専用です。 この属性を持つインターフェースを実装するオブジェクトは、その属性への代入を許可しません。代入が単に拒否されるか、無視されるか、例外となるかは言語バインディング依存です。

interface interface_identifier {
  readonly attribute type identifier;
};

型がPromise型の属性は必ず読み取り専用でなければなりません。また、[LegacyLenientSetter]、 [PutForwards]、 [Replaceable]、 [SameObject]の いずれの拡張属性も持てません。

通常の属性読み取り専用でないものは、 祖先インターフェースからgetterを継承するよう宣言できます。これにより、祖先インターフェースで読み取り専用の属性を派生インターフェースで書き込み可能にできます。 属性がinherit付きで宣言されていればgetterを継承します。 getterを継承する元の属性は、継承元インターフェースで同じ識別子の属性です。型は一致していなければなりません。

注: 文法によりinherit読み取り専用属性や静的属性には使えません。

[Exposed=Window]
interface Ancestor {
  readonly attribute TheType theIdentifier;
};

[Exposed=Window]
interface Derived : Ancestor {
  inherit attribute TheType theIdentifier;
};

通常の属性宣言にstringifierキーワードが使われている場合、 そのインターフェースを実装するオブジェクトは属性値でストリング化されることを示します。詳細は§ 2.5.5 ストリギファイア参照。

interface interface_identifier {
  stringifier attribute DOMString identifier;
};

通常・静的属性に適用可能な拡張属性は以下の通りです: [CrossOriginIsolated]、 [Exposed]、 [SameObject]、 [SecureContext]。

通常属性にのみ適用可能な拡張属性は以下の通りです: [LegacyLenientSetter]、 [LegacyLenientThis]、 [PutForwards]、 [Replaceable]、 [LegacyUnforgeable]。

ReadOnlyMember ::
    readonly ReadOnlyMemberRest
ReadOnlyMemberRest ::
    AttributeRest
    MaplikeRest
    SetlikeRest
ReadWriteAttribute ::
    AttributeRest
InheritAttribute ::
    inherit AttributeRest
AttributeRest ::
    attribute TypeWithExtendedAttributes AttributeName ;
AttributeName ::
    AttributeNameKeyword
    identifier
AttributeNameKeyword ::
    required
OptionalReadOnly ::
    readonly
    ε

次のIDLフラグメントは、 インターフェース上で属性を宣言する方法を示しています:

[Exposed=Window]
interface Animal {

  // 任意の文字列値を設定できるシンプルな属性
  readonly attribute DOMString name;

  // 値を代入できる属性
  attribute unsigned short age;
};

[Exposed=Window]
interface Person : Animal {

  // Animalからgetter動作を継承する属性。Personの説明に記載不要。
  inherit attribute DOMString name;
};

2.5.3. 操作

操作は、 インターフェースメンバーコールバックインターフェースメンバー名前空間メンバーstatic RegularOperationstringifierRegularOperationまたは SpecialOperationに一致)であり、 インターフェースを実装するオブジェクト上で呼び出せる振る舞いを定義します。操作には3種類あります:

  1. 通常の操作: インターフェースを実装するオブジェクトが、指定された識別子のメソッドを持つことを宣言します。

    interface interface_identifier {
      return_type identifier(/* arguments... */);
    };
    
  2. 特殊操作: インターフェースを実装するオブジェクト上で、インデックス付きやストリング化などの特殊な振る舞いを宣言します。

    interface interface_identifier {
      /* special_keyword */ return_type identifier(/* arguments... */);
      /* special_keyword */ return_type (/* arguments... */);
    };
    
  3. 静的操作: インターフェースを実装する特定のオブジェクトとは関連しない操作を宣言します。

    interface interface_identifier {
      static return_type identifier(/* arguments... */);
    };
    

操作に識別子があり、staticキーワードがない場合は通常の操作となります。 宣言に特殊キーワードSpecialstringifierキーワード)を使っていれば、特殊操作となります。1つの操作で通常操作と特殊操作両方を宣言できます。 詳細は§ 2.5.6 特殊操作参照。 通常操作はインターフェースメンバーだけでなく、 コールバックインターフェースメンバー名前空間メンバーにもなり得ます。

操作に識別子がない場合、特殊キーワードを用いて特殊操作として宣言しなければなりません。

通常の操作静的操作の識別子は、 同じインターフェースコールバックインターフェース名前空間上の定数属性と重複してはなりません。 静的操作の識別子は"prototype"であってはなりません。

注: 識別子は同じインターフェース内の他の操作と重複しても構いません。 これが操作のオーバーロード指定方法です。

注: 静的操作の識別子は、 同じインターフェース上の通常の操作と重複しても構いません。

操作の戻り値型は、 宣言で識別子の前に現れる型(Typeに一致)で指定されます。 戻り値型が識別子+?の場合、その識別子は インターフェース辞書列挙型コールバック関数コールバックインターフェース型定義 のいずれかを識別しなければなりません。

操作の引数(ArgumentListに一致)は宣言の括弧内で指定します。各引数は型(Typeに一致)+識別子ArgumentNameに一致)で指定します。

注: 表現力のため、操作引数の識別子はArgumentNameKeywordキーワードでも指定でき、その場合エスケープ不要です。

操作引数の型が識別子+?の場合、その識別子は インターフェース列挙型コールバック関数コールバックインターフェース型定義 を識別しなければなりません。 ?がない場合は、これらに加えて辞書も識別可能です。

typedef解決後、引数型がヌラブル型なら、 内側の型辞書型であってはなりません。

interface interface_identifier {
  return_type identifier(type identifier, type identifier /* , ... */);
};

各引数の識別子は、同じ操作宣言内の他の引数の識別子と重複してはなりません。

各引数には、拡張属性ExtendedAttributeListに一致)を前置でき、 引数として渡された値の言語バインディングでの扱い方を制御できます。

interface interface_identifier {
  return_type identifier([extended_attributes] type identifier, [extended_attributes] type identifier /* , ... */);
};

次のIDLフラグメントは、 インターフェース上で通常の操作を宣言する方法を示しています:

[Exposed=Window]
interface Dimensions {
  attribute unsigned long width;
  attribute unsigned long height;
};

[Exposed=Window]
interface Button {

  // 引数なし・booleanを返す操作
  boolean isMouseOver();

  // オーバーロードされた操作
  undefined setDimensions(Dimensions size);
  undefined setDimensions(unsigned long width, unsigned long height);
};

操作やコンストラクター操作は、 最後の引数に...トークンを型の直後に使った場合、可変長とみなされます。 可変長操作は、宣言された最後の引数以降に任意個の追加引数を受け取れます。暗黙の追加仮引数は宣言された最後の引数と同じ型です。呼び出し時は最後の引数を省略しても構いません。...は引数リストの最後の引数でのみ使えます。

interface interface_identifier {
  return_type identifier(type... identifier);
  return_type identifier(type identifier, type... identifier);
};

本仕様で定義される拡張属性のうち、引数リストを取るもの ([LegacyFactoryFunction])や コールバック関数も、 引数リストに...トークンが使われている場合は可変長とみなされます。

次のIDLフラグメントは、2つの可変長操作を持つインターフェースの例です:

[Exposed=Window]
interface IntegerSet {
  readonly attribute unsigned long cardinality;

  undefined union(long... ints);
  undefined intersection(long... ints);
};

JavaScriptバインディングでは、可変長操作は引数を可変個受け付ける関数として実装されます:

var s = getIntegerSet();  // IntegerSetのインスタンス取得

s.union();                // 'ints'に対応する引数なし
s.union(1, 4, 7);         // 'ints'に3引数

可変長関数非対応の言語バインディングでは、明示的な配列やリストを渡す仕様となる場合もあります。

引数がoptionalキーワードで宣言されている場合、その引数はオプション引数です。 可変長操作の最後の引数もオプション引数とみなされます。オプション引数の宣言は、操作呼び出し時にその引数を省略できることを示します。可変長操作では最後の引数を明示的にoptionalと宣言してはなりません。

interface interface_identifier {
  return_type identifier(type identifier, optional type identifier);
};

オプション引数にはデフォルト値も指定できます。引数識別子の後にU+003D(=)と値(DefaultValueに一致)を続けて指定します。 可変長操作の暗黙的オプション引数にはデフォルト値を指定できません。デフォルト値は、操作呼び出し時に該当引数が省略された場合に仮定される値です。

interface interface_identifier {
  return_type identifier(type identifier, optional type identifier = "value");
};

デフォルト値としてtrueをboolean型引数に使うことは強く推奨されません。 著者が暗黙のundefinedデフォルト変換(すなわちfalse)を期待しがちなため、混乱の元となります。 [API-DESIGN-PRINCIPLES]

引数型が辞書型または辞書型メンバーを持つユニオン型で、辞書型や祖先に required メンバーがなく、 引数が最後または以降がオプション引数のみの場合は、その引数をオプション・デフォルト値付きで宣言しなければなりません。

これはAPI設計上、空の辞書値を渡さずデフォルト値だけ使いたい場合に著者が明示的に空辞書を渡す必要がないようにするためです。

多くの場合デフォルト値は{}ですが、辞書型をメンバーに持つユニオン型の場合は他メンバーの初期化値でも構いません。

booleanリテラル(truefalse)、nullトークン、integerトークン、decimalトークン、浮動小数点リテラル(Infinity-InfinityNaN)をデフォルト値に使った場合は、定数の場合と同様に解釈されます。

undefinedトークンをデフォルト値に使った場合、その値はIDLのundefined値となります。

オプション引数のデフォルト値にstringトークンも使え、 そのは以下のように型ごとに決まります:
  1. Sstringトークンで一致したスカラー値(先頭と末尾のU+0022(")を除く)とする。

  2. 引数の型ごとに:

    DOMString
    USVString
    列挙型

    stringトークンの値はS

    ByteString

    Assert: SにU+00FFを超えるコードポイントが含まれていないこと。

    stringトークンの値はS等価エンコード

オプション引数の型が列挙型の場合、 デフォルト値はその列挙型値のいずれかでなければなりません。

オプション引数のデフォルト値として、2トークン値[](空のシーケンス値)も使えます。型はその引数の型(シーケンス型、ヌラブルなシーケンス型、ユニオン型またはヌラブルユニオン型でシーケンス型メンバーを持つ場合)と一致していなければなりません。

オプション引数のデフォルト値として、2トークン値{}(デフォルト初期化辞書値)も使えます。型はその引数の型(辞書型、ユニオン型またはヌラブルユニオン型で辞書型メンバーを持つ場合)と一致していなければなりません。

次のIDLフラグメントは、 2通りの引数数で呼び出せる操作を持つインターフェースの例です:

[Exposed=Window]
interface ColorCreator {
  object createColor(double v1, double v2, double v3, optional double alpha);
};

これは以下のように2つのオーバーロード操作に相当します:

[Exposed=Window]
interface ColorCreator {
  object createColor(double v1, double v2, double v3);
  object createColor(double v1, double v2, double v3, double alpha);
};

次のIDLフラグメントは、 辞書型引数を取る操作を持つインターフェースの例です:

dictionary LookupOptions {
  boolean caseSensitive = false;
};

[Exposed=Window]
interface AddressBook {
  boolean hasAddressForName(USVString name, optional LookupOptions options = {});
};

hasAddressForNameを1引数で呼ぶと、2番目の引数にはデフォルト初期化されたLookupOptions辞書が渡され、caseSensitivefalseとなります。

操作に適用可能な拡張属性は以下の通りです: [CrossOriginIsolated]、 [Default]、 [Exposed]、 [LegacyUnforgeable]、 [NewObject]、 [SecureContext]。

操作operationメソッド手順は、「operation(arg1, arg2, ...)メソッド手順は次の通り:」という文+リスト、または「operation(arg1, arg2, ...)メソッド手順は...」という文+インライン説明で記述します。

注: メソッド手順を定義する際は暗黙的にthisにアクセスできます。

DefaultValue ::
    ConstValue
    string
    [ ]
    { }
    null
    undefined
Operation ::
    RegularOperation
    SpecialOperation
RegularOperation ::
    Type OperationRest
SpecialOperation ::
    Special RegularOperation
Special ::
    getter
    setter
    deleter
OperationRest ::
    OptionalOperationName ( ArgumentList ) ;
OptionalOperationName ::
    OperationName
    ε
OperationName ::
    OperationNameKeyword
    identifier
OperationNameKeyword ::
    includes
ArgumentList ::
    Argument Arguments
    ε
Arguments ::
    , Argument Arguments
    ε
Argument ::
    ExtendedAttributeList ArgumentRest
ArgumentRest ::
    optional TypeWithExtendedAttributes ArgumentName Default
    Type Ellipsis ArgumentName
ArgumentName ::
    ArgumentNameKeyword
    identifier
Ellipsis ::
    ...
    ε
ArgumentNameKeyword ::
    attribute
    callback
    const
    constructor
    deleter
    dictionary
    enum
    getter
    includes
    inherit
    interface
    iterable
    maplike
    mixin
    namespace
    partial
    readonly
    required
    setlike
    setter
    static
    stringifier
    typedef
    unrestricted
2.5.3.1. toJSON

toJSON 通常の操作を宣言することで、 インターフェースは、 それを実装するオブジェクトをJSON型に変換する方法を指定します。

toJSON 通常の操作はこの用途に予約されています。 引数はゼロでなければならず、戻り値はJSON型でなければなりません。

JSON型は次の通りです:

toJSON 通常の操作をオブジェクト上でどう公開するか、 JSON型をどうJSON文字列に変換するかは、言語バインディング依存です。

注: JavaScriptバインディングでは、toJSONメソッドが公開され、 その返すJSON型はJavaScript値となり、JSON.stringify() 関数でJSON文字列に変換できます。 また、JavaScriptバインディングではtoJSON操作に[Default] 拡張属性を付与でき、この場合はデフォルトtoJSON手順が公開されます。

次のIDLフラグメントは、 TransactionインターフェースにtoJSONメソッド(本文で定義)を持つ例です:

[Exposed=Window]
interface Transaction {
  readonly attribute DOMString from;
  readonly attribute DOMString to;
  readonly attribute double amount;
  readonly attribute DOMString description;
  readonly attribute unsigned long number;
  TransactionJSON toJSON();
};

dictionary TransactionJSON {
  Account from;
  Account to;
  double amount;
  DOMString description;
};

TransactionインターフェースのtoJSON 通常の操作は、次のように定義できます:

toJSON()メソッド手順:

  1. jsonを新しいマップとする。

  2. 次の各属性識別子attrについて:「from」「to」「amount」「description」:

    1. valueattrgetter手順this上)を実行した結果とする。

    2. json[attr]にvalueをセットする。

  3. jsonを返す。

JavaScriptバインディングでは、TransactionオブジェクトにtoJSON()メソッドが存在します:

// Transactionのインスタンス取得
var txn = getTransaction();

// 次のようなオブジェクトになる:
// {
//   from: "Bob",
//   to: "Alice",
//   amount: 50,
//   description: "books"
// }
txn.toJSON();

// 次のような文字列になる:
// '{"from":"Bob","to":"Alice","amount":50,"description":"books"}'
JSON.stringify(txn);

2.5.4. コンストラクター操作

あるインターフェースコンストラクター操作メンバー(Constructorに一致)がある場合、 そのインターフェースを実装するオブジェクトを コンストラクターで生成できることを示します。

1つのインターフェースに 複数のコンストラクター操作を定義できます。 各コンストラクター操作ごとに、 指定された引数でインスタンスを生成しようとする手段が提供されます。

インターフェース名interfaceコンストラクター操作コンストラクター手順は、 「new interface(arg1, arg2, ...)コンストラクター手順は次の通り:」という文+リスト、 または「new interface(arg1, arg2, ...)コンストラクター手順は...」という文+インライン説明で記述します。

コンストラクター手順は、何もしない・渡された値で thisを初期化する・例外をスローする、いずれかの動作を行う必要があります。

コンストラクターが thisを初期化しない場合は 「new Example(init)コンストラクター手順は何もしない」と記述できます。

コンストラクター操作の実装方法については § 3.7.1 インターフェースオブジェクトを参照してください。

以下のIDLは2つのインターフェースを定義しています。2番目はコンストラクター操作を持ち、1番目は持ちません。

[Exposed=Window]
interface NodeList {
  Node item(unsigned long index);
  readonly attribute unsigned long length;
};

[Exposed=Window]
interface Circle {
  constructor();
  constructor(double radius);
  attribute double r;
  attribute double cx;
  attribute double cy;
  readonly attribute double circumference;
};

これらのインターフェースをサポートするJavaScript実装では、Circleインターフェースオブジェクトに[[Construct]]内部メソッドが実装され、 インターフェースを実装する新しいオブジェクトを返します。 引数はゼロまたは1個取れます。

NodeListインターフェースオブジェクトが[[Construct]]内部メソッドを持つかは不明ですが、 いずれにせよコンストラクターとして使うとTypeErrorがスローされます。 [whatwg/webidl Issue #698]

var x = new Circle();      // 引数なしコンストラクターでCircleインターフェースを実装する
                           // プラットフォームオブジェクト参照を生成

var y = new Circle(1.25);  // 1引数コンストラクターでCircleオブジェクト生成

var z = new NodeList();    // コンストラクター未宣言なのでTypeErrorになる
Constructor ::
    constructor ( ArgumentList ) ;
ArgumentList ::
    Argument Arguments
    ε
Arguments ::
    , Argument Arguments
    ε
Argument ::
    ExtendedAttributeList ArgumentRest
ArgumentRest ::
    optional TypeWithExtendedAttributes ArgumentName Default
    Type Ellipsis ArgumentName
ArgumentName ::
    ArgumentNameKeyword
    identifier
Ellipsis ::
    ...
    ε
ArgumentNameKeyword ::
    attribute
    callback
    const
    constructor
    deleter
    dictionary
    enum
    getter
    includes
    inherit
    interface
    iterable
    maplike
    mixin
    namespace
    partial
    readonly
    required
    setlike
    setter
    static
    stringifier
    typedef
    unrestricted

2.5.5. ストリギファイア

あるインターフェースストリギファイアがある場合、 そのインターフェースを実装するオブジェクトはデフォルト以外の文字列変換を持つことを意味します。ストリギファイアはstringifierキーワードで指定でき、 単独で使うとストリギファイア操作を生成します。

interface interface_identifier {
  stringifier;
};

インターフェースの付随する本文で、そのインターフェースのストリギファイ挙動を定義しなければなりません。

stringifierキーワードは属性にも付けられます。 この場合、オブジェクトを文字列に変換した際の値はその属性値となります。stringifierキーワードは、 属性がDOMString またはUSVString型でない限り付与できません。 また、静的属性には付与できません。

interface interface_identifier {
  stringifier attribute DOMString identifier;
};

1つのインターフェースにはストリギファイアは最大1つだけ存在できます。

Stringifier ::
    stringifier StringifierRest
StringifierRest ::
    OptionalReadOnly AttributeRest
    ;

次のIDLフラグメントは、 name属性の値でストリング化されるインターフェースを定義しています:

[Exposed=Window]
interface Student {
  constructor();
  attribute unsigned long id;
  stringifier attribute DOMString name;
};

JavaScriptバインディングでは、Studentオブジェクトが文字列を期待する文脈で使われた場合、 オブジェクトのnameプロパティ値が使われます:

var s = new Student();
s.id = 12345678;
s.name = '周杰倫';

var greeting = 'Hello, ' + s + '!';  // greeting == 'Hello, 周杰倫!'

次のIDLフラグメントは、 IDL自体には記載されていないカスタムストリング化挙動を持つインターフェースを定義します。

[Exposed=Window]
interface Student {
  constructor();
  attribute unsigned long id;
  attribute DOMString? familyName;
  attribute DOMString givenName;

  stringifier;
};

したがって、本文でストリギファイ挙動を説明する必要があります。 familyNamegivenName属性がそれぞれ家族名・名前概念に裏付けられていると仮定します。

ストリギファイ挙動手順:

  1. thisのfamily nameがnullなら、 thisのgiven nameを返す。

  2. thisのgiven name+U+0020 SPACE+thisのfamily nameを連結して返す。

このIDLのJavaScript実装は以下のように動作します:

var s = new Student();
s.id = 12345679;
s.familyName = 'Smithee';
s.givenName = 'Alan';

var greeting = 'Hi ' + s;  // greeting == 'Hi Alan Smithee'

2.5.6. 特殊操作

特殊操作は、 その宣言が現れるインターフェースを実装するオブジェクト上で特定の特殊な挙動を宣言するものです。 特殊操作は、操作宣言内で特殊キーワードを使って宣言します。

特殊操作には3種類あります。以下の表は、各特殊操作の種類ごとに宣言に使う特殊キーワードとその目的を示します:

特殊操作 キーワード 目的
ゲッター getter オブジェクトがプロパティ取得でインデックスされた時の挙動を定義
セッター setter オブジェクトがプロパティ代入や作成でインデックスされた時の挙動を定義
デリーター deleter オブジェクトがプロパティ削除でインデックスされた時の挙動を定義

すべての言語バインディングが全ての特殊オブジェクト挙動をサポートするわけではありません。識別子なしで宣言された特殊操作は、その挙動をサポートしない言語バインディングでは単に機能しません。

次のIDLフラグメントはgetterとsetterを持つインターフェースの例です:

[Exposed=Window]
interface Dictionary {
  readonly attribute unsigned long propertyCount;

  getter double (DOMString propertyName);
  setter undefined (DOMString propertyName, double propertyValue);
};

プロパティgetter・setter非対応の言語バインディングでは、Dictionaryを実装するオブジェクトはその特殊挙動を持ちません。

特殊操作に識別子を付けて宣言することは、識別子なしの特殊操作宣言を独立して分離するのと同等です。この方法はインターフェースのメソッド手順の単純化に役立ちます。

次の2つのインターフェースは等価です:

[Exposed=Window]
interface Dictionary {
  readonly attribute unsigned long propertyCount;

  getter double getProperty(DOMString propertyName);
  setter undefined setProperty(DOMString propertyName, double propertyValue);
};
[Exposed=Window]
interface Dictionary {
  readonly attribute unsigned long propertyCount;

  double getProperty(DOMString propertyName);
  undefined setProperty(DOMString propertyName, double propertyValue);

  getter double (DOMString propertyName);
  setter undefined (DOMString propertyName, double propertyValue);
};

1つの操作に同じ特殊キーワードを2回使ってはなりません。

ゲッターとセッターには2種類あり、プロパティ名としてDOMStringを取るものは 名前付きプロパティゲッター名前付きプロパティセッター、 プロパティインデックスとしてunsigned longを取るものは インデックス付きプロパティゲッターインデックス付きプロパティセッターです。 デリーターは1種類のみで、 名前付きプロパティデリーターです。 詳細は§ 2.5.6.1 インデックス付きプロパティ§ 2.5.6.2 名前付きプロパティ参照。

1つのインターフェース上には、 名前付きプロパティデリーターは最大1つ、 ゲッター・セッター各種も最大1つずつしか存在できません。

インターフェースがある種類のセッターを持つ場合は、同じ種類のゲッターも持たなければなりません。名前付きプロパティデリーターを持つ場合は、 名前付きプロパティゲッターも持たなければなりません。

操作で宣言する特殊操作は可変長オプション引数を持ってはなりません。

オブジェクトが、同じ特殊操作を定義する複数のインターフェースを実装する場合、その操作でどちらの特殊操作が呼ばれるかは未定義です。

2.5.6.1. インデックス付きプロパティ

インデックス付きプロパティゲッター を定義する インターフェイス は、インデックス付きプロパティをサポートすると言います。 拡張として、プラットフォームオブジェクト は、インターフェイスを 実装している場合、そのインターフェイスがインデックス付きプロパティをサポートしていれば インデックス付きプロパティをサポートすると言います。

もしインターフェイスがインデックス付きプロパティをサポートする 場合、インターフェイス定義には オブジェクトがどのインデックスでインデックス可能かという説明が伴わなければなりません。 これらのインデックスはサポートされるプロパティインデックスと呼ばれます。

インデックス付きプロパティをサポートするインターフェイスは、 "length" という名前の 整数型 属性を定義しなければなりません。

インデックス付きプロパティゲッターは 一つの unsigned long 引数を取るように宣言されなければなりません。 インデックス付きプロパティセッターは 二つの引数を取り、最初の引数が unsigned long でなければなりません。

interface interface_identifier {
  getter type identifier(unsigned long identifier);
  setter type identifier(unsigned long identifier, type identifier);

  getter type (unsigned long identifier);
  setter type (unsigned long identifier, type identifier);
};

インデックス付きプロパティゲッターとセッターの定義には以下の要件が適用されます:

もしインデックス付きプロパティゲッターセッターオペレーション識別子を使って指定された場合、 オブジェクトをサポートされるプロパティインデックスではない 整数でインデックス付けしても、 そのオペレーションでそのインデックスを渡して呼び出した場合と同じ挙動になるとは限りません。実際の挙動は言語バインディングによって異なります。

JavaScriptの言語バインディングでは、通常のプロパティ検索が行われます。例えば、次のIDLを考えます:

[Exposed=Window]
interface A {
  getter DOMString toWord(unsigned long index);
};

Aを実装するオブジェクトが サポートされるプロパティインデックス として 0 ≤ index < 2 の範囲を持つとします。また toWordは引数を英語の単語に変換して返すとします。 範囲外のインデックスでオペレーションを呼び出した場合の挙動と、オブジェクトを直接インデックス付けした場合の挙動は異なります:

var a = getA();

a.toWord(0);  // "zero" が評価される。
a[0];         // これも "zero" が評価される。

a.toWord(5);  // "five" が評価される。
a[5];         // プロパティ "5" が存在しないため undefined になる。

次のIDLフラグメントOrderedMap インターフェイスを定義しており、 名前やインデックス番号による値の取得・設定を可能にします:

[Exposed=Window]
interface OrderedMap {
  readonly attribute unsigned long size;

  getter any getByIndex(unsigned long index);
  setter undefined setByIndex(unsigned long index, any value);

  getter any get(DOMString name);
  setter undefined set(DOMString name, any value);
};

すべての特殊操作が識別子付きオペレーションで宣言されているため、 必要な追加の説明はキー集合に関するものだけです。 get() オペレーションが、 OrderedMap で存在しないエントリを検索した場合は null を返すと定義されているなら、次の2文で十分です:

OrderedMap を実装するオブジェクト map は、 0 ≤ index < map.size の範囲のインデックスで インデックス付きプロパティをサポートします。

また、get() に渡して非null値が返る名前ごとに 名前付きプロパティもサポートします。

§ 3.9 レガシープラットフォームオブジェクトで説明されている通り、 JavaScriptの実装では レガシープラットフォームオブジェクトOrderedMap を実装する場合、 名前付き・インデックス付き両方のプロパティ集合に対応した プロパティが作成されます。 これらのプロパティを使って、オブジェクトのメソッドを呼び出す場合と同様に オブジェクトとやり取りできます。以下の例を参照ください:

// map は OrderedMap インターフェイスを実装するレガシープラットフォームオブジェクトと仮定する。
var map = getOrderedMap();
var x, y;

x = map[0];       // map.length > 0 の場合、これは次と等価:
                  //
                  //   x = map.getByIndex(0)
                  //
                  // "0" というプロパティが map に作成されているため。
                  // それ以外では "0" プロパティが存在せず undefined になる。

map[1] = false;   // 次と等価:
                  //
                  //   map.setByIndex(1, false)

y = map.apple;    // "apple" という名前付きプロパティが存在する場合、
                  // 次と等価:
                  //
                  //   y = map.get('apple')
                  //
                  // "apple" プロパティが map に作成されているため。
                  // 存在しなければ undefined になる。

map.berry = 123;  // 次と等価:
                  //
                  //   map.set('berry', 123)

delete map.cake;  // "cake" という名前付きプロパティが存在する場合、
                  // その "cake" プロパティが削除され、次と等価な処理が行われる:
                  //
                  //   map.remove("cake")
2.5.6.2. 名前付きプロパティ

名前付きプロパティゲッター を定義する インターフェイス は、名前付きプロパティをサポートすると言います。 拡張として、プラットフォームオブジェクト は、そのオブジェクトが インターフェイス を実装し、そのインターフェイス自体が名前付きプロパティをサポートしている場合、 名前付きプロパティをサポートすると言います。

もしインターフェイスが名前付きプロパティをサポートする 場合、インターフェイス定義には オブジェクトをインデックス付けするために任意の時点で利用できる名前の順序付き集合の説明が伴わなければなりません。 これらの名前は サポートされるプロパティ名 と呼ばれます。

名前付きプロパティゲッターおよびデリーターは 一つの DOMString 引数を取るように宣言されなければなりません。 名前付きプロパティセッターは 二つの引数を取り、最初の引数が DOMString でなければなりません。

interface interface_identifier {
  getter type identifier(DOMString identifier);
  setter type identifier(DOMString identifier, type identifier);
  deleter type identifier(DOMString identifier);

  getter type (DOMString identifier);
  setter type (DOMString identifier, type identifier);
  deleter type (DOMString identifier);
};

名前付きプロパティゲッター・セッター・デリーターの定義には以下の要件が適用されます:

注: インデックス付きプロパティと同様に、 名前付きプロパティゲッターセッター または デリーターオペレーション識別子を使って指定された場合、 オブジェクトを サポートされるプロパティ名ではない 名前でインデックス付けしても、 そのオペレーションでその名前を渡して呼び出した場合と同じ挙動になるとは限りません。 挙動は言語バインディングによって異なります。

2.5.7. 静的属性および操作

静的属性 および 静的操作 とは、 宣言された インターフェイス の特定のインスタンスには関連付けられず、インターフェイス自体に関連付けられるものです。 静的属性および操作は宣言に static キーワードを使用して宣言されます。

静的操作や静的属性をインターフェイスのインスタンス参照を通じて呼び出すことができるかどうかは、言語バインディングごとに異なります。

StaticMember ::
    static StaticMemberRest
StaticMemberRest ::
    OptionalReadOnly AttributeRest
    RegularOperation

次のIDLフラグメントCircle インターフェイスを定義しており、 その上に静的操作が宣言されています:

[Exposed=Window]
interface Point { /* ... */ };

[Exposed=Window]
interface Circle {
  attribute double cx;
  attribute double cy;
  attribute double radius;

  static readonly attribute long triangulationCount;
  static Point triangulate(Circle c1, Circle c2, Circle c3);
};

JavaScript言語バインディングでは、関数オブジェクト triangulate および triangulationCount のアクセサプロパティは インターフェイスオブジェクト Circle 上に存在します:

var circles = getCircles();           // Circle オブジェクトの配列

typeof Circle.triangulate;            // "function" と評価される
typeof Circle.triangulationCount;     // "number" と評価される
Circle.prototype.triangulate;         // undefined となる
Circle.prototype.triangulationCount;  // これも undefined となる
circles[0].triangulate;               // こちらも同様
circles[0].triangulationCount;        // これも同じ

// 静的操作の呼び出し
var triangulationPoint = Circle.triangulate(circles[0], circles[1], circles[2]);

// 何回三角測量を行ったか調べる
window.alert(Circle.triangulationCount);

2.5.8. オーバーロード

インターフェイス上に定義された 通常の操作 または 静的操作 が、同じ種類(通常または静的)の操作として同じ 識別子を持つ別の操作と重複している場合、 その操作は オーバーロードされていると言います。 オーバーロードされた操作の識別子を使って、 インターフェイスを実装するオブジェクト上で操作を呼び出した場合、 渡された引数の数や型によって、どのオーバーロードされた操作が実際に呼び出されるかが決定されます。 コンストラクタ操作も オーバーロード可能です。 オーバーロードされた操作やコンストラクタが取ることができる引数にはいくつか制約があり、 これらの制約を説明するために 有効なオーバーロード集合 という概念が使われます。

オーバーロードされた 操作の集合は、次のいずれかでなければなりません:

操作インターフェイス部分インターフェイスインターフェイスミックスイン部分インターフェイスミックスイン の定義をまたいでオーバーロードしてはなりません。

例えば、fg の両方のオーバーロードは許可されません:

[Exposed=Window]
interface A {
  undefined f();
};

partial interface A {
  undefined f(double x);
  undefined g();
};

partial interface A {
  undefined g(DOMString x);
};

コンストラクタ操作や [LegacyFactoryFunction] 拡張属性部分インターフェイス の定義に現れることは許可されていないため、コンストラクタのオーバーロードを禁止する必要はありません。

有効なオーバーロード集合は、 特定の操作コンストラクタ操作 または [LegacyFactoryFunction]、 コールバック関数 の許容される呼び出しを表します。 有効なオーバーロード集合を計算するアルゴリズムは、 以下の4種類のIDL構成要素のいずれかに対して動作し、必要な入力は以下の通りです。

通常の操作の場合
静的操作の場合
コンストラクタの場合
レガシーファクトリ関数の場合

有効なオーバーロード集合は、インターフェイス上で指定されたオーバーロード操作やコンストラクタに 曖昧さがないかどうかなどを判断するために使われます。

項目有効なオーバーロード集合タプルであり、 (呼び出し可能, 型リスト, オプショナリティリスト) という形式です。それぞれの 項目は以下の通りです:

タプルは、 その操作・コンストラクタ・コールバック関数を、指定された型の引数値リストで呼び出せることを表します。 オプション引数可変長操作・コンストラクタにより、 同じ操作やコンストラクタを識別する 有効なオーバーロード集合に 複数の項目が含まれる場合があります。

以下は 有効なオーバーロード集合を計算する アルゴリズムです。必要に応じて次の入力変数を使います:

拡張属性の引数について言及される場合、それは拡張属性の 名前付き引数リストの引数を指します。

  1. S順序付き集合とする。

  2. F順序付き集合とし、 項目有効なオーバーロード集合の種類ごとに以下とする:

    通常の操作の場合

    Fの要素は、インターフェイスI上に識別子Aで定義された 通常の操作です。

    静的操作の場合

    Fの要素は、インターフェイスI上に識別子Aで定義された 静的操作です。

    コンストラクタの場合

    Fの要素は インターフェイスI上の コンストラクタ操作 です。

    レガシーファクトリ関数の場合

    Fの要素は、インターフェイスI上の [LegacyFactoryFunction] 拡張属性であり、 名前付き引数リストの識別子がAであるものです。

  3. maxargを、F内の操作・レガシーファクトリ関数・コールバック関数が宣言で取る最大の引数数とする。 可変長操作やレガシーファクトリ関数では、 エリプシスが付く引数も1つとして数える。

    注: undefined f(long x, long... y); は2引数とみなされる。

  4. max = max(maxarg, N) とする。

  5. 操作または拡張属性Xについて、F内で:

    1. argumentsを、Xが宣言で取る引数の リストとする。

    2. nを、argumentsサイズ とする。

    3. types型リストとする。

    4. optionalityValuesオプショナリティリストとする。

    5. argument について、arguments内で:

      1. typesargument の型を追加。

      2. optionalityValuesargument が最後の可変長引数なら "variadic"、 optional なら "optional"、 それ以外は "required" を追加。

    6. Sタプル (X, types, optionalityValues) を追加。

    7. もしX可変長として宣言されていれば:

      1. i について 範囲 n から max − 1 まで:

        1. t型リストとする。

        2. oオプショナリティリストとする。

        3. j について 範囲 0 から n − 1 まで:

          1. ttypes[j] を追加。

          2. ooptionalityValues[j] を追加。

        4. j について 範囲 n から i まで:

          1. ttypes[n − 1] を追加。

          2. o に "variadic" を追加。

        5. Sタプル (X, t, o) を追加。

    8. i = n − 1 とする。

    9. i ≥ 0 の間:

      1. もし arguments[i] が optional でなければ ("optional"もしくは最後の可変長引数でなければ)、break

      2. t型リストとする。

      3. oオプショナリティリストとする。

      4. j について 範囲 0 から i − 1 まで:

        1. ttypes[j] を追加。

        2. ooptionalityValues[j] を追加。

      5. Sタプル (X, t, o) を追加。

        注: i が 0 の場合、 S に (X, « », « ») を追加することになる ("« »" は 空リストを表す)。

      6. i = i − 1 とする。

  6. S を返す。

次のインターフェイスについて:

[Exposed=Window]
interface A {
  /* f1 */ undefined f(DOMString a);
  /* f2 */ undefined f(Node a, DOMString b, double... c);
  /* f3 */ undefined f();
  /* f4 */ undefined f(Event a, DOMString b, optional DOMString c, double... d);
};

NodeEventがどちらも実装できるオブジェクトが存在しない2つのインターフェイスであると仮定すると、 識別子f通常の操作の 引数数4に対する有効なオーバーロード集合は次の通りです:

«
  (f1, « DOMString »,                           « required »),
  (f2, « Node, DOMString »,                     « required, required »),
  (f2, « Node, DOMString, double »,             « required, required, variadic »),
  (f2, « Node, DOMString, double, double »,     « required, required, variadic, variadic »),
  (f3, « »,                                     « »),
  (f4, « Event, DOMString »,                    « required, required »),
  (f4, « Event, DOMString, DOMString »,         « required, required, optional »),
  (f4, « Event, DOMString, DOMString, double », « required, required, optional, variadic »)
»

2つの型は、次のアルゴリズムがtrueを返す場合、 識別可能と言います。

  1. 一方の型がnullable型を含み、 もう一方もnullable型を含むか、 ユニオン型であり フラット化されたメンバー型辞書型を含むか、 辞書型なら、 falseを返す。

    次のペアはどれも識別できません:
  2. 両方の型がユニオン型またはnullableユニオン型なら、 一方の各メンバー型が他方の各メンバー型と識別可能であればtrue、そうでなければfalseを返す。

  3. 一方の型がユニオン型またはnullableなユニオン型なら、 そのユニオン型の各 メンバー型 が非ユニオン型と識別可能であればtrue、そうでなければfalseを返す。

  4. 各型のinner type注釈付き型ならそれを取り、 さらにinner typenullable型ならそれを取った2つの「最も内側の型」を考える。 これら2つの型が次の表に現れるかカテゴリに属し、対応する欄に「●」があるか、文字があり追加要件を満たすならtrueを返す。 そうでなければfalseを返す。

    カテゴリ:

    interface-like
    dictionary-like
    sequence-like
    undefined
    boolean
    numeric types
    bigint
    string types
    object
    symbol
    interface-like
    callback function
    dictionary-like
    async sequence
    sequence-like
    undefined
    boolean
    numeric types (b)
    bigint
    string types (d)
    object
    symbol
    interface-like (a)
    callback function (c)
    dictionary-like
    async sequence
    sequence-like
    1. 識別された2つのinterface-like型が同じでなく、どのプラットフォームオブジェクトも両方の型を実装しない場合。

    2. 型は識別可能だが、オーバーロードでの利用には別の制約があり、 これら型のユニオン利用についての助言も参照。

    3. コールバック関数が [LegacyTreatNonObjectAsNull] 拡張属性を持たない場合、辞書型カテゴリの型と識別可能。

      例えば、ECMAScript値から コールバック関数と辞書型を含む ユニオン型に変換する場合、 値がcallableなら コールバック関数に変換し、それ以外は辞書型に変換される。
    4. 型は識別可能だが、ECMAScript値から変換する際、 文字列オブジェクト非同期シーケンスタイプ には変換されない(%Symbol.iterator%メソッドがあっても)。 文字列型が集合やユニオンに含まれる場合も同様。

    doubleDOMString は、numeric型とstring型の交差点に●があるので識別可能です。
    doublelongは、 両方ともnumeric型で、交差点に●や文字がないため識別できません。
    例:
    callback interface CBIface {
        undefined handle();
    };
    
    [Exposed=Window]
    interface Iface {
        attribute DOMString attr2;
    };
    
    dictionary Dict {
        DOMString field1;
    };
    

    CBIfaceIfaceとは識別可能ですが(dictionary-likeとinterface-likeの交差点に●があるため)、 Dictとは識別できません(dictionary-like同士の交差点に●がないため)。

    Promise型は上記の表に現れず、 他の型とは識別できません。

有効なオーバーロード集合型リストサイズが同じ 項目が複数ある場合、 それらの項目について、各ペアの型リストのインデックスiの型が 識別可能である 必要がある。 この最も小さいインデックスを、 識別引数インデックス と呼ぶ。

有効なオーバーロード集合には、 型リストサイズが同じ 項目が 2つ以上含まれてはならず、 そのうち一方の 識別引数インデックス位置に bigint 型の引数があり、 他方にはnumeric型の引数がある場合は不可。

前述の有効なオーバーロード集合では、 型リストサイズ2, 3, 4に複数の項目があります。 これらの型リストサイズに対し、 識別引数インデックスは0です。 NodeEvent識別可能だからです。

次のようなオーバーロードの利用は無効です:

[Exposed=Window]
interface B {
  undefined f(DOMString x);
  undefined f(USVString x);
};

DOMStringUSVString は識別できないためです。

さらに、型リストサイズが同じアイテム群について、 識別引数インデックスより小さい各インデックスjにおいて、 すべての型リストの型は同じであり、 すべてのオプショナリティリストの値も同じでなければなりません。

次は無効です:

[Exposed=Window]
interface B {
  /* f1 */ undefined f(DOMString w);
  /* f2 */ undefined f(long w, double x, Node y, Node z);
  /* f3 */ undefined f(double w, double x, DOMString y, Node z);
};

引数数4の場合の有効なオーバーロード集合

«
  (f1, « DOMString »,                       « required »),
  (f2, « long, double, Node, Node »,        « required, required, required, required »),
  (f3, « double, double, DOMString, Node », « required, required, required, required »)
»

型リストサイズ4のアイテム群を見ると、 識別引数インデックスは2です。 NodeDOMString識別可能だからです。 しかし、これら2つのオーバーロードの0番目の引数が異なるため、オーバーロードは無効です。

2.5.8.1. オーバーロードとユニオン型の違い

この節は参考情報です。

IDLの操作を定義する仕様において、オーバーロードユニオン型オプション引数の組み合わせには、機能的な重なりがあるように見えるかもしれません。

まず重要なのは、オーバーロードユニオン型オプション引数と異なる挙動を持ち、 どちらか一方で完全に定義することはできません(もちろん追加の記述を加えることでWeb IDL型システムの意義が失われる場合を除く)。 例えば、stroke() 操作がCanvasDrawPath インターフェイスに定義されている場合を考えます [HTML]:

interface CanvasDrawPathExcerpt {
  undefined stroke();
  undefined stroke(Path2D path);
};

JavaScript言語バインディングでは、stroke(undefined)CanvasDrawPathExcerptを実装するオブジェクト上で呼び出すと、2番目のオーバーロードが呼ばれ、 undefinedPath2D変換できないため TypeError となります。 しかし、操作がオプション引数で統合されていた場合、

interface CanvasDrawPathExcerptOptional {
  undefined stroke(optional Path2D path);
};

オーバーロード解決アルゴリズムpath引数が未指定とみなし、例外を投げません。

注: この例では、後者の挙動がWeb開発者の期待に沿っています。 CanvasDrawPath が現在設計されるなら、オプション引数stroke()が定義されるでしょう。

さらに、意味論的な違いもあります。ユニオン型は通常「どの型でもほぼ同じように動作する」場合に使われますが、 オーバーロード操作はC++のオーバーロードのような言語機能に適合しやすく、 異なる型の引数で本質的に異なる挙動を持つ操作に向いています。 とはいえ、そうした操作はJavaScript言語では明示的なオーバーロードがないため、混乱を避けるためにも別名の操作にしたほうが良い場合が多いです。 そのため、オーバーロードは新しいAPIにはほとんど適さず、レガシーAPIや特殊な事情で現れることが多いです。

以下に、どのWeb IDL言語機能を使うべきか迷った場合の推奨例を挙げます:

上記のいずれにも当てはまらない場合は、仕様作成者がスタイルを選択できますが、たいていどちらでも十分に意図した挙動を記述できます。 ただし、変換アルゴリズムを含め、ユニオン型オプション引数の方が オーバーロードより 実装・理解が容易であり、JavaScriptのAPIにもより適しています。 したがって特別な事情がなければ、ユニオン型オプション引数、またはその両方がデフォルトの選択肢です。

仕様では、ユニオン型とオーバーロードを混ぜて使うことも自由です。適切かつ便利と思えばそのようにしてください。

2.5.9. イテラブル宣言

インターフェイスは、インターフェイス本体内で イテラブルイテラブル宣言Iterableに合致)を使って宣言できます。

interface interface_identifier {
  iterable<value_type>;
  iterable<key_type, value_type>;
};

イテラブルとして宣言されたインターフェイスを実装するオブジェクトは、値の列として反復処理(イテレーション)できます。

注: JavaScript言語バインディングでは、イテラブルなインターフェイスは entries, forEach, keys, values, %Symbol.iterator% プロパティをインターフェイスプロトタイプオブジェクト上に持ちます。

型パラメータが1つだけ指定されている場合、そのインターフェイスは 値イテレータとなり、指定された型の値を提供します。 型パラメータが2つ指定されている場合、そのインターフェイスは ペアイテレータとなり、 指定された型の値ペアを提供します。

値ペアとは、キー型と値型が与えられた場合、 2つの構造体アイテムを持つ アイテムのことです:

  1. アイテム名前が"key"で、 値ペアキーと呼ばれ、値はキー型のIDL値です。

  2. アイテム名前が"value"で、 値ペアと呼ばれ、値は値型のIDL値です。

値イテレータは、必ず インデックス付きプロパティをサポートする インターフェイスにのみ宣言できます。 この値イテレータの値型は、 インデックス付きプロパティゲッターが返す型と同じでなければなりません。 値イテレータは、 オブジェクトのインデックス付きプロパティをイテレートするものとして暗黙的に定義されます。

ペアイテレータは、 インデックス付きプロパティをサポートする インターフェイスには宣言できません。

ペアイテレータを持つインターフェースに付随する説明文では、 インターフェースの各インスタンスごとに リストとして 値ペアを定義する必要があります。 このリストがイテレートする値ペアです。

JavaScriptで値イテレータ用に生成されるforEachメソッドはArray.prototype.forEachのようにコールバックを呼び、 ペアイテレータ用forEachはMap.prototype.forEachのようにコールバックを呼びます。

値イテレータは現状 インデックス付きプロパティをサポートする インターフェイスだけで許されていますので、ArrayライクなforEachが理にかなっています。 値イテレータが (a) インデックス付きプロパティをサポートしないインターフェイス上に必要な場合や、 (b) Set.prototype.forEachのようにキーと値が同じになるforEachを必要とする場合があります。 そうしたAPIが必要なら issueを提出 してください。

注: これは配列イテレータオブジェクトの仕組みです。 インデックス付きプロパティをサポートするインターフェイスでは、 entries, keys, values, %Symbol.iterator% が返すイテレータオブジェクトは実際に配列イテレータオブジェクトです。

イテラブル宣言を持つ インターフェイスentries, forEach, keys, valuesという名前の 属性定数通常の操作を持ってはならず、 またこれらを持つ継承インターフェイスを持ってもいけません。

次のSessionManagerインターフェイスは、ユーザー名でキーされる複数のSessionオブジェクトにアクセスできます:

[Exposed=Window]
interface SessionManager {
  Session getSessionForUser(DOMString username);

  iterable<DOMString, Session>;
};

[Exposed=Window]
interface Session {
  readonly attribute DOMString username;
  // ...
};

イテレータの挙動は次のように定義できます:

イテレートすべき値ペアは、 値ペアのリストで、 キーがユーザー名、 が そのユーザー名に対応するSessionオブジェクト(開いているもの)で、 ユーザー名でソートされます。

JavaScript言語バインディングでは、SessionManagerインターフェイスプロトタイプオブジェクト にはvaluesメソッド(関数)があり、呼び出すとイテレータオブジェクトを返し、 そのイテレータオブジェクトにはnextメソッドがあり、次の値を返します。 keysentriesメソッドはセッションオブジェクトのユーザー名やユーザー名/Sessionペアをイテレートします。 %Symbol.iterator% もあり、for..ofループでentriesと同じ値を使えます:

// SessionManagerのインスタンスを取得
// "anna"と"brian"の2ユーザーのセッションがあると仮定
var sm = getSessionManager();

typeof SessionManager.prototype.values;            // "function"と評価される
var it = sm.values();                              // values()はイテレータオブジェクトを返す
String(it);                                        // "[object SessionManager Iterator]"と評価される
typeof it.next;                                    // "function"と評価される

// このループは"anna"と"brian"を順に出力
for (;;) {
  let result = it.next();
  if (result.done) {
    break;
  }
  let session = result.value;
  console.log(session.username);
}

// このループも"anna"と"brian"を順に出力
for (let username of sm.keys()) {
  console.log(username);
}

// もう1つの方法
for (let [username, session] of sm) {
  console.log(username);
}

インターフェイスは複数のイテラブル宣言を持ってはなりません。 イテラブル宣言を持つインターフェイスの 継承インターフェイスもイテラブル宣言を持ってはなりません。 イテラブル宣言を持つインターフェイスおよびその継承インターフェイスは、 maplike宣言setlike宣言非同期イテラブル宣言を持ってはなりません。

次の拡張属性はイテラブル宣言に適用できます: [CrossOriginIsolated]、 [Exposed]、 [SecureContext]。

Iterable ::
    iterable < TypeWithExtendedAttributes OptionalType > ;
OptionalType ::
    , TypeWithExtendedAttributes
    ε

2.5.10. 非同期イテラブル宣言

インターフェイスは、インターフェイス本体内で 非同期イテラブル宣言AsyncIterableに合致)を使って非同期イテラブルとして宣言できます。

interface interface_identifier {
  async_iterable<value_type>;
  async_iterable<value_type>(/* arguments... */);
  async_iterable<key_type, value_type>;
  async_iterable<key_type, value_type>(/* arguments... */);
};

インターフェイスを非同期イテラブルとして宣言した場合、 それを実装するオブジェクトは値の列を非同期にイテレートできます。

型パラメータが1つだけの場合、そのインターフェイスは 値非同期イテラブル宣言となり、指定した型の値を非同期で提供します。 型パラメータが2つの場合、そのインターフェイスは ペア非同期イテラブル宣言となり、指定した型の 値ペアを非同期で提供します。

引数が指定されている場合、非同期イテラブル宣言の引数(ArgumentListに合致)はすべて オプション引数でなければなりません。

JavaScript言語バインディングでは、非同期イテラブルなインターフェイスは %Symbol.asyncIterator%valuesプロパティを インターフェイスプロトタイプオブジェクト上に持ちます。 ペア非同期イテラブル宣言の場合はentriesおよびkeysも追加されます。 これらのメソッドは宣言で指定された引数(オプション)を受け取ることができ、 非同期イテレータ初期化手順(あれば)で処理されます。

この要件により、JavaScriptバインディングでfor-await-ofが直接使えるようになります。 for-await-ofは、引数無しで %Symbol.asyncIterator% メソッドを呼び出します。

非同期イテラブル宣言を持つインターフェイスには、 次のイテレーション結果を取得する アルゴリズムを定義する必要があります。 このアルゴリズムは、イテレートされるインターフェイスのインスタンスと、非同期イテレータ自身(状態保存などに利用可能)を受け取ります。 戻り値はPromiseであり、rejectされるか、 イテレーション終了のための特別なイテレーション終了値で解決するか、 以下のいずれかで解決します:

値非同期イテラブル宣言の場合:

宣言で指定した型の値

ペア非同期イテラブル宣言の場合:

宣言で指定した型の値2つからなるタプル

記述には、非同期イテレータreturnアルゴリズムを定義してもよいです。 このアルゴリズムは、イテレートされるインターフェイスのインスタンス・非同期イテレータ自身・any型の値1つを受け取ります。 非同期イテレータの途中終了時に呼ばれ、Promiseを返します。 Fulfillされた場合、値は無視され、Rejectされた場合はAPI利用側に伝播します。

JavaScriptバインディングでは、このアルゴリズムでasync iteratorのreturn()メソッド呼び出し時の挙動をカスタマイズできます。 breakreturnfor-await-ofループから抜ける時などに使われます。

同様のthrow()用フックも追加可能です。現状需要はありませんが、必要なら issueを提出してください。

記述には非同期イテレータ初期化手順も定義できます。 これらは、イテレートされるインターフェイスのインスタンス・新規作成されたイテレータオブジェクト・渡された引数(IDL値のリスト)を受け取ります。

非同期イテラブル宣言を持つインターフェイスは、 entries, keys, valuesという名前の 属性定数通常の操作を持ってはならず、 またこれらを持つ継承インターフェイスも持ってはなりません。

次のSessionManagerインターフェイスは、ユーザー名でキーされる複数のSessionオブジェクトにアクセスできます:

[Exposed=Window]
interface SessionManager {
  Session getSessionForUser(DOMString username);

  async_iterable<DOMString, Session>;
};

[Exposed=Window]
interface Session {
  readonly attribute DOMString username;
  // ...
};

イテレータの挙動は次のように定義できます:

SessionManager非同期イテレータiterator非同期イテレータ初期化手順

  1. iterator現在状態を「まだ開始されていない」に設定。

SessionManagermanagerとその非同期イテレータiterator次のイテレーション結果を取得する

  1. promise を新しい promise とする。

  2. key を次の値(該当すれば)、そうでなければ null とする:

    もし iteratorcurrent state が "not yet started" である場合

    manager の open sessions における、辞書順で最も小さい username

    それ以外の場合

    manager の open sessions における、iterator の current state より大きい username のうち、辞書順で最も小さいもの

    注: iteratorcurrent state は、open sessions に存在しなくなっている場合があります。

  3. key が null なら:

    1. promiseend of iteration で解決する。

  4. それ以外の場合:

    1. sessionkey に対応する Session オブジェクトとする。

    2. promise を (username, session) で解決する。

    3. iteratorcurrent stateusername に設定する。

  5. promise を返す。

JavaScript言語バインディングでは、SessionManagerインターフェイスプロトタイプオブジェクトには valuesメソッド(関数)があり、呼び出すと非同期イテレータオブジェクトを返し、 そのイテレータオブジェクトにはnextメソッドがある。 keysentriesはセッションオブジェクトのユーザー名や(username, Session)ペアをイテレートする。 %Symbol.asyncIterator% もあり、for await..ofループでentriesと同じ値を使える:

// SessionManagerのインスタンスを取得
// "anna"と"brian"の2ユーザーのセッションがあると仮定
var sm = getSessionManager();

typeof SessionManager.prototype.values;            // "function"と評価される
var it = sm.values();                              // values()はイテレータオブジェクトを返す
typeof it.next;                                    // "function"と評価される

// このループは"anna"と"brian"を順に出力
for await (let username of sm.keys()) {
  console.log(username);
}

// もう1つの方法
for await (let [username, session] of sm) {
  console.log(username);
}

インターフェイスは複数の 非同期イテラブル宣言を持ってはなりません。 非同期イテラブル宣言を持つインターフェイス継承インターフェイスも非同期イテラブル宣言を持ってはなりません。 非同期イテラブル宣言を持つインターフェイス及びその継承インターフェイスは、 maplike宣言setlike宣言イテラブル宣言を持ってはなりません。

次の拡張属性は非同期イテラブル宣言に適用できます: [CrossOriginIsolated]、 [Exposed]、 [SecureContext]。

これらの拡張属性は現時点では考慮されていません。 今後考慮される場合は、期待通りの効果となります。

AsyncIterable ::
    async_iterable < TypeWithExtendedAttributes OptionalType > OptionalArgumentList ;
OptionalArgumentList ::
    ( ArgumentList )
    ε

2.5.11. maplike宣言

インターフェイスは、 インターフェイス本体内で maplikemaplike宣言ReadWriteMaplike または readonly MaplikeRest) を使って宣言できます。

interface interface_identifier {
  readonly maplike<key_type, value_type>;
  maplike<key_type, value_type>;
};

maplikeとして宣言されたインターフェイスを実装するオブジェクトは、 最初は空の順序付きマップ(key–valueペア)を表します。 これはそのオブジェクトのマップエントリです。 キーと値の型はmaplike宣言の山括弧内で指定されます。キーは一意でなければなりません。

仕様策定者はマップエントリの内容を変更できます。 この変更はJavaScriptコードからオブジェクトの内容を観測した時にも自動的に反映されます。

maplikeインターフェイスは、言語バインディングに応じてマップエントリの問い合わせAPIをサポートします。 readonlyキーワードが使われていない場合は、マップエントリの変更APIもサポートします。

注: JavaScript言語バインディングでは、 マップエントリ操作APIはJavaScriptの Map オブジェクトに似ています。 readonlyキーワードの場合はentriesforEachgethaskeysvalues%Symbol.iterator% メソッド、およびsizeゲッターが含まれます。 読み書き可能なmaplikeにはさらにcleardeletesetメソッドも含まれます。

maplikeインターフェイスは、属性定数通常の操作で "entries", "forEach", "get", "has", "keys", "size", "values" という名前を持つものを持ってはならず、 またこれらを持つ継承インターフェイスも持てません。

読み書き可能なmaplikeインターフェイスは、 属性定数で "clear", "delete", "set" という名前を持つものを持ってはならず、 またこれらを持つ継承インターフェイスも持てません。

注: 読み書き可能なmaplikeインターフェイスは 通常の操作として "clear", "delete", "set"の名前を持つことができ、 これらはデフォルト実装(§ 3.7.11 maplike宣言で定義)を上書きします。 その場合、入力・出力仕様はデフォルト実装セクションの期待と一致させる必要があります。

インターフェイスは複数の maplike宣言 を持ってはなりません。 maplikeインターフェイスの継承インターフェイスも maplike宣言を持ってはなりません。 maplikeインターフェイスとその継承インターフェイスは、 イテラブル宣言非同期イテラブル宣言setlike宣言インデックス付きプロパティゲッター を持ってはなりません。

ReadOnlyMember ::
    readonly ReadOnlyMemberRest
ReadOnlyMemberRest ::
    AttributeRest
    MaplikeRest
    SetlikeRest
ReadWriteMaplike ::
    MaplikeRest
MaplikeRest ::
    maplike < TypeWithExtendedAttributes , TypeWithExtendedAttributes > ;

この仕様で定義された拡張属性は、 maplike宣言 には適用できません。

例を追加。

2.5.12. setlike宣言

インターフェイスは、 インターフェイス本体内で setlikesetlike宣言ReadWriteSetlike または readonly SetlikeRest) を使って宣言できます。

interface interface_identifier {
  readonly setlike<type>;
  setlike<type>;
};

setlikeとして宣言されたインターフェイスを実装するオブジェクトは、 最初は空の順序付き集合(値のセット)を表します。 これはそのオブジェクトのセットエントリです。 値の型はsetlike宣言の山括弧内で指定されます。値は一意でなければなりません。

仕様策定者はセットエントリの内容を変更できます。 この変更はJavaScriptコードからオブジェクトの内容を観測した時にも自動的に反映されます。

setlikeインターフェイスは、言語バインディングに応じてセットエントリの問い合わせAPIをサポートします。 readonlyキーワードが使われていない場合は、セットエントリの変更APIもサポートします。

注: JavaScript言語バインディングでは、 セットエントリ操作APIはJavaScriptの Set オブジェクトに似ています。 readonlyキーワードの場合はentriesforEachhaskeysvalues%Symbol.iterator% メソッド、およびsizeゲッターが含まれます。 読み書き可能なsetlikeにはさらにaddcleardeleteメソッドも含まれます。

setlikeインターフェイスは、属性定数通常の操作で "entries", "forEach", "has", "keys", "size", "values" という名前を持つものを持ってはならず、 またこれらを持つ継承インターフェイスも持てません。

読み書き可能なsetlikeインターフェイスは、 属性定数で "add", "clear", "delete" という名前を持つものを持ってはならず、 またこれらを持つ継承インターフェイスも持てません。

注: 読み書き可能なsetlikeインターフェイスは 通常の操作として "add", "clear", "delete"の名前を持つことができ、 これらはデフォルト実装(§ 3.7.12 setlike宣言で定義)を上書きします。 その場合、入力・出力仕様はデフォルト実装セクションの期待と一致させる必要があります。

インターフェイスは複数の setlike宣言 を持ってはなりません。 setlikeインターフェイスの継承インターフェイスも setlike宣言を持ってはなりません。 setlikeインターフェイスとその継承インターフェイスは、 イテラブル宣言非同期イテラブル宣言maplike宣言インデックス付きプロパティゲッター を持ってはなりません。

ReadOnlyMember ::
    readonly ReadOnlyMemberRest
ReadOnlyMemberRest ::
    AttributeRest
    MaplikeRest
    SetlikeRest
ReadWriteSetlike ::
    SetlikeRest
SetlikeRest ::
    setlike < TypeWithExtendedAttributes > ;

この仕様で定義された拡張属性は、 setlike宣言 には適用できません。

例を追加。

2.6. 名前空間

名前空間は、グローバルなシングルトンと関連する振る舞いを宣言する定義(Namespaceに合致)です。

namespace identifier {
  /* namespace_members... */
};

名前空間は、名前空間メンバーNamespaceMembersに合致)、 すなわち波括弧内で宣言された通常の操作読み取り専用 通常の属性定数の集合の仕様です。 これらの操作や属性が名前空間にパッケージ化された振る舞いを記述します。

インターフェイスと同様に、名前空間のIDLはpartial namespace定義(partial Namespaceに合致)によって複数に分割できます。 partial namespace定義の識別子は、名前空間定義の識別子と同じでなければなりません。 各partial namespace定義に現れるメンバーは全て、名前空間自身のメンバーとみなされます。

namespace SomeNamespace {
  /* namespace_members... */
};

partial namespace SomeNamespace {
  /* namespace_members... */
};

注: partial interface定義と同様、partial namespace定義は仕様編集上の補助を目的としており、 名前空間の定義を文書の複数のセクションや複数文書に分散できます。

メンバーの出現順は、JavaScriptバインディングにおけるプロパティの列挙で意味を持ちます。

インターフェイスや辞書型とは異なり、名前空間は型を生成しません。

この仕様で定義された拡張属性のうち、 [CrossOriginIsolated]、 [Exposed]、 [SecureContext] 拡張属性のみが名前空間に適用可能です。

名前空間は必ず [Exposed] 拡張属性を注釈しなければなりません。

Partial ::
    partial PartialDefinition
PartialDefinition ::
    interface PartialInterfaceOrPartialMixin
    PartialDictionary
    Namespace
Namespace ::
    namespace identifier { NamespaceMembers } ;
NamespaceMembers ::
    ExtendedAttributeList NamespaceMember NamespaceMembers
    ε
NamespaceMember ::
    RegularOperation
    readonly AttributeRest
    Const

以下のIDLフラグメント名前空間を定義しています。

namespace VectorUtils {
  readonly attribute Vector unit;
  double dotProduct(Vector x, Vector y);
  Vector crossProduct(Vector x, Vector y);
};

JavaScript実装では、グローバルなVectorUtilsデータプロパティが 単純なオブジェクト(プロトタイプは %Object.prototype%) となり、宣言された各操作の列挙可能なデータプロパティと、宣言された各属性の列挙可能なget専用アクセサを持ちます:

Object.getPrototypeOf(VectorUtils);                         // Object.prototype となる。
Object.keys(VectorUtils);                                   // ["dotProduct", "crossProduct"] となる。
Object.getOwnPropertyDescriptor(VectorUtils, "dotProduct"); // { value: <関数>, enumerable: true, configurable: true, writable: true } となる。
Object.getOwnPropertyDescriptor(VectorUtils, "unit");       // { get: <関数>, enumerable: true, configurable: true } となる。

2.7. 辞書型

辞書型は、 Dictionaryに合致する定義であり、 固定された順序付きの順序付きマップデータ型を定義するために使用されます。 このマップのエントリは、 辞書メンバーと呼ばれ、 キーは文字列で、 は定義内で指定された特定の型となります。

dictionary identifier {
  /* dictionary_members... */
};

辞書インスタンスは、その言語固有の表現(例:対応するJavaScriptオブジェクト)への参照を保持しません。 たとえば、操作から辞書を返す場合は、 辞書の現在の値から新しいJavaScriptオブジェクトが作成されます。 また、操作が引数として辞書を受け取る場合は、 渡されたJavaScript値から一度だけ変換が行われ、辞書が作成されます。 辞書の変更は対応するJavaScriptオブジェクトには反映されず、逆も同様です。

辞書型は属性定数の型として使用してはなりません。

辞書型は、他の辞書型から継承するように定義できます。 辞書型の識別子の後にコロンと識別子が続く場合、 その識別子が継承元の辞書型を表します。識別子は必ず辞書型を指す必要があります。

辞書型は、その継承階層に循環があってはなりません。 つまり、辞書型Aが自分自身を継承してはならず、 また他の辞書型BAを継承し、ABを継承するような循環も不可です。

dictionary Base {
  /* dictionary_members... */
};

dictionary Derived : Base {
  /* dictionary_members... */
};

継承辞書型とは、 辞書型Dが直接または間接的に継承する全ての辞書型の集合です。 Dが他の辞書型を継承しなければ空集合です。 そうでなければ、Dが継承するEと、そのE継承辞書型も含みます。

辞書メンバー必須 として指定できます。言語固有値を辞書型に変換する際、そのメンバーの値を必ず指定する必要があります。 必須でない辞書メンバーは オプション です。

辞書メンバー必須と指定しても、 それが観測可能になるのは他の表現(例えば操作の引数としてJavaScript値を渡す場合)をIDL辞書型に変換するときのみです。 仕様策定者は、辞書型が操作の戻り値としてのみ使われる場合などは、メンバーはすべて オプションにするべきです。

辞書型Dの値は、Dおよびその 継承辞書型 に定義された各辞書メンバーに対するエントリを持ちます。 必須メンバーや デフォルト値を持つメンバーには必ず対応する エントリが存在します。 それ以外のメンバーのエントリは辞書値に存在する場合としない場合があります。

JavaScriptバインディングでは、辞書メンバーに対応するプロパティの値がundefinedの場合、 そのプロパティが省略された場合と同じ扱いになります。 そのため、メンバーが必須ならエラーとなり、 デフォルト値があればそれが使われ、 それ以外はそのメンバーのエントリが辞書値に存在しません。

操作引数のデフォルト値と同様に、 boolean辞書メンバーのデフォルト値に trueを使うことは強く非推奨です。これは、undefinedのデフォルト変換として falseを期待する著者を混乱させるためです。 [API-DESIGN-PRINCIPLES]

文字列キーの順序付きマップは、 すべてのエントリが 辞書型D辞書メンバーに対応し、 それらの型が正しく、かつ必須またはデフォルト値付きメンバーに対応する エントリが存在すれば、暗黙的にその辞書型の値とみなされます。

dictionary Descriptor {
  DOMString name;
  sequence<unsigned long> serviceIdentifiers;
};

Descriptor辞書型は次の手順で作成できます:

  1. identifiers = « 1, 3, 7 » とする。

  2. «[ "name" → "test", "serviceIdentifiers" → identifiers ]» を返す。

辞書メンバーDictionaryMemberに合致)は、 型(Typeに合致)と 識別子 (型の後にidentifierトークン)が続きます。 識別子はキー名となります。 型が識別子?が続く場合、識別子は インターフェイス列挙型コールバック関数コールバックインターフェイスtypedefのいずれかを指す必要があります。 ?が付いていない場合は、これらのいずれかまたは 辞書型を指す必要があります。

辞書メンバーの型(typedef展開後)がnullable型の場合、 そのinner type辞書型であってはなりません。

dictionary identifier {
  type identifier;
};

オプションの辞書メンバーの識別子の後に U+003D(=)と値(DefaultValueに合致)が続く場合、 そのメンバーのデフォルト値となり、 著者コードや仕様本文で値が指定されない場合に使われる値です。

dictionary identifier {
  type identifier = "value";
};

デフォルト値としてbooleanリテラル(trueまたはfalse)、 nullトークン、 integerトークン、 decimalトークン、 3つの特殊な浮動小数点リテラル値(Infinity-InfinityNaN)、 stringトークン、 []の2トークン、{}の2トークンが使われた場合、 操作オプション引数デフォルト値と同じ解釈をします。

辞書メンバーの型が列挙型の場合、 デフォルト値(指定されていれば)は列挙型ののいずれかでなければなりません。

辞書メンバーの型の前にrequiredキーワードが付いている場合、 そのメンバーは必須 辞書メンバーとなります。

dictionary identifier {
  required type identifier;
};

辞書メンバーの型は、その辞書型自身を含んではなりません。型が辞書型Dを含むとは、以下のいずれかが真である場合です:

インターフェイスと同様に、辞書型のIDLは partial dictionary 定義(partial Dictionaryに合致)で分割できます。 partial dictionary定義の識別子は 本体の辞書型と同じでなければなりません。各partial dictionary定義のメンバーは全て辞書型自身のメンバーとみなされます。

dictionary SomeDictionary {
  /* dictionary_members... */
};

partial dictionary SomeDictionary {
  /* dictionary_members... */
};

注: partial interface定義と同様、partial dictionary定義は仕様編集上の補助を目的としており、 インターフェイス定義を文書の複数セクションや複数文書に分割できます。

辞書型の辞書メンバーの順序は、 継承辞書型のメンバーが非継承メンバーより前になり、 本体(およびpartial dictionary定義)に現れるメンバーは識別子のUnicodeコードポイント順(辞書順)になります。

例えば、次の定義の場合:

dictionary B : A {
  long b;
  long a;
};

dictionary A {
  long c;
  long g;
};

dictionary C : B {
  long e;
  long f;
};

partial dictionary A {
  long h;
  long d;
};

C型の辞書値の辞書メンバーの順序は c, d, g, h, a, b, e, f となります。

辞書型はメンバーの順序が必要です。なぜなら、言語バインディングによっては辞書値をプラットフォームオブジェクトに渡した時の 辞書メンバー取得順で観測結果が変わる場合があるからです。例えば次のインターフェイスを考えます:

[Exposed=Window]
interface Something {
  undefined f(A a);
};

そしてこのJavaScriptコード:

var something = getSomething();  // Somethingのインスタンス取得
var x = 0;

var dict = { };
Object.defineProperty(dict, "d", { get: function() { return ++x; } });
Object.defineProperty(dict, "c", { get: function() { return ++x; } });

something.f(dict);

辞書メンバー取得順で値が決まります。Aの順序はc→dなので、 cの値が1、dの値が2となります。

辞書メンバーの識別子は、同じ辞書型またはその 継承辞書型に定義された他の辞書メンバーと重複してはなりません。

この仕様では、辞書型に適用可能な拡張属性はありません。

Partial ::
    partial PartialDefinition
PartialDefinition ::
    interface PartialInterfaceOrPartialMixin
    PartialDictionary
    Namespace
Dictionary ::
    dictionary identifier Inheritance { DictionaryMembers } ;
DictionaryMembers ::
    DictionaryMember DictionaryMembers
    ε
DictionaryMember ::
    ExtendedAttributeList DictionaryMemberRest
DictionaryMemberRest ::
    required TypeWithExtendedAttributes identifier ;
    Type identifier Default ;
PartialDictionary ::
    dictionary identifier { DictionaryMembers } ;
Default ::
    = DefaultValue
    ε
DefaultValue ::
    ConstValue
    string
    [ ]
    { }
    null
    undefined
Inheritance ::
    : identifier
    ε

辞書型の一つの用途は、多数のオプション引数を 操作に渡す際、 呼び出し元で指定順序に制約されずに渡すことを可能にすることです。 例えば、以下のIDLフラグメントを考えます:

[Exposed=Window]
interface Point {
  constructor();
  attribute double x;
  attribute double y;
};

dictionary PaintOptions {
  DOMString fillPattern = "black";
  DOMString strokePattern;
  Point position;
};

[Exposed=Window]
interface GraphicsContext {
  undefined drawRectangle(double width, double height, optional PaintOptions options);
};

IDLのJavaScript実装では、オプションPaintOptions辞書型にObjectを渡せます:

// GraphicsContextのインスタンスを取得
var ctx = getGraphicsContext();

// 四角形を描画
ctx.drawRectangle(300, 200, { fillPattern: "red", position: new Point(10, 10) });

PaintOptionsのメンバーはオプションです。 fillPatternが省略された場合、 drawRectangleはデフォルト値を利用でき、明示的な省略時処理を記述する必要はありません。 strokePatternpositionが省略された場合は drawRectangle側で明示的に省略時処理を行う必要があります。

2.8. 例外

例外は、 エラーを表すオブジェクトの一種であり、実装によってthrowされたり第一級値として扱われたりします。 Web IDLには仕様が参照・throwできる多くの事前定義された例外があり、 操作や属性等の定義で使用できます。カスタム例外型も、 インターフェイスとして DOMException継承することで定義可能です。

単純例外は、 以下の型で識別されます:

これらはJavaScriptのエラーオブジェクト (ただし SyntaxError および Error は除く。前者はJSパーサ用、後者は著者用として予約されているため)に対応します。 各単純例外の意味は JavaScript仕様の対応するエラーオブジェクトと一致します。

2番目の例外はDOMExceptionであり、 発生したエラーに関する詳細情報(name)をプログラム的に取得できます。 これらnameは 以下のDOMException名テーブルから選ばれます。

DOMExceptionインターフェイスタイプなので、 IDLで型として使えます。 例えば操作の戻り値型として DOMException を宣言できます。ただし例外はthrowされるべきものであり、戻り値で返すべきではないため、通常は推奨されません。

最後の例外はDOMExceptionの派生インターフェイスです。 これらはより複雑なため、専用の節§ 2.8.2 DOMException派生インターフェイスで説明します。

単純例外は 型名を指定することで生成できます。 DOMExceptionnameDOMException を指定して生成できます。 例外はまたthrowすることもでき、 生成時と同じ情報を指定します。両ケースとも、例外の意味を説明する追加情報を指定可能であり、 これは例外メッセージの構築に有用です。

例外の生成・throwの文言例:

型がTypeError単純例外をthrowする:

TypeError をthrowする。

新しい DOMExceptionname "NotAllowedError" でスローするには:

"NotAllowedError" DOMException をthrowする。

新しい DOMExceptionname "SyntaxError" で作成するには:

object を新たに "SyntaxError" DOMException で 生成する。

新しい DOMExceptionname "OperationError" で promise を reject するには:

p を "OperationError" DOMException で rejectする。

例外メッセージの構築に追加情報を含める例:

"SyntaxError" DOMException をthrowし、 その値が末尾の空白を許容しないことを示す。

こうした追加コンテキストは、なぜ例外がthrowされたかが明確でない場合(アルゴリズム内の多くのステップで "SyntaxError" DOMExceptionがthrowされる等)に実装者にとって特に有用です。 一方、例えばユーザーが機能利用の許可を与えたか検証した直後に "NotAllowedError" DOMExceptionをthrowする場合は、メッセージは自明なので指定不要です。

例外の生成・throwの結果的な挙動は言語バインディングごとに異なります。

§ 3.14.3 例外の生成とthrowも参照ください。 JavaScriptバインディングにおける例外の生成・throwの詳細について記載されています。

2.8.1. 基本 DOMException エラー名

以下のDOMException名テーブルは、 基本のDOMException インターフェイスのインスタンスに許可されるnameの一覧と、 それらの意味、およびレガシーの数値エラーコード値を示します。

DOMException継承するインターフェイス(§ 2.8.2 DOMException 派生インターフェイス参照)は 独自のnameを持ち、本テーブルには掲載されません。

DOMException生成または throwする際は、仕様は必ずこの一覧のnameを使わなければなりません。 適切なnameがない場合は、issueを提出し、 共有名前空間への追加を議論してください。APIで複数のエラー条件をWeb開発者が区別する必要がある場合のみ、 新たなユースケース固有nameの追加が重要です。

DOMException のうち「非推奨」と記載されたnameはレガシー目的で保持されていますが、利用は推奨されません。

注: ここで定義される"SyntaxError" DOMException と、JavaScriptのSyntaxError を混同しないでください。 "SyntaxError" DOMException はWeb APIのパースエラー(例:セレクタのパースなど)を報告するために使用されます。 一方、JavaScriptのSyntaxError はJSパーサ専用です。 誤解を避けるため、SyntaxError DOMException の表記を使い、単にSyntaxError だけでDOMException を指すことは避けてください。 [DOM]

名前 説明 レガシーコード名・値
"IndexSizeError" 非推奨。 RangeError を代わりに使用してください。 INDEX_SIZE_ERR (1)
"HierarchyRequestError" 操作により不正なノードツリーが生成されます。 [DOM] HIERARCHY_REQUEST_ERR (3)
"WrongDocumentError" オブジェクトが誤った文書に属しています。 [DOM] WRONG_DOCUMENT_ERR (4)
"InvalidCharacterError" 文字列に不正な文字が含まれています。 INVALID_CHARACTER_ERR (5)
"NoModificationAllowedError" オブジェクトを変更できません。 NO_MODIFICATION_ALLOWED_ERR (7)
"NotFoundError" オブジェクトがここに見つかりません。 NOT_FOUND_ERR (8)
"NotSupportedError" 操作がサポートされていません。 NOT_SUPPORTED_ERR (9)
"InUseAttributeError" 属性が他の要素で利用中です。 [DOM] INUSE_ATTRIBUTE_ERR (10)
"InvalidStateError" オブジェクトが不正な状態です。 INVALID_STATE_ERR (11)
"SyntaxError" 文字列が期待されたパターンと一致しませんでした。 SYNTAX_ERR (12)
"InvalidModificationError" この方法でオブジェクトを変更できません。 INVALID_MODIFICATION_ERR (13)
"NamespaceError" 操作がXML名前空間によって許可されていません。 [XML-NAMES] NAMESPACE_ERR (14)
"InvalidAccessError" 非推奨。 無効な引数にはTypeError、 サポートされていない操作には"NotSupportedError" DOMException、 拒否された要求には"NotAllowedError" DOMExceptionを使用してください。 INVALID_ACCESS_ERR (15)
"TypeMismatchError" 非推奨。 TypeError を代わりに使用してください。 TYPE_MISMATCH_ERR (17)
"SecurityError" 操作が安全でありません。 SECURITY_ERR (18)
"NetworkError" ネットワークエラーが発生しました。 NETWORK_ERR (19)
"AbortError" 操作が中断されました。 ABORT_ERR (20)
"URLMismatchError" 非推奨。 URL_MISMATCH_ERR (21)
"QuotaExceededError" 非推奨。 QuotaExceededError DOMExceptionの派生インターフェイスを使用してください。 QUOTA_EXCEEDED_ERR (22)
"TimeoutError" 操作がタイムアウトしました。 TIMEOUT_ERR (23)
"InvalidNodeTypeError" 与えられたノードがこの操作に不適切または不適切な祖先を持つ。 [DOM] INVALID_NODE_TYPE_ERR (24)
"DataCloneError" オブジェクトをクローンできません。 DATA_CLONE_ERR (25)
"EncodingError" エンコードまたはデコード操作が失敗しました。
"NotReadableError" I/Oの読み取り操作が失敗しました。
"UnknownError" 一時的な理由(例:メモリ不足等)により操作が失敗しました。
"ConstraintError" トランザクション内のミューテーション操作が制約違反で失敗しました。 [INDEXEDDB]
"DataError" 提供されたデータが不十分です。
"TransactionInactiveError" 現在アクティブでない、もしくは完了したトランザクションに対してリクエストが行われました。 [INDEXEDDB]
"ReadOnlyError" "readonly"トランザクションで変更操作が行われました。 [INDEXEDDB]
"VersionError" 既存バージョンより低いバージョンでデータベースを開こうとしました。 [INDEXEDDB]
"OperationError" 操作固有の理由により失敗しました。
"NotAllowedError" 現在のコンテキストでユーザーエージェントまたはプラットフォームにより要求が許可されていません(ユーザーが権限を拒否した可能性あり)。
"OptOutError" ユーザーがプロセスからオプトアウトしました。

2.8.2. DOMException 派生インターフェイス

例外がDOMExceptionname以上の情報をプログラム的に取得できる必要がある場合、仕様策定者は インターフェイスを定義し、 DOMExceptionを継承できます。 このようなインターフェイスは、開発者に予測可能な形を提供するため、以下の規則に従う必要があります。具体的には:

これらの要件により、これらインターフェイスに継承されたcode プロパティは常に0を返します。

DOMException 派生インターフェイスを生成throwするには、 インターフェイスの識別子と 構築に必要な追加情報を指定します。

QuotaExceededError のインスタンスをthrowするには:

QuotaExceededErrorをthrowし、 quotaに42、 requestedに50を指定する。

2.8.3. 事前定義されたDOMException 派生インターフェイス

現行標準では1つの事前定義済みDOMException 派生インターフェイスを定義しています:

[Exposed=*, Serializable]
interface QuotaExceededError : DOMException {
  constructor(optional DOMString message = "", optional QuotaExceededErrorOptions options = {});

  readonly attribute double? quota;
  readonly attribute double? requested;
};

dictionary QuotaExceededErrorOptions {
  double quota;
  double requested;
};

QuotaExceededError 例外はクォータ超過時にthrowできます。プロパティが2つあり、それぞれ開発者に要求値とクォータ値の比較情報を提供します。

以前の現行標準では"QuotaExceededError"は 基本DOMExceptionエラー名の一つでしたが、 追加情報の対応のため完全なインターフェイスに引き上げられました。

全てのQuotaExceededError インスタンスは、requestedquota(いずれも数値またはnull)を持ち、初期値はnullです。

new QuotaExceededError(message, options) のコンストラクタ手順は以下の通りです:
  1. thisnameを "QuotaExceededError"に設定。

  2. thismessagemessageに設定。

  3. もしoptions["quota"] が存在する場合:

    1. options["quota"] が0未満の場合、RangeErrorをスローする。

    2. thisquotaoptions["quota"]で設定。

  4. もしoptions["requested"] が存在する場合:

    1. options["requested"] が0未満の場合、RangeErrorをスローする。

    2. thisrequestedoptions["requested"]で設定。

  5. thisquota が null でなく、thisrequested が null でなく、 さらに thisrequestedthisquota より小さい場合、 RangeError をスローする。

quotaのgetter手順は thisquotaを返す。

requestedのgetter手順は thisrequestedを返す。

QuotaExceededError インターフェイスはDOMException インターフェイスのcode getterを継承し、常に22を返します。ただしこの値に依存するのは非推奨です(QuotaExceededErrorでもDOMExceptionでも)。 name getterを使う方がよいです。


QuotaExceededError オブジェクトはシリアライズ可能オブジェクトです。

valueserializedを受け取るシリアライズ手順は:
  1. DOMExceptionシリアライズ手順valueserializedで実行。

  2. serialized.[[Quota]]にvaluequotaを設定。

  3. serialized.[[Requested]]にvaluerequestedを設定。

serializedvalueを受け取るデシリアライズ手順は:
  1. DOMExceptionデシリアライズ手順serializedvalueで実行。

  2. valuequotaserialized.[[Quota]]を設定。

  3. valuerequestedserialized.[[Requested]]を設定。


作成またはスローによってQuotaExceededError を生成する仕様は、 requestedおよびquotaの両方がnullでなく、 かつrequestedquotaより小さい場合を提供してはならない。

2.9. 列挙型

列挙型は、 Enumに合致する定義であり、 有効な値が事前定義された文字列集合となる型を宣言します。列挙型は、 DOMString に割り当てられる値や 属性操作の引数として渡される値を制限できます。

enum identifier { "enum", "values" /* , ... */ };

列挙値は、 カンマ区切りのstringリテラルとして指定されます。 列挙値のリストに重複は許されません。

列挙値はすべて小文字で、複数語はハイフン区切りまたは区切りなしとすることが強く推奨されます。 別の命名方式を使う特別な理由がなければこの推奨に従ってください。 例えば「createobject」または「create-object」など。 関連API間で命名方式を統一するよう検討してください。

型が列挙型の場合、属性への代入や操作引数として有効でない文字列値を使った場合の挙動は言語バインディング依存です。

注: JavaScriptバインディングでは、属性への無効な文字列値の代入は無視されますが、 操作引数など他の文脈で渡した場合は例外がthrowされます。

この仕様で定義された拡張属性列挙型には適用できません。

Enum ::
    enum identifier { EnumValueList } ;
EnumValueList ::
    string EnumValueListComma
EnumValueListComma ::
    , EnumValueListString
    ε
EnumValueListString ::
    string EnumValueListComma
    ε

次のIDLフラグメントは、 列挙型を定義し、 属性操作引数の型として用いています:

enum MealType { "rice", "noodles", "other" };

[Exposed=Window]
interface Meal {
  attribute MealType type;
  attribute double size;     // in grams

  undefined initialize(MealType type, double size);
};

JavaScript実装では、typeプロパティやinitializeMeal関数に割り当てられる文字列は、 列挙型で定義されたものに制限されます。

var meal = getMeal();                // Mealのインスタンス取得

meal.initialize("rice", 200);        // 通常通り操作が呼ばれる

try {
  meal.initialize("sandwich", 100);  // TypeErrorがthrowされる
} catch (e) {
}

meal.type = "noodles";               // 属性代入は通常通り
meal.type = "dumplings";             // 属性代入は無視される
meal.type == "noodles";              // trueと評価される

2.10. コールバック関数

「Custom DOM Elements」仕様では、プラットフォームオブジェクト提供関数にコールバック関数型を使いたい意図があります。 「コールバック関数」という呼称を「関数」に変更し、両方の用途に使えることを明確にした方がよいでしょうか?

コールバック関数は、 callback CallbackRestに合致する定義であり、 関数型を宣言するために使います。

callback identifier = return_type (/* arguments... */);

注: 類似名のコールバックインターフェイスも参照ください。

イコール記号の左側の識別子コールバック関数の名前となり、 右側の戻り値型・引数リスト(TypeArgumentListに合致)が コールバック関数型のシグネチャとなります。

コールバック関数定数の型として使うことはできません。

コールバック関数型に適用可能な拡張属性は以下のみです: [LegacyTreatNonObjectAsNull]。

CallbackOrInterfaceOrMixin ::
    callback CallbackRestOrInterface
    interface InterfaceOrMixin
CallbackRest ::
    identifier = Type ( ArgumentList ) ;

次のIDLフラグメントは、 操作完了時にユーザー定義関数を呼び出すAPI用の コールバック関数を定義しています。

callback AsyncOperationCallback = undefined (DOMString status);

[Exposed=Window]
interface AsyncOperations {
  undefined performOperation(AsyncOperationCallback whenFinished);
};

JavaScriptバインディングでは、関数オブジェクトを操作引数として渡します。

var ops = getAsyncOperations();  // AsyncOperationsのインスタンス取得

ops.performOperation(function(status) {
  window.alert("Operation finished, status is " + status + ".");
});

2.11. typedef

typedefは、 Typedefに合致する定義であり、 型に新しい名前を与えるために使われます。この新しい名前は言語バインディングでは公開されず、 純粋にIDL内で型参照の簡略化のために使われます。

typedef type identifier;

新しい名前が与えられる型typedefキーワードの後(TypeWithExtendedAttributesに合致)に指定され、 型の後ろのidentifierトークンが名前を表します。

Typeは、 同じまたは他のtypedefの識別子であってはなりません。

この仕様で定義された拡張属性typedefには適用できません。

Typedef ::
    typedef TypeWithExtendedAttributes identifier ;

次のIDLフラグメントは、 typedefの利用例であり、 長いsequence型の代わりに 短い識別子を使えるようにしています。

[Exposed=Window]
interface Point {
  attribute double x;
  attribute double y;
};

typedef sequence<Point> Points;

[Exposed=Window]
interface Widget {
  boolean pointWithinBounds(Point p);
  boolean allPointsWithinBounds(Points ps);
};

2.12. インターフェイスを実装するオブジェクト

特定のIDLフラグメントセットの実装において、 オブジェクトはプラットフォームオブジェクトと見なされる場合があります。

プラットフォームオブジェクトは、 インターフェイスを実装するオブジェクトです。

レガシープラットフォームオブジェクトは、 プラットフォームオブジェクトであり、 [Global] 拡張属性を持たず、 インデックス付きプロパティ名前付きプロパティ、または両方をサポートするインターフェイスを実装します。

例えばブラウザでは、 DOMオブジェクト(NodeDocumentなどのインターフェイスを実装)が JavaScriptからWebページ内容へアクセスを提供する場合、それらは プラットフォームオブジェクトです。 これらはC++などで実装されたエキゾチックオブジェクトの場合もあれば、ネイティブJavaScriptオブジェクトの場合もあります。 いずれにせよ、IDLフラグメントセットの実装は、 生成された全てのプラットフォームオブジェクトを認識できる必要があります。 実装内部状態でオブジェクトがプラットフォームオブジェクトかどうか記録したり、 内部C++クラス実装かどうかで判定するなど、認識方法は実装依存です。

それ以外のシステム上のオブジェクトはプラットフォームオブジェクト扱いされません。 例えば、WebページがJavaScriptライブラリでDOM Coreを実装する場合、 これはブラウザとは別実装と見なされ、 ライブラリが生成したNodeインターフェイス実装オブジェクトは、 ブラウザ実装におけるNodeプラットフォームオブジェクトとはされません。

コールバックインターフェイスは一方で、 任意のJavaScriptオブジェクトで実装可能です。 これによりWeb APIは著者定義操作を呼び出せます。 例えばDOM Events実装では、 EventListener インターフェイスを実装したオブジェクトをコールバック登録できます。

2.13.

この節では、Web IDLがサポートする型、各型に対応する値やInfra型、そしてその型の定数の表現方法を一覧します。

以下の型は整数型と呼ばれます: byte, octet, short, unsigned short, long, unsigned long, long long および unsigned long longです。

以下の型は数値型です: 整数型全て、 float, unrestricted float, doubleunrestricted doubleです。

プリミティブ型bigint, boolean数値型全てです。

文字列型DOMString, 全ての列挙型, ByteString, USVStringです。

バッファ型ArrayBufferSharedArrayBufferです。

型付き配列型Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, Uint32Array, Uint8ClampedArray, BigInt64Array, BigUint64Array, Float16Array, Float32ArrayFloat64Arrayです。

バッファビュー型DataView および 型付き配列型全てです。

バッファソース型バッファ型バッファビュー型全てです。

object型、 全てのインターフェイス型、 全てのコールバックインターフェイス型オブジェクト型です。

言語バインディング固有型からIDL型への変換は、操作を呼び出す時や 属性に値を代入する時、指定機能の実行前に全て行われます。 変換できない場合、操作は実行されず属性も更新されません。 言語バインディングによっては型変換失敗時に例外がthrowされる場合があり、 その場合例外は操作呼び出し元や属性代入元に伝播されます。

Type ::
    SingleType
    UnionType Null
TypeWithExtendedAttributes ::
    ExtendedAttributeList Type
SingleType ::
    DistinguishableType
    any
    PromiseType
UnionType ::
    ( UnionMemberType or UnionMemberType UnionMemberTypes )
UnionMemberType ::
    ExtendedAttributeList DistinguishableType
    UnionType Null
UnionMemberTypes ::
    or UnionMemberType UnionMemberTypes
    ε
DistinguishableType ::
    PrimitiveType Null
    StringType Null
    identifier Null
    sequence < TypeWithExtendedAttributes > Null
    async_sequence < TypeWithExtendedAttributes > Null
    object Null
    symbol Null
    BufferRelatedType Null
    FrozenArray < TypeWithExtendedAttributes > Null
    ObservableArray < TypeWithExtendedAttributes > Null
    RecordType Null
    undefined Null
ConstType ::
    PrimitiveType
    identifier
PrimitiveType ::
    UnsignedIntegerType
    UnrestrictedFloatType
    boolean
    byte
    octet
    bigint
UnrestrictedFloatType ::
    unrestricted FloatType
    FloatType
FloatType ::
    float
    double
UnsignedIntegerType ::
    unsigned IntegerType
    IntegerType
IntegerType ::
    short
    long OptionalLong
OptionalLong ::
    long
    ε
StringType ::
    ByteString
    DOMString
    USVString
PromiseType ::
    Promise < Type >
RecordType ::
    record < StringType , TypeWithExtendedAttributes >
Null ::
    ?
    ε

2.13.1. any

any型は 他の全ての非ユニオン型の 和集合です。

any型は 判別付きユニオン型に似ていて、その値ごとに 特定の非any型が 紐付いています。例えばany型の値に unsigned longの150や、 longの150があり、 これは異なる値です。

any値の型は 具体型と呼ばれます。 (ユニオン型の値も 具体型を持ちます。)

2.13.2. undefined

undefined型は 一意な値を持ちます。

undefinedの 定数値はIDLでundefinedトークンで表されます。

undefinedは いかなる場合も引数型(操作コールバック関数コンストラクタ操作等)や 辞書メンバー型 (直接でもユニオンでも)として使ってはなりません。 代わりにoptional引数や 非必須 辞書メンバーを使ってください。

注: この値は以前voidと綴られ、使用制限もより厳格でした。

2.13.3. boolean

boolean型は boolean値に対応します。

booleanの 定数値はIDLでtruefalseトークンで表されます。

2.13.4. byte

byte型は 8ビット符号付き整数に対応します。

byteの 定数値はIDLでintegerトークンで表されます。

2.13.5. octet

octet型は 8ビット符号なし整数に対応します。

octetの 定数値はIDLでintegerトークンで表されます。

2.13.6. short

short型は 16ビット符号付き整数に対応します。

shortの 定数値はIDLでintegerトークンで表されます。

2.13.7. unsigned short

unsigned short型は 16ビット符号なし整数に対応します。

unsigned shortの 定数値はIDLでintegerトークンで表されます。

2.13.8. long

long型は 32ビット符号付き整数に対応します。

longの 定数値はIDLでintegerトークンで表されます。

2.13.9. unsigned long

unsigned long型は 32ビット符号なし整数に対応します。

unsigned longの 定数値はIDLでintegerトークンで表されます。

2.13.10. long long

long long型は 64ビット符号付き整数に対応します。

long longの 定数値はIDLでintegerトークンで表されます。

2.13.11. unsigned long long

unsigned long long型は 64ビット符号なし整数に対応します。

unsigned long longの 定数値はIDLでintegerトークンで表されます。

2.13.12. float

float型は 浮動小数点数型で、有限な単精度32ビットIEEE 754浮動小数点数値の集合に対応します。 [IEEE-754]

floatの 定数値はIDLでdecimalトークンで表されます。

特別な理由がなければ32ビット浮動小数点型より double型を 仕様では使うべきです。 double型の値集合の方が JavaScriptのNumber型により近いからです。

2.13.13. unrestricted float

unrestricted float型は 浮動小数点数型で、全ての単精度32ビットIEEE 754浮動小数点数値(有限値、非有限値、NaNなど特殊値含む)の集合に対応します。 [IEEE-754]

unrestricted floatの 定数値はIDLでdecimalトークンで表されます。

2.13.14. double

double型は 浮動小数点数型で、有限な倍精度64ビットIEEE 754浮動小数点数値の集合に対応します。 [IEEE-754]

doubleの 定数値はIDLでdecimalトークンで表されます。

2.13.15. unrestricted double

unrestricted double型は 浮動小数点数型で、全ての倍精度64ビットIEEE 754浮動小数点数値(有限値、非有限値、NaNなど特殊値含む)の集合に対応します。 [IEEE-754]

unrestricted doubleの 定数値はIDLでdecimalトークンで表されます。

2.13.16. bigint

bigint型は 範囲制限のない任意精度整数型です。

bigintの 定数値はIDLでintegerトークンで表されます。

2.13.17. DOMString

DOMString型は 文字列に対応します。

注: nullDOMString型の値ではありません。 nullを許可する場合は nullableDOMString (IDLではDOMString?)を使用してください。

注: DOMString値には マッチしないサロゲート コードポイントが含まれる場合があります。 これを許容しない場合はUSVStringを使ってください。

DOMString型定数値はIDLで表現できませんが、 DOMString辞書メンバー デフォルト値操作のoptional引数 デフォルト値には 文字列リテラルトークンの値を設定できます。

2.13.18. ByteString

ByteString型は バイト列に対応します。

ByteString型定数値はIDLで表現できませんが、 ByteString辞書メンバー デフォルト値操作のoptional引数 デフォルト値には 文字列リテラルトークンの値を設定できます。

ByteString型は HTTPなどバイトと文字列が混在するプロトコルとのインターフェース用途にのみ使うべきです。一般的な文字列は DOMString型で表現するべきで、 たとえ値がASCIIや8ビット文字コードであることが期待されても同様です。 8ビットデータを保持するには sequence型frozen array型(要素型はoctetbyte)、 Uint8ArrayInt8Arrayを使うべきです。 ByteStringは避けてください。

2.13.19. USVString

USVString型は スカラー値文字列に対応します。 文脈によって、これらはコード単位の列や スカラー値の列として扱われます。

USVString型定数値はIDLで表現できませんが、 USVString辞書メンバー デフォルト値操作のoptional引数 デフォルト値には 文字列リテラルトークンの値を設定できます。

USVString型は テキスト処理APIなど、スカラー値列として 文字列処理が必要な場合のみ使うべきです。ほとんどのAPIは DOMString型を使うべきで、 コード単位の解釈をしません。 迷う場合はDOMStringを使ってください。

2.13.20. object

object型は 全ての非nullオブジェクト参照の集合に対応します。

object型定数値はIDLで表現できません。

全てのオブジェクト参照とnullを含む型を表現するには nullable型 object?を使ってください。

2.13.21. symbol

symbol型は 全ての可能なsymbol値の集合に対応します。symbol値は不透明で object値ではありませんが、 識別性(自分自身のみ等価)を持ちます。

symbol型定数値はIDLで表現できません。

2.13.22. インターフェイス型

識別子インターフェイスを指す場合、 その型はそのインターフェイスを実装した全ての非nullオブジェクト参照の集合に対応します。

IDL値はオブジェクト参照のみで表現されます。

特定インターフェイス型のオブジェクト参照定数値はIDLで表現できません。

そのインターフェイスを実装する全てのオブジェクト参照とnullを含む型を表現するには nullable型を使ってください。

2.13.23. コールバックインターフェイス型

識別子コールバックインターフェイスを指す場合、 その型は全ての非nullオブジェクト参照の集合に対応します。

IDL値はオブジェクト参照と コールバックコンテキストのタプルで表現されます。 コールバックコンテキストは 言語バインディング固有値であり、言語バインディング固有オブジェクト参照をIDL値に変換する時点の実行コンテキスト情報を保持します。

注: JavaScriptオブジェクトの場合 コールバックコンテキストは そのObject値がIDLコールバックインターフェイス型値に変換される時点の インカンベント設定オブジェクトへの参照を保持します。 § 3.2.16 コールバックインターフェイス型参照。

特定コールバックインターフェイス型のオブジェクト参照定数値はIDLで表現できません。

全てのオブジェクト参照とnullを含む型を表現するには nullable型を使ってください。

2.13.24. 辞書型

識別子辞書型を指す場合、 その型は辞書定義に準拠する全ての辞書の集合に対応します。

順序付きマップのリテラル構文は、 文脈から特定の辞書型インスタンスとして扱われることが暗黙的に理解できれば辞書の表現にも使えます。 ただし、IDLフラグメント内で定数辞書値を表現する方法はありません。

2.13.25. 列挙型

識別子列挙型を指す場合、 その型はコード単位DOMStringと同様)の シーケンスである文字列のうち、 列挙値として定義されたものの集合に対応します。

DOMString型と同様、 列挙型の定数値はIDLで表現できませんが、 列挙型の辞書メンバー デフォルト値操作のoptional引数 デフォルト値には 文字列リテラルトークンの値を設定できます。

2.13.26. コールバック関数型

識別子コールバック関数を指す場合、 その型は指定されたシグネチャを持つ関数オブジェクトへの参照値の集合に対応します。

注: LegacyTreatNonObjectAsNull 拡張属性が定義に指定される場合、 関数以外のオブジェクト参照値も許容されます。

IDLのコールバック関数型値は、オブジェクト参照と コールバックコンテキストのタプルで表現されます。

注: コールバックインターフェイス型と同様、 コールバックコンテキストは JavaScript Object値がIDLコールバック関数型値に変換される時点の インカンベント設定オブジェクト参照を保持します。 § 3.2.19 コールバック関数型参照。

コールバック関数型の定数値はIDLで表現できません。

2.13.27. nullable型 — T?

nullable型は 既存型(inner type)を基に、 追加でnull値を許容するIDL型です。 nullable型はIDLで型の後ろにU+003F(?)を付けて表します。 inner typeは次に該当してはなりません:

注: 辞書型は通常nullableですが、 操作引数型や辞書メンバー型として使う場合はnullable不可です。

nullable型定数値はIDLで、inner typeの定数値またはnullトークンで表現します。

例えば、値がtruefalsenullを許容する型は boolean?と記述します:

[Exposed=Window]
interface NetworkFetcher {
  undefined get(optional boolean? areWeThereYet = false);
};

次のインターフェイスは 2つの属性を持ちます。 1つはDOMStringまたはnull値、 もう1つはNodeオブジェクト参照またはnull値:

[Exposed=Window]
interface Node {
  readonly attribute DOMString? namespaceURI;
  readonly attribute Node? parentNode;
  // ...
};

2.13.28. sequence型 — sequence<T>

sequence<T>型は 型Tの値からなる(長さ0もあり得る)リスト値の集合を持つパラメータ化型です。

sequence型は必ず値渡しです。 言語バインディングでsequenceが何らかのオブジェクトで表現される場合、 sequenceをプラットフォームオブジェクトに渡しても そのオブジェクトにsequence参照が保持されることはありません。 プラットフォームオブジェクトから返されたsequenceもコピーであり、 変更はプラットフォームオブジェクトに反映されません。

リストのリテラル構文は、 文脈からsequence型インスタンスとして扱われることが暗黙的に理解できればsequenceの表現にも使えます。 ただし、IDLフラグメント内で定数sequence値を表現する方法はありません。

sequence型は属性定数の型として使ってはなりません。

注: この制約は、仕様策定者やAPI利用者が sequence型がコピー渡しされ、 参照渡しされないことを明確にするために存在します。writableなsequence型属性の代わりに、 sequenceの取得・設定操作を対で提供することが推奨されます。

リストは 全ての要素が型Tである限り、暗黙的にsequence<T>型として扱えます。

2.13.29. async_sequence型 — async_sequence<T>

async_sequence型は 型Tの値からなる非同期イテラブル(無限長もあり得る)シーケンスを生成できるオブジェクト参照値の集合を持つパラメータ化型です。

sequence型が 事前に値が全て分かる固定長リストであるのに対し、 async_sequence型の非同期イテラブルシーケンスは遅延生成です。 値や長さはasync_sequence生成時には分からず、 イテレーション時に非同期で値が生成される場合もあります。

async_sequence型は言語バインディングでオブジェクトで表現される場合は参照渡しです。 そのため、async_sequenceをプラットフォームオブジェクトに渡すと そのオブジェクトにasync_sequence参照が保持されます。 プラットフォームオブジェクトから返されたasync_sequenceも同じオブジェクトへの参照であり、 変更はプラットフォームオブジェクトに反映されます(sequence型とは対照的に)。

注: async_sequence型はIDLで構築できません。 操作の戻り値や辞書メンバー型として使われる場合、 async_sequenceはホスト環境から言語バインディングでIDL型に変換されて生成されます。 操作がasync_sequence型を返す代わりに、 インターフェイス非同期イテラブル宣言を持たせることもできます。

async_sequence型は属性定数の型として使ってはなりません。

async_sequence型値はIDLで表現できません。

2.13.30. record型 — record<K, V>

record型は 型パラメータ化されており、値は 順序付きマップであり、 キーK型、 V型のインスタンスです。 KDOMStringUSVStringByteStringのいずれかでなければなりません。

順序付きマップのリテラル構文は 文脈からrecord型として扱われることが暗黙的に理解できればrecordの表現にも使えます。 ただし、IDLフラグメント内で定数record値を表現する方法はありません。

record型は必ず値渡しです。言語バインディングでrecordが何らかのオブジェクトで表現される場合、 recordをプラットフォームオブジェクトに渡しても そのオブジェクトにrecord参照が保持されることはありません。 プラットフォームオブジェクトから返されたrecordもコピーであり、 変更はプラットフォームオブジェクトに反映されません。

record型は属性定数の型として使ってはなりません。

順序付きマップは 全てのエントリのキーがK型、値がV型である限り 暗黙的にrecord<K, V>型として扱えます。

2.13.31. Promise型 — Promise<T>

promise型は 型パラメータ化されており、その値は 「非同期処理の結果のプレースホルダとして使われるオブジェクト参照値」です。 詳細はJavaScript仕様の section 25.4 を参照してください。

Promise型はnullable不可ですが、Tはnullable可です。

Promise値はIDLで表現できません。

2.13.32. ユニオン型

ユニオン型は 複数の型の値集合の合併となる型です。ユニオン型(UnionTypeに合致)は 一連の型をorキーワードで区切り、括弧で囲んで記述します。 ユニオン型を構成する型はユニオンのメンバー型と呼びます。

例えば(Node or DOMString)(double or sequence<double>)と書きます。 ユニオン型全体に?サフィックスを付ける場合は 閉じ括弧の後に置きます(例:(Node or DOMString)?)。

ユニオン型のメンバー型は ネストしたユニオン型には降りません。 例えば(double or (sequence<long> or Event) or (Node or DOMString)?)のメンバー型は double(sequence<long> or Event)(Node or DOMString)?です。

any 型と同様に、 ユニオン型の値には特定の型があり、 それは値に一致するメンバー型である。

flattened member型とは ユニオン型(場合によって注釈付き型含む)の型集合で、次の手順で定まります:

  1. Tユニオン型とする。

  2. S を ∅ に初期化する。

  3. T の各 メンバー型 U について:

    1. もし U注釈付き型であれば、Uその内側の型に設定する。

    2. もし Unullable型であれば、Uその内側の型に設定する。

    3. もし Uユニオン型であれば、U平坦化されたメンバー型S に追加する。

    4. それ以外の場合、Uユニオン型ではない。US に追加する。

  4. S を返す。

注: 例えば (Node or (sequence<long> or Event) or (XMLHttpRequest or DOMString)? or sequence<(sequence<double> or NodeList)>) のflattened member型は Nodesequence<long>EventXMLHttpRequestDOMStringsequence<(sequence<double> or NodeList)>の6型です。

nullableメンバー型数とは ユニオン型Tについて次の手順で決まる整数値です:

  1. Tをユニオン型とする。

  2. nを0で初期化。

  3. ユニオン型Tの各Uについて:

    1. Unullable型なら:

      1. n=n+1。

      2. Uをそのinner typeに置き換える。

    2. Uがユニオン型なら:

      1. mUのnullableメンバー型数とする。

      2. n=n+m

  4. nを返す。

any型はユニオン型のメンバー型として使ってはなりません。

ユニオン型のnullableメンバー型数は0または1でなければならず、1の場合flattened member型に辞書型を含んではなりません。

型がnullable型を含むとは:

ユニオン型のflattened member型の各ペアT, U区別可能でなければなりません。

bigint型と数値型のユニオン型は作成可能ですが、 これは基本的にNumberFormatなど値を計算せず書式化するインターフェイス用です。 ユニオン型で受け取った値をbigintに変換して計算に使うのは精度エラーの危険があるため推奨されません。 この機能の利用意向がある場合は issue を提出してください。

型がundefinedを含むとは:

ユニオン型の定数値はメンバー型の定数値と同じ方法でIDLで表現します。

UnionType ::
    ( UnionMemberType or UnionMemberType UnionMemberTypes )
UnionMemberType ::
    ExtendedAttributeList DistinguishableType
    UnionType Null
UnionMemberTypes ::
    or UnionMemberType UnionMemberTypes
    ε
DistinguishableType ::
    PrimitiveType Null
    StringType Null
    identifier Null
    sequence < TypeWithExtendedAttributes > Null
    async_sequence < TypeWithExtendedAttributes > Null
    object Null
    symbol Null
    BufferRelatedType Null
    FrozenArray < TypeWithExtendedAttributes > Null
    ObservableArray < TypeWithExtendedAttributes > Null
    RecordType Null
    undefined Null

2.13.33. 注釈付き型

既存型に特定の拡張属性を指定することで 追加型を作成できます。これらの型を注釈付き型と呼び、注釈付けされる型を inner typeと呼びます。

[Clamp] longは新たな注釈付き型を定義し、 inner typeである longの挙動を基にしつつ、 [Clamp]拡張属性で修正したものです。

以下の拡張属性は型に適用可能です: [AllowResizable], [AllowShared], [Clamp], [EnforceRange], [LegacyNullToEmptyString]

型に関連付けられる拡張属性 IDL型typeについて、次の手順で決定します:
  1. extended attributesを空の集合で初期化。

  2. typeTypeWithExtendedAttributes 生成式の一部で現れる場合、 そのExtendedAttributeListに記載された 拡張属性をすべて extended attributesに追加します。

    [Exposed=Window]
    interface I {
        attribute [XAttr] long attrib;
        undefined f1(sequence<[XAttr] long> arg);
        undefined f2(optional [XAttr] long arg);
    
        maplike<[XAttr2] DOMString, [XAttr3] long>;
    };
    
    dictionary D {
        required [XAttr] long member;
    };
    
  3. typeユニオン型メンバーとして ユニオン型Uに含まれる場合、 Uに関連付けられる拡張属性を全てextended attributesに追加します。

    [Exposed=Window]
    interface I {
        attribute [XAttr] (long or Node) attrib;
    };
    
  4. typeType生成式内で Argument生成式直下で現れる場合、 そのExtendedAttributeListに記載された 型に適用可能な拡張属性を全てextended attributesに追加します。

    [Exposed=Window]
    interface I {
        undefined f([XAttr] long attrib);
    };
    

    この場合、[XAttr]が型に適用可能な拡張属性ならこの手順の例となります。 そうでない場合は[XAttr]は引数自体への属性となり型には適用されません。

  5. typeType生成式内で DictionaryMember生成式直下で現れる場合、 そのExtendedAttributeListに記載された 型に適用可能な拡張属性を全てextended attributesに追加します。

    dictionary D {
        [XAttr] long member;
    };
    

    この場合、[XAttr]が型に適用可能な拡張属性ならこの手順の例となります。 そうでない場合は[XAttr]は辞書メンバー自体の属性であり型には適用されません。

  6. typetypedefの場合、 新しい名前が与えられる型に関連付けられる拡張属性を追加します。

    typedef [XAttr] long xlong;
    
  7. extended attributesを返します。

いかなる型でも、関連付けられる拡張属性は 型に適用可能な拡張属性のみ含む必要があります。

2.13.34. バッファソース型

バッファ型やそのビュー型となる全ての非nullオブジェクト参照値の集合に対応する型があります。 下表はそれぞれの型と対応するバッファやビューの種類を示します。

バッファの種類
ArrayBuffer 固定バイト数のバッファへのポインタ(nullも可)を保持するオブジェクト
SharedArrayBuffer 固定バイト数の共有バッファへのポインタ(null不可)を保持するオブジェクト
DataView バッファ型インスタンスへのビューであり、任意バイトオフセットの整数・浮動小数点値への型付きアクセスが可能
Int8Array バッファ型インスタンスへのビューであり、2の補数表現の符号付き整数配列としてビットサイズごとに公開
Int16Array
Int32Array
BigInt64Array
Uint8Array バッファ型インスタンスへのビューであり、ビットサイズごとに符号なし整数配列として公開
Uint16Array
Uint32Array
BigUint64Array
Uint8ClampedArray バッファ型インスタンスへのビューであり、8ビット符号なし整数としてクランプ変換付き配列で公開
Float16Array バッファ型インスタンスへのビューであり、指定ビットサイズのIEEE 754浮動小数点配列として公開。Float16ArrayはECMAScript提案 [PROPOSAL-FLOAT16ARRAY]に対応。
Float32Array
Float64Array

注: これらの型はすべてJavaScriptで定義されたクラスに対応します。

これらの型の定数値をIDLで表現する方法はありません。

仕様本文レベルでは、IDLバッファソース型は単なるオブジェクト参照です。 バッファ内部のバイト列を検査・操作するには、仕様本文で § 3.2.26 バッファソース型のアルゴリズムを利用してください。

BufferRelatedType ::
    ArrayBuffer
    SharedArrayBuffer
    DataView
    Int8Array
    Int16Array
    Int32Array
    Uint8Array
    Uint16Array
    Uint32Array
    Uint8ClampedArray
    BigInt64Array
    BigUint64Array
    Float16Array
    Float32Array
    Float64Array

2.13.35. フローズン配列型 — FrozenArray<T>

フローズン配列型は 型パラメータ化されており、値は固定長で変更不可な値の配列を保持するオブジェクト参照値です。配列内の値はT型です。

フローズン配列型は、インターフェイス上で定義される 通常属性または static属性の型としてのみ使うべきです。

次のIDLフラグメントは、 2つのフローズン配列属性(1つは読み取り専用、1つは非読み取り専用)を持つ インターフェイスを定義します。
[Exposed=Window]
interface PersonalPreferences {
    readonly attribute FrozenArray<DOMString> favoriteColors;
    attribute FrozenArray<DOMString> favoriteFoods;

    undefined randomizeFavoriteColors();
};

これらの属性の挙動は以下のように定義できます:

PersonalPreferencesfavorite colorsFrozenArray<DOMString>)を持ち、初期値は« "purple", "aquamarine" »からフローズン配列の生成を行った結果です。

PersonalPreferencesfavorite foodsFrozenArray<DOMString>)を持ち、初期値は空リストからフローズン配列の生成を行った結果です。

favoriteColorsgetter手順thisのfavorite colorsを返す。

favoriteFoodsgetter手順thisのfavorite foodsを返す。

favoriteFoodssetter手順thisのfavorite foodsをthe given valueに設定する。

randomizeFavoriteColors()メソッド手順は:

  1. newFavoriteColorsを、ランダムに選んだ2つの色文字列のリストとする。

  2. thisのfavorite colorsをnewFavoriteColorsからフローズン配列の生成を行った結果で設定する。

FrozenArray<T>値は参照であり、 sequence型が値渡しであるのとは異なります。

フローズン配列値をIDLで定数値として表現する方法はありません。

2.13.36. オブザーバブル配列型 — ObservableArray<T>

オブザーバブル配列型は 型パラメータ化されており、値はT型のオブジェクトからなる可変リストと、著者コードによるリスト内容変更時に実行される挙動を組み合わせたオブジェクト参照値です。

型パラメータT辞書型sequence型record型オブザーバブル配列型のいずれも不可ですが、nullableは可です。

sequence型フローズン配列型と同様、オブザーバブル配列型はJavaScript配列型のラッパーであり、使用時に追加意味論が課されます。

オブザーバブル配列型は、インターフェイス上で定義される 通常属性の型としてのみ使うべきです。

オブザーバブル配列型属性について、仕様策定者は以下のアルゴリズム群を指定できます:

これらのアルゴリズムはどちらも任意であり、提供されていない場合、デフォルトの動作は何もしないことである。いずれのアルゴリズムも、例えば不正な値を拒否するために例外をスローしてもよい。

JavaScript コードが既存のインデックスに新しい値を設定するときは、まず インデックス付き値の削除アルゴリズムが呼び出され既存の値が削除され、 次に新しい値でインデックス付き値の設定アルゴリズムが呼び出される。

型がobservable array 型である通常の属性には、 バッキングリストリスト、初期状態は空)が存在する。 仕様策定者はバッキングリストの内容を修正することができ、その内容は JavaScript コードから観測される observable array の内容にも自動的に反映される。 同様に、JavaScript コードによる observable array の内容の変更は、 インデックス付き値の設定および インデックス付き値の削除アルゴリズムを通過した後、バッキングリストにも反映される。

IDL で定数の observable array 値を表現する方法は存在しない。

次のIDLフラグメントは、 オブザーバブル配列属性を持つインターフェイスを定義します:
[Exposed=Window]
interface Building {
  attribute ObservableArray<Employee> employees;
};

属性の挙動は以下のように定義できます:

Buildingemployees属性について、インデックス値設定アルゴリズムはemployeeindexを受け取り:
  1. employeeが今日建物に入る許可がなければ、"NotAllowedError" DOMExceptionをthrow。

  2. indexが200以上なら、QuotaExceededError(quota=200, requested=index)をthrow。

  3. employeeを勤務開始させる。

Buildingemployees属性について、インデックス値削除アルゴリズムはemployeeindexを受け取り:

  1. employeeが建物から退去したことを警備に通知する。

この属性はJavaScriptコードで様々な操作が可能です:

// Buildingのインスタンス取得
const building = getBuilding();

building.employees.push(new Employee("A"));
building.employees.push(new Employee("B"));
building.employees.push(new Employee("C"));

building.employees.splice(2, 1);
const employeeB = building.employees.pop();

building.employees = [new Employee("D"), employeeB, new Employee("C")];

building.employees.length = 0;

// 例外発生:
building.employees.push("not an Employee; a string instead");

これら全ての操作は、上記で定義したインデックス値設定アルゴリズムを通り、条件次第で例外をthrowします。 また、インデックス値削除アルゴリズムに記載の副作用も実行されます。

また、上記コード例で示すように、Array.prototypeの全メソッドはオブザーバブル配列で動作します。実際、完全に Arrayインスタンスとして振る舞います:

const normalArray = [];

// building.employeesがインデックス付きプロパティgetterインターフェイスの場合:normalArrayにbuilding.employeesのみ
// オブザーバブル配列(およびフローズン配列)では:normalArrayにbuilding.employees内の全アイテム
normalArray.concat(building.employees);

// namesはJS配列
const names = building.employees.map(employee => employee.name);

// ブランドチェックも通る:
console.assert(building.employees instanceof Array);
console.assert(Array.isArray(building.employees));
console.assert(building.employees.constructor === Array);

// JSON.stringifyでも配列扱い(外側の[]に注意)
console.assert(JSON.stringify(building.employees) === `[{}]`);

2.14. 拡張属性

拡張属性は、注釈であり 定義や 型(注釈付き型)、 インターフェイスメンバーインターフェイスミックスインメンバーコールバックインターフェイスメンバー名前空間メンバー辞書メンバー操作引数などに付与でき、 言語バインディングでの扱い方を制御します。 拡張属性はExtendedAttributeListとして指定し、 これは角括弧で囲まれた、カンマ区切りの ExtendedAttributeのリストです。

ExtendedAttribute 文法記号はほぼ任意のトークン列に合致しますが、 本書で定義される拡張属性は より制限された構文のみ許容します。 IDLフラグメント中で見つかった拡張属性は、以下の文法記号と照合されて どの形式か判定されます:

文法記号 形式
ExtendedAttributeNoArgs 引数なし [Replaceable]
ExtendedAttributeArgList 引数リストあり 現行標準では未使用。過去には[Constructor(double x, double y)]で使用。
ExtendedAttributeNamedArgList 名前付き引数リストあり [LegacyFactoryFunction=Image(DOMString src)]
ExtendedAttributeIdent 識別子あり [PutForwards=name]
ExtendedAttributeString 文字列あり [Reflect="popover"]
ExtendedAttributeInteger 整数あり [ReflectDefault=2]
ExtendedAttributeDecimal 小数あり [ReflectDefault=2.0]
ExtendedAttributeIntegerList 整数リストあり [ReflectRange=(2, 600)]
ExtendedAttributeIdentList 識別子リストあり [Exposed=(Window,Worker)]
ExtendedAttributeWildcard ワイルドカードあり [Exposed=*]

本現行標準ではJavaScript言語バインディングに適用可能な拡張属性がいくつか定義されており、 § 3.3 拡張属性で説明されています。 各拡張属性定義では上記のどの形式が許容されるか明示されます。

ExtendedAttributeList ::
    [ ExtendedAttribute ExtendedAttributes ]
    ε
ExtendedAttributes ::
    , ExtendedAttribute ExtendedAttributes
    ε
ExtendedAttribute ::
    ( ExtendedAttributeInner ) ExtendedAttributeRest
    [ ExtendedAttributeInner ] ExtendedAttributeRest
    { ExtendedAttributeInner } ExtendedAttributeRest
    Other ExtendedAttributeRest
ExtendedAttributeRest ::
    ExtendedAttribute
    ε
ExtendedAttributeInner ::
    ( ExtendedAttributeInner ) ExtendedAttributeInner
    [ ExtendedAttributeInner ] ExtendedAttributeInner
    { ExtendedAttributeInner } ExtendedAttributeInner
    OtherOrComma ExtendedAttributeInner
    ε
Other ::
    integer
    decimal
    identifier
    string
    other
    -
    -Infinity
    .
    ...
    :
    ;
    <
    =
    >
    ?
    *
    ByteString
    DOMString
    FrozenArray
    Infinity
    NaN
    ObservableArray
    Promise
    USVString
    any
    bigint
    boolean
    byte
    double
    false
    float
    long
    null
    object
    octet
    or
    optional
    record
    sequence
    short
    symbol
    true
    unsigned
    undefined
    ArgumentNameKeyword
    BufferRelatedType
OtherOrComma ::
    Other
    ,
IdentifierList ::
    identifier Identifiers
Identifiers ::
    , identifier Identifiers
    ε
IntegerList ::
    integer Integers
Integers ::
    , integer Integers
    ε
ExtendedAttributeNoArgs ::
    identifier
ExtendedAttributeArgList ::
    identifier ( ArgumentList )
ExtendedAttributeIdent ::
    identifier = identifier
ExtendedAttributeString ::
    identifier = string
ExtendedAttributeInteger ::
    identifier = integer
ExtendedAttributeDecimal ::
    identifier = decimal
ExtendedAttributeWildcard ::
    identifier = *
ExtendedAttributeIdentList ::
    identifier = ( IdentifierList )
ExtendedAttributeIntegerList ::
    identifier = ( IntegerList )
ExtendedAttributeNamedArgList ::
    identifier = identifier ( ArgumentList )

3. JavaScriptバインディング

この節では、§ 2 インターフェイス定義言語で定義されたIDLによる定義が ECMAScript Language Specification [ECMA-262] に定義されるJavaScriptの構成要素とどのように対応するかを説明します。

特に指定がない限り、この節で定義されるオブジェクトは ECMAScript § 10.1 Ordinary Object Internal Methods and Internal Slotsで説明される通常オブジェクトです。 オブジェクトが関数オブジェクトの場合は、 ECMAScript § 10.3 Built-in Function Objectsに従います。

この節ではオブジェクトの一部内部メソッドや内部スロットを再定義する場合があります。 他の仕様でも、プラットフォームオブジェクトインターフェイスのインスタンス)について、 いかなる内部メソッドや内部スロットの定義も上書き可能です。 これらの意味論が変更されたオブジェクトは、エキゾチックオブジェクトの規則に従って扱われます。

JavaScriptオブジェクトの内部メソッドをオーバーライドすることは低レベルな操作であり、 通常オブジェクトと異なる挙動となる場合があるため、 セキュリティや互換性のために必要な場合以外は利用すべきではありません。 現状では HTMLAllCollectionLocation インターフェイスの定義に使われています。[HTML]

特に指定がない限り、この節や他の仕様で定義されるエキゾチックオブジェクトは、 通常オブジェクトと同じ内部スロットを持ち、 代替定義がない内部メソッドは 通常オブジェクトと同じです。

特に指定がない限り、この節で定義されるオブジェクトの[[Extensible]]内部スロット値はtrueです。

特に指定がない限り、この節で定義されるオブジェクトの[[Prototype]]内部スロットは %Object.prototype%です。

このセクションで説明される一部のオブジェクトには、クラス文字列が定義されている。 クラス文字列は、Object.prototype.toStringが返す文字列に含めるための文字列である。

オブジェクトがクラス文字列classStringを持つ場合、そのオブジェクトは作成時に、 名前が%Symbol.toStringTag% であるプロパティを持たなければならない。 PropertyDescriptor{[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true, [[Value]]: classString} である。

この節のアルゴリズムはECMAScript § 5.2 アルゴリズム規約で説明される手順やサブ手順、数学演算などの記法慣例を用います。 また、他のECMA-262部分で定義された抽象演算や記法も参照する場合があります。

アルゴリズムで throw SomethingError と記述されている場合、 現在のrealmで JavaScriptのSomethingErrorオブジェクトを新たに構築し、 ECMA-262のアルゴリズムと同様にthrowすることを意味します。

アルゴリズムの手順は他のアルゴリズムや抽象演算を呼び出し、そこからthrowされる例外を明示的に処理しない場合があります。 例外がアルゴリズムや抽象演算からthrowされ、呼び出し元で明示的に処理されない場合、 そのアルゴリズムは終了し、例外は呼び出し元へ伝播し続けます。

次のアルゴリズムを考えます:

  1. xをこのアルゴリズムに渡されたJavaScript値とする。

  2. y? ToString(x)の呼び出し結果とする。

  3. yを返す。

ToStringは例外をthrowし得ます(例えば({ toString: function() { throw 1 } })を渡した場合)ので、 上記アルゴリズム中で例外が処理されない場合、例外が発生するとこのアルゴリズムは終了し、 呼び出し元があればそこへ例外が伝播します。

3.1. JavaScript環境

特定のIDLフラグメントセットを JavaScriptで実装する場合、そのIDLフラグメント 定義に対応するJavaScriptオブジェクト群が存在します。 これらのオブジェクトを初期オブジェクトと呼び、以下を含みます:

realmは、 それぞれ固有の初期オブジェクト群を持たなければならず、 それらはJavaScript実行コンテキストがrealmに入る前、かつそのrealmのグローバルオブジェクトが生成された後に作成されます。 あるrealm内の全初期オブジェクトの[[Prototype]]はそのrealm由来でなければなりません。

HTMLユーザーエージェントでは、複数のrealmが存在します(複数のフレームやウィンドウが生成された場合など)。 各フレームやウィンドウごとに独自の初期オブジェクト群があり、以下のHTML文書がこれを説明します:

<!DOCTYPE html>
<title>Different Realms</title>
<iframe id=a></iframe>
<script>
var iframe = document.getElementById("a");
var w = iframe.contentWindow;              // フレーム内のグローバルオブジェクト

Object == w.Object;                        // ECMA-262によりfalse
Node == w.Node;                            // false
iframe instanceof w.Node;                  // false
iframe instanceof w.Object;                // false
iframe.appendChild instanceof Function;    // true
iframe.appendChild instanceof w.Function;  // false
</script>

注: 全てのインターフェイスはどのrealm公開されるか定義します。 これにより例えばWeb Workers用のrealmは Webページ用realmとは異なるインターフェイス群を公開できます。

執筆時点ではJavaScript仕様に反映されていませんが、 全てのJavaScriptオブジェクトは関連realmを持たなければなりません。 オブジェクトとrealmの関連付け機構は現状未規定ですが、 プラットフォームオブジェクトでは関連realmがオブジェクトの関連realmと等価であり、 非エキゾチックな関数オブジェクト(callable proxyやbound関数でない)は 関数オブジェクトの[[Realm]]内部スロット値と等価です。

3.2. JavaScript型マッピング

この節では、IDLの型がJavaScriptの型にどのようにマッピングされるかを説明します。

以下の各小節では、指定されたIDL型の値がJavaScriptでどのように表現されるかを説明します。各IDL型について、JavaScript値が IDL値へ変換 される方法(その型を期待するプラットフォームオブジェクトに渡された場合)、およびIDL値が その型から JavaScript値へ変換 される方法(プラットフォームオブジェクトから返される場合)を記述します。

以下の小節やアルゴリズムは、拡張属性を型ヘッダーに適用して作られる注釈付き型にも適用されます。

3.2.1. any

IDL any型は 他の全IDL型の合併であるため、すべてのJavaScript値型に対応できます。

JavaScript値VをIDL any値に 変換するアルゴリズム:

  1. Vundefinedなら、 一意なundefined IDL値を返す。

  2. Vnullなら、 nullobject?参照を返す。

  3. VBoolean型なら、 同じ真偽値を表すboolean値を返す。

  4. VNumber型なら、 変換して unrestricted double値として返す。

  5. VBigInt型なら、 変換して bigint値として返す。

  6. VString型なら、 変換して DOMString値として返す。

  7. VSymbol型なら、 変換して symbol値として返す。

  8. VObject型なら、 Vを参照するIDL object値を返す。

IDL any値は JavaScript値へ変換 されますが、その際はIDL any値の 具体型の変換規則に従います(以降の節参照)。

3.2.2. undefined

JavaScript値VをIDL undefined値に 変換する場合、 Vを無視して一意なundefined値を返します。

一意なIDL undefined値は JavaScript値へ変換する際、 JavaScriptのundefined値となります。

3.2.3. boolean

JavaScript値VをIDL boolean値に 変換するアルゴリズム:

  1. xToBoolean(V)の計算結果とする。

  2. JavaScript Boolean値xと同じ真偽値を表すIDL boolean値を返す。

IDL booleantrueJavaScript値へ変換した時、 JavaScriptのtrue値となり、 falseはJavaScriptのfalse値となります。

3.2.4. 整数型

この節で使われる数学演算は、 ECMAScript § 5.2 アルゴリズム規約で定義されたものも含め、 数学的実数上の厳密な演算として理解してください。

つまり、xがNumber値である場合、 「xに対する演算」とは 「xと同じ数値を表す数学的実数に対する演算」を意味します。

3.2.4.1. byte

JavaScript値VをIDL byte値に 変換するアルゴリズム:

  1. x? ConvertToInt(V, 8, "signed")の結果とする。

  2. xと同じ数値を表すIDL byte値を返す。

IDL byte値を JavaScript値へ変換した結果は、 IDL byte値と同じ数値を表す Number値となります。 Number値は範囲[−128, 127]の整数です。

3.2.4.2. octet

JavaScript値VをIDL octet値に 変換するアルゴリズム:

  1. x? ConvertToInt(V, 8, "unsigned")の結果とする。

  2. xと同じ数値を表すIDL octet値を返す。

IDL octet値を JavaScript値へ変換した結果は、 IDL octet値と同じ数値を表す Number値となります。 Number値は範囲[0, 255]の整数です。

3.2.4.3. short

JavaScript値VをIDL short値に 変換するアルゴリズム:

  1. x? ConvertToInt(V, 16, "signed")の結果とする。

  2. xと同じ数値を表すIDL short値を返す。

IDL short値を JavaScript値へ変換した結果は、 IDL short値と同じ数値を表す Number値となります。 Number値は範囲[−32768, 32767]の整数です。

3.2.4.4. unsigned short

JavaScript値VをIDL unsigned short値に 変換するアルゴリズム:

  1. x? ConvertToInt(V, 16, "unsigned")の結果とする。

  2. xと同じ数値を表すIDL unsigned short値を返す。

IDL unsigned short値を JavaScript値へ変換した結果は、 IDL unsigned short値と同じ数値を表す Number値となります。 Number値は範囲[0, 65535]の整数です。

3.2.4.5. long

JavaScript値VをIDL long値に 変換するアルゴリズム:

  1. x? ConvertToInt(V, 32, "signed")の結果とする。

  2. xと同じ数値を表すIDL long値を返す。

IDL long値を JavaScript値へ変換した結果は、 IDL long値と同じ数値を表す Number値となります。 Number値は範囲[−2147483648, 2147483647]の整数です。

3.2.4.6. unsigned long

JavaScript値VをIDL unsigned long値に 変換するアルゴリズム:

  1. x? ConvertToInt(V, 32, "unsigned")の結果とする。

  2. xと同じ数値を表すIDL unsigned long値を返す。

IDL unsigned long値を JavaScript値へ変換した結果は、 IDL unsigned long値と同じ数値を表す Number値となります。 Number値は範囲[0, 4294967295]の整数です。

3.2.4.7. long long

JavaScript値VをIDL long long値に 変換するアルゴリズム:

  1. x? ConvertToInt(V, 64, "signed")の結果とする。

  2. xと同じ数値を表すIDL long long値を返す。

IDL long long値を JavaScript値へ変換した結果は、 long longに最も近い数値を表すNumber値となり、 2つの値が同じだけ近い場合は有効数字が偶数の方を選択します。 long longが範囲 [−253 + 1, 253 − 1]内なら、Numberは long longと全く同じ値を表せます。

3.2.4.8. unsigned long long

JavaScript値VをIDL unsigned long long値に 変換するアルゴリズム:

  1. x? ConvertToInt(V, 64, "unsigned")の結果とする。

  2. xと同じ数値を表すIDL unsigned long long値を返す。

IDL unsigned long long値を JavaScript値へ変換した結果は、 unsigned long longに最も近い数値を表すNumber値となり、 2つの値が同じだけ近い場合は有効数字が偶数の方を選択します。 unsigned long longが253−1以下なら、Numberは unsigned long longと全く同じ値を表せます。

3.2.4.9. 抽象演算

IntegerPart(n)

  1. rfloor(abs(n))とする。

  2. もしn<0なら−1×rを返す。

  3. それ以外ならrを返す。

ConvertToInt(V, bitLength, signedness)

  1. bitLengthが64なら:

    1. upperBoundを253−1とする。

    2. signednessが"unsigned"ならlowerBoundを0とする。

    3. それ以外ならlowerBoundを−253+1とする。

      注: これにより long long型に [EnforceRange]や [Clamp] 拡張属性が関連付けられている場合でも JavaScriptのNumber型で 明確な整数として表現可能です。

  2. それ以外でsignednessが"unsigned"なら:

    1. lowerBoundを0とする。

    2. upperBoundを2bitLength−1とする。

  3. それ以外の場合:

    1. lowerBoundを−2bitLength−1とする。

    2. upperBoundを2bitLength−1−1とする。

  4. x? ToNumber(V)とする。

  5. xが−0ならxを+0にする。

  6. 変換先IDL型が[EnforceRange] 拡張属性に関連付けられていたら:

    1. xNaN、+∞、−∞なら throw TypeError

    2. xIntegerPart(x)にする。

    3. x<lowerBoundまたはx>upperBoundなら throw TypeError

    4. xを返す。

  7. xNaNでなく、変換先IDL型が[Clamp]拡張属性に関連付けられていたら:

    1. xmin(max(x, lowerBound), upperBound)にする。

    2. xを最も近い整数に丸め、2つの整数の中間なら偶数整数を選択し、−0より+0を選択する。

    3. xを返す。

  8. xNaN、+0、+∞、−∞なら+0を返す。

  9. xIntegerPart(x)にする。

  10. xx modulo 2bitLengthにする。

  11. signednessが"signed"かつx≥2bitLength−1なら x−2bitLengthを返す。

  12. それ以外ならxを返す。

3.2.5. float

JavaScript値VをIDL float値に 変換するアルゴリズム:

  1. x? ToNumber(V)とする。

  2. xNaN、+∞、−∞なら throw TypeError

  3. Sを有限なIEEE 754単精度浮動小数点値集合(−0を除く)とし、2つの特殊値2128と−2128を加える。

  4. yxに最も近いS内の値とし、2つの値が同じだけ近い場合は有効数字が偶数の方を選択する。 (この目的で2128と−2128は有効数字が偶数と見なす。)

  5. yが2128または−2128なら throw TypeError

  6. yが+0かつxが負なら−0を返す。

  7. yを返す。

IDL float値を JavaScript値へ変換した結果は、 IDL float値と同じ数値を表す Number値です。

3.2.6. unrestricted float

JavaScript値VをIDL unrestricted float値に 変換するアルゴリズム:

  1. x? ToNumber(V)とする。

  2. xNaNなら、 IEEE 754 NaN値(ビットパターン0x7fc00000)を表すIDL unrestricted float値を返す。 [IEEE-754]

  3. Sを有限なIEEE 754単精度浮動小数点値集合(−0を除く)とし、2つの特殊値2128と−2128を加える。

  4. yxに最も近いS内の値とし、2つの値が同じだけ近い場合は有効数字が偶数の方を選択する。 (この目的で2128と−2128は有効数字が偶数と見なす。)

  5. yが2128なら+∞を返す。

  6. yが−2128なら−∞を返す。

  7. yが+0かつxが負なら−0を返す。

  8. yを返す。

注: JavaScriptのNaN値は1つしかないため、 特定の単精度IEEE 754 NaN値に正規化する必要があります。上記で言及したNaN値は、ビットパターンを32ビット符号なし整数として解釈したとき最小値のquiet NaNです。

IDL unrestricted float値を JavaScript値へ変換した結果はNumber値です:

  1. IDL unrestricted float値がNaNなら、 Number値はNaNです。

  2. それ以外は、IDL unrestricted float値と同じ数値を表すNumber値です。

3.2.7. double

JavaScript値VをIDL double値に 変換するアルゴリズム:

  1. x? ToNumber(V)とする。

  2. xNaN、+∞、−∞なら throw TypeError

  3. xと同じ数値を表すIDL double値を返す。

IDL double値を JavaScript値へ変換した結果は、 IDL double値と同じ数値を表す Number値です。

3.2.8. unrestricted double

JavaScript値VをIDL unrestricted double値に 変換するアルゴリズム:

  1. x? ToNumber(V)とする。

  2. xNaNなら、 IEEE 754 NaN値(ビットパターン0x7ff8000000000000)を表すIDL unrestricted double値を返す。 [IEEE-754]

  3. xと同じ数値を表すIDL unrestricted double値を返す。

注: JavaScriptのNaN値は1つしかないため、 特定の倍精度IEEE 754 NaN値に正規化する必要があります。上記で言及したNaN値は、ビットパターンを64ビット符号なし整数として解釈したとき最小値のquiet NaNです。

IDL unrestricted double値を JavaScript値へ変換した結果はNumber値です:

  1. IDL unrestricted double値がNaNなら、 Number値はNaNです。

  2. それ以外は、IDL unrestricted double値と同じ数値を表すNumber値です。

3.2.9. bigint

JavaScript値VをIDL bigint値に 変換するアルゴリズム:

  1. x? ToBigInt(V)とする。

  2. xと同じ数値を表すIDL bigint値を返す。

IDL bigint値を JavaScript値へ変換した結果はBigInt値です:

  1. IDL BigInt値で、 IDL bigint値と同じ数値を表すものを返す。

JavaScript値VをIDL 数値型 Tまたはbigint値に 変換するアルゴリズム:

  1. x? ToNumeric(V)とする。

  2. xBigInt型なら:

    1. xと同じ数値を表すIDL bigint値を返す。

  3. (アサーション)xNumber型

  4. Tへの変換結果を返す。

3.2.10. DOMString

JavaScript値VをIDL DOMString値に 変換するアルゴリズム:

  1. 変換先IDL型が[LegacyNullToEmptyString]拡張属性に関連付けられていて Vnullなら、空文字列を表すDOMString値を返す。

  2. x? ToString(V)とする。

  3. JavaScript String値xが表すコード単位列と同じ列を表すIDL DOMString値を返す。

IDL DOMString値を JavaScript値へ変換した結果は、 IDL DOMStringが表す コード単位列と同じ列を表す String値です。

3.2.11. ByteString

JavaScript値VをIDL ByteString値に 変換するアルゴリズム:

  1. x? ToString(V)とする。

  2. xのいずれかの要素値が255を超える場合、 throw TypeError

  3. xの長さと同じ長さで、各要素の値がxの対応する要素値と同じIDL ByteString値を返す。

IDL ByteString値を JavaScript値へ変換した結果は、 ByteStringの長さと同じ長さで、 各要素値が対応する ByteStringの要素値と同じ String値です。

3.2.12. USVString

JavaScript値VをIDL USVString値に 変換するアルゴリズム:

  1. stringVDOMString変換した結果とする。

  2. stringスカラー値列へ変換した結果を持つIDL USVString値を返す。

IDL USVStringSJavaScript値へ変換した結果はSです。

3.2.13. object

IDL object値は JavaScriptのObject値で表現されます。

JavaScript値VをIDL object値に 変換するアルゴリズム:

  1. VObject型でない場合、 throw TypeError

  2. Vと同じオブジェクトを参照するIDL object値を返す。

IDL object値を JavaScript値へ変換した結果は、 IDL objectが 参照する同一オブジェクトを参照するObject値です。

3.2.14. symbol

IDL symbol値は JavaScriptのSymbol値で表現されます。

JavaScript値VをIDL symbol値に 変換するアルゴリズム:
  1. VSymbol型でない場合、 throw TypeError

  2. Vと同じSymbolを参照するIDL symbol値を返す。

IDL symbol値を JavaScript値へ変換した結果は、 IDL symbolが 参照する同一Symbolを参照するSymbol値です。

3.2.15. インターフェイス型

IDL インターフェイス型値は JavaScriptのObject値(関数オブジェクトも含む)で表現されます。

JavaScript値VをIDL インターフェイス型値に 変換するアルゴリズム(Iインターフェイス):

  1. VI実装していれば、そのプラットフォームオブジェクトへの参照を表すIDL インターフェイス型値を返す。

  2. throw TypeError

IDL インターフェイス型値を JavaScript値へ変換した結果は、 IDL インターフェイス型値が参照する同一オブジェクトを参照する Object値です。

3.2.16. コールバックインターフェイス型

IDL コールバックインターフェイス型値は JavaScriptのObject値(関数オブジェクトも含む)で表現されます。

JavaScript値VをIDL コールバックインターフェイス型値に 変換するアルゴリズム:

  1. VObject型でない場合、 throw TypeError

  2. Vへの参照を持つIDL コールバックインターフェイス型値を返す。 この時現任設定オブジェクトコールバックコンテキストとする。

IDL コールバックインターフェイス型値を JavaScript値へ変換した結果は、 IDL コールバックインターフェイス型値が参照する同一オブジェクトを参照する Object値です。

3.2.17. 辞書型

IDL 辞書型値は JavaScriptのObject値で表現されます。オブジェクト(またはプロトタイプチェーン上)のプロパティが 辞書メンバーに対応します。

JavaScript値jsDictをIDL 辞書型値に 変換するアルゴリズム(D辞書型):

  1. jsDictObject型でなく undefinedでもnullでもない場合、 throw TypeError

  2. idlDictを空の順序付きマップ(型Dの辞書)で初期化。

  3. dictionariesを、Dとその全継承辞書のリスト(派生度が低い順→高い順)とする。

  4. dictionaries内の各dictionaryについて順に:

    1. dictionaryに宣言された各memberについて辞書順:

      1. keymember識別子とする。

      2. jsDictundefinedまたはnullなら:

        1. jsMemberValueundefinedとする。

      3. それ以外:

        1. jsMemberValue? Get(jsDict, key)とする。

      4. jsMemberValueundefinedでない場合:

        1. idlMemberValuejsMemberValuememberの型に変換した結果とする。

        2. Set idlDict[key] = idlMemberValue

      5. それ以外でjsMemberValueundefinedかつmemberデフォルト値を持つ場合:

        1. idlMemberValuememberのデフォルト値とする。

        2. Set idlDict[key] = idlMemberValue

      6. それ以外でjsMemberValueundefinedかつmemberrequiredなら TypeErrorをthrow。

  5. idlDictを返す。

注: JavaScriptオブジェクト上で辞書メンバーを検索する順序は オブジェクトのプロパティ列挙順とは限りません。

IDL辞書値VJavaScript値へ変換するアルゴリズム(D辞書):

  1. OOrdinaryObjectCreate(%Object.prototype%)で初期化。

  2. dictionariesを、Dとその全継承辞書のリスト(派生度が低い順→高い順)とする。

  3. dictionaries内の各dictionaryについて順に:

    1. dictionaryに宣言された各memberについて辞書順:

      1. keymember識別子とする。

      2. V[key]が存在すれば:

        1. idlValueV[key]とする。

        2. valueidlValueJavaScript値へ変換した結果とする。

        3. ! CreateDataPropertyOrThrow(O, key, value)を実行。

        なお、memberデフォルト値を持つ場合は keyは必ずV存在します。

  4. Oを返す。

3.2.18. 列挙型

IDL 列挙型は JavaScriptのString値で表現されます。

JavaScript値VをIDL 列挙型値に 変換する手順(E列挙型):

  1. S? ToString(V)の結果とする。

  2. SE列挙値のいずれでもなければ、 throw TypeError

  3. Sと等しい型Eの列挙値を返す。

IDL 列挙型値を JavaScript値へ変換した結果は、 コード単位列が 列挙値と同じであるString値です。

3.2.19. コールバック関数型

IDL コールバック関数型は JavaScriptの関数オブジェクトで表現されます。 ただし[LegacyTreatNonObjectAsNull]の場合は任意のオブジェクトも可です。

JavaScript値VをIDL コールバック関数型値に 変換する手順:

  1. IsCallable(V)の結果がfalseで、 変換先IDL値が属性の値となる場合であり、 その属性型が[LegacyTreatNonObjectAsNull]注釈付きnullableな コールバック関数型でない場合、 throw TypeError

  2. Vが参照するオブジェクトへの参照を持ち、現任設定オブジェクトコールバックコンテキストとするIDL コールバック関数型値を返す。

IDL コールバック関数型値を JavaScript値へ変換した結果は、 IDL コールバック関数型値が参照する同一オブジェクトを参照する値です。

3.2.20. nullable型 — T?

IDL nullable型値は inner IDL型に対応するJavaScript型の値、またはJavaScriptのnull値で表現されます。

JavaScript値VをIDL nullable型 T?値に 変換する手順(Tinner型):

  1. VObject型でない場合で、 V属性の値として割り当てられる場合、 その属性型が[LegacyTreatNonObjectAsNull]注釈付きnullableな コールバック関数型であるなら、IDL nullable型 T?nullを返す。

  2. それ以外でVundefinedかつTundefinedを含むなら、一意なundefined値を返す。

  3. それ以外でVnullまたはundefinedなら、 IDL nullable型 T?nullを返す。

  4. それ以外は変換規則に従い、 T型としてVを変換した結果を返す。

IDL nullable型値を JavaScript値へ変換する手順:

  1. IDL nullable型 T?値がnullなら、 JavaScript値はnull

  2. それ以外は、inner型TとしてIDL値をJavaScript値へ変換した結果。

3.2.21. sequence型 — sequence<T>

IDL sequence<T>値は JavaScriptのArray値で表現されます。

JavaScript値VをIDL sequence<T>値に 変換する手順:

  1. VObject型でない場合、 throw TypeError

  2. method? GetMethod(V, %Symbol.iterator%)の結果とする。

  3. methodundefinedなら、 throw TypeError

  4. Vmethodからsequenceの生成を行った結果を返す。

sequence<T>の IDL sequence値SJavaScriptのArrayオブジェクトに変換する手順:

  1. nSの長さとする。

  2. A[]式で生成した新しいArrayオブジェクトとする。

  3. iを0で初期化。

  4. i<nの間:

    1. VSのインデックスiの値とする。

    2. EVJavaScript値へ変換した結果とする。

    3. P! ToString(i)の結果とする。

    4. ! CreateDataPropertyOrThrow(A, P, E)を実行。

    5. ii+1にする。

  5. Aを返す。

3.2.21.1. イテラブルからsequenceの生成

イテラブルiterableとイテレータ取得メソッドmethodが与えられたとき、型sequence<T>のIDL値を生成するには、以下の手順を行う:

  1. iteratorRecord? GetIteratorFromMethod(iterable, method)の結果とする。

  2. iを0で初期化。

  3. 繰り返し:

    1. next? IteratorStepValue(iteratorRecord)の結果とする。

    2. nextdoneなら、 長さiの型sequence<T>のIDL値を返す。 インデックスjの要素の値はSjとする。

    3. Sinextを型TのIDL値に変換した結果で初期化。

    4. ii+1にする。

次のインターフェイスは sequence型属性とsequence型引数を持つ操作を定義する。

[Exposed=Window]
interface Canvas {

  sequence<DOMString> getSupportedImageCodecs();

  undefined drawPolygon(sequence<double> coordinates);
  sequence<double> getLastDrawnPolygon();

  // ...
};

このインターフェイスのJavaScript実装では、要素型がStringのArrayオブジェクトがsequence<DOMString>を、 要素型がNumberのArrayがsequence<double>を表現する。 Arrayオブジェクトは事実上値渡しとなる。 getSupportedImageCodecs()関数の呼び出しごとに新しいArrayが返り、 ArrayがdrawPolygonに渡された場合も呼び出し完了後は参照が保持されない。

// Canvasインスタンス取得。getSupportedImageCodecs()は
// 2つのDOMString値:"image/png"と"image/svg+xml"からなるsequenceを返すと仮定。
var canvas = getCanvas();

// 長さ2のArrayオブジェクト。
var supportedImageCodecs = canvas.getSupportedImageCodecs();

// "image/png"を返す。
supportedImageCodecs[0];

// canvas.getSupportedImageCodecs()の呼び出しごとに新しいArrayオブジェクトが返る。
// 返されたArrayを変更しても、次の呼び出しの戻り値には影響しない。
supportedImageCodecs[0] = "image/jpeg";

// "image/png"を返す。
canvas.getSupportedImageCodecs()[0];

// 常に新しいArrayが返るので、==で比較するとfalse。
canvas.getSupportedImageCodecs() == canvas.getSupportedImageCodecs();

// NumberのArray...
var a = [0, 0, 100, 0, 50, 62.5];

// ...はsequence<double>を期待するプラットフォームオブジェクトに渡せる。
canvas.drawPolygon(a);

// 各要素はまずToNumber()でdoubleに変換される。
// 次の呼び出しは前のものと同じだが、"hi"はdrawPolygon()の戻り前にalertされる。
a = [false, "",
     { valueOf: function() { alert("hi"); return 100; } }, 0,
     "50", new Number(62.5)];
canvas.drawPolygon(a);

// drawPolygon()に渡したArrayを変更してもCanvasには影響しない(値渡し)。
a[4] = 20;
var b = canvas.getLastDrawnPolygon();
alert(b[4]);    // "50"がalertされる。

3.2.22. 非同期sequence型 — async_sequence<T>

JavaScriptバインディングにおいて、IDL async sequence値は 以下の構造体として表現される:

JavaScript値VをIDL async_sequence<T>値に 変換する手順:
  1. VObject型でない場合、 throw TypeError

  2. method? GetMethod(obj, %Symbol.asyncIterator%)の結果とする。

  3. methodundefinedの場合:

    1. syncMethod? GetMethod(obj, %Symbol.iterator%)の結果とする。

    2. syncMethodがundefinedならthrow TypeError

    3. IDL async sequence値を返す。objectVmethodsyncMethodtypeに"sync"を設定。

  4. IDL async sequence値を返す。objectVmethodmethodtypeに"async"を設定。

IDL async_sequence<T>VJavaScriptオブジェクトに変換する手順:
  1. Vobjectを返す。

3.2.22.1. 非同期sequenceのイテレーション

async sequenceは直接イテレートされません。まずオープンして非同期イテレータを作成し、その非同期イテレータを非同期的にイテレートして値を生成します。

非同期イテレータは、以下の構造体項目を持ちます:

async sequenceのオープン手順: async_sequence<T> sequenceについて:

  1. iterator? GetIteratorFromMethod(sequenceobject, sequencemethod)とする。

  2. sequencetypeが"sync"の場合は iteratorCreateAsyncFromSyncIterator(iterator)の結果に置換する。

  3. 非同期イテレータ値を返す。 underlying recorditeratortype parameterTを設定。

非同期イテレータの次の値取得手順: 非同期イテレータ iteratorについて:

  1. nextResultIteratorNext(iteratorunderlying record)の結果とする。

  2. nextResultabrupt completionなら、その値でrejectされたpromiseを返す。

  3. nextPromisenextResultの値でresolveされたpromiseとする。

  4. nextPromiseに対して、以下のfulfilledステップで反応する(iterResultを与える):

    1. iterResultObject型でない場合は、throw TypeError

    2. done? IteratorComplete(iterResult)の結果とする。

    3. もしdoneがtrueなら:

      1. イテレーション終了を返す。

    4. それ以外:

      1. V? IteratorValue(iterResult)の結果とする。

      2. valueViteratortype parameter型のIDL値に変換した結果とする。

      3. valueを返す。

非同期イテレータのクローズ手順: async iterator<T> iterator(ECMAScript値reason付き)について:

  1. iteratorRecorditeratorunderlying recordとする。

  2. iteratorObjiteratorRecord.[[Iterator]]とする。

  3. returnMethodGetMethod(iteratorObj, "return")の結果とする。

  4. returnMethodabrupt completionなら、その値でrejectされたpromiseを返す。

  5. returnMethodundefinedなら、undefinedでresolveされたpromiseを返す。

  6. returnResultCall(returnMethod.[[Value]], iteratorObj, « reason »)の結果とする。

  7. returnResultabrupt completionなら、その値でrejectされたpromiseを返す。

  8. returnPromisereturnResultの値でresolveされたpromiseとする。

  9. returnPromiseに対して、以下のfulfilledステップで反応する(returnPromiseResultを与える):

    1. returnPromiseResultObject型でない場合は、throw TypeError

    2. undefinedを返す。

concatNは、引数で渡されたasync sequenceがyieldする全ての文字列を連結した結果を返すpromiseを返す操作です。async sequenceがmaxN個の文字列をyieldしたらそこで連結・イテレータをクローズします。

interface I {
  Promise<DOMString> concatN(async_sequence<DOMString> strings, unsigned long maxN);
};

concatN(sequence, maxN)メソッドの手順:

  1. promise新しいpromiseとする。

  2. resultを空文字列で初期化。

  3. nを0で初期化。

  4. iteratorsequenceオープンした結果とする。

  5. stepをasync sequenceを処理する手順列とする:

    1. nextiterator次の値取得の結果とする。

    2. next反応する:

      • nextが値vでfulfilledされた場合:

        1. vイテレーション終了ならpromiseresultresolve

        2. resultvを連結した結果でresultを更新。

        3. nn+1に。

        4. nmaxNなら:

          1. finishiteratorを理由undefinedクローズした結果とする。

          2. finish反応する:

            • finishがfulfilledならpromiseresultresolve

            • finishが理由rでrejectedならpromiserreject

        5. それ以外:

          1. stepを呼び出す。

      • nextが理由rでrejectedされた場合はpromiserreject

  6. stepを呼び出す。

  7. promiseを返す。

3.2.23. record型 — record<K, V>

IDL record<K, V>値は JavaScriptのObject値で表現されます。

JavaScript値OをIDL record<K, V>値に 変換する手順:

  1. OObject型でない場合、 throw TypeError

  2. resultを新しい空の record<K, V>インスタンスで初期化。

  3. keys? O.[[OwnPropertyKeys]]()の結果とする。

  4. keysの各 keyについて:

    1. desc? O.[[GetOwnProperty]](key)の結果とする。

    2. descundefinedでなく、かつdesc.[[Enumerable]]がtrueなら:

      1. typedKeykeyを型KのIDL値に変換した結果とする。

      2. value? Get(O, key)の結果とする。

      3. typedValuevalueを型VのIDL値に変換した結果とする。

      4. Set result[typedKey] = typedValue

        注: KUSVStringkeyにペアでないサロゲートが含まれる場合、 typedKeyがすでにresultに存在する可能性があります。

  5. resultを返す。

IDL record<…>DJavaScript値へ変換する手順:

  1. resultOrdinaryObjectCreate(%Object.prototype%)で初期化。

  2. Dの各key→valueについて:

    1. jsKeykeyJavaScript値に変換した結果とする。

    2. jsValuevalueJavaScript値に変換した結果とする。

    3. created! CreateDataProperty(result, jsKey, jsValue)の結果とする。

    4. (アサーション)createdtrueである。

  3. resultを返す。

JavaScript値{b: 3, a: 4}record<DOMString, double>型引数として渡した場合、 IDL値「[ "b" → 3, "a" → 4 ]」となります。

Recordは自分自身の enumerableプロパティのみを考慮します。 したがって、以下のIDL操作 record<DOMString, double> identity(record<DOMString, double> arg)が引数をそのまま返す場合、下記のコードはアサーションをパスします:

let proto = {a: 3, b: 4};
let obj = {__proto__: proto, d: 5, c: 6}
Object.defineProperty(obj, "e", {value: 7, enumerable: false});
let result = identity(obj);
console.assert(result.a === undefined);
console.assert(result.b === undefined);
console.assert(result.e === undefined);
let entries = Object.entries(result);
console.assert(entries[0][0] === "d");
console.assert(entries[0][1] === 5);
console.assert(entries[1][0] === "c");
console.assert(entries[1][1] === 6);

Recordのキーと値には制約を設けられますが、キーは3つの文字列型間のみ制約できます。 下記の変換結果は次の通りです:

渡される型 結果
{"😞": 1} record<ByteString, double> TypeError
{"\uD83D": 1} record<USVString, double> «[ "\uFFFD" → 1 ]»
{"\uD83D": {hello: "world"}} record<DOMString, double> «[ "\uD83D" → 0 ]»

3.2.24. Promise型 — Promise<T>

IDL promise型値は JavaScriptのPromiseCapabilityレコードで表現されます。

JavaScript値VをIDL Promise<T>値に 変換する手順:

  1. promiseCapability? NewPromiseCapability(%Promise%)で初期化。

  2. ? Call(promiseCapability.[[Resolve]], undefined, « V »)を実行。

  3. promiseCapabilityを返す。

IDL promise型値を JavaScript値へ変換した結果は、 IDL promise型値が表すレコードの[[Promise]]フィールドの値です。

3.2.24.1. Promiseの生成・操作

新しいPromiseの生成手順: Promise<T>realm realmで生成するには:

  1. constructorrealm.[[Intrinsics]].[[%Promise%]]とする。

  2. ? NewPromiseCapability(constructor)を返す。

resolveされたpromiseの生成手順: Promise<T> 型で値x(型T)をrealm realmに持つ場合:

  1. valuexJavaScript値に変換した結果とする。

  2. constructorrealm.[[Intrinsics]].[[%Promise%]]とする。

  3. promiseCapability? NewPromiseCapability(constructor)で初期化。

  4. ! Call(promiseCapability.[[Resolve]], undefined, « value »)を実行。

  5. promiseCapabilityを返す。

rejectされたpromiseの生成手順: Promise<T> 型で理由r(JavaScript値)をrealm realmに持つ場合:

  1. constructorrealm.[[Intrinsics]].[[%Promise%]]とする。

  2. promiseCapability? NewPromiseCapability(constructor)で初期化。

  3. ! Call(promiseCapability.[[Reject]], undefined, « r »)を実行。

  4. promiseCapabilityを返す。

resolve手順: Promise<T> pを値x(型T)でresolveするには:

  1. xが与えられていない場合は、一意なundefined値とする。

  2. valuexJavaScript値に変換した結果とする。

  3. ! Call(p.[[Resolve]], undefined, « value »)を実行。

Tundefinedなら、 x引数は省略可能であり、簡易な「resolve p」用法が可能です。

reject手順: Promise<T> pを理由r(JavaScript値)でrejectするには:

  1. ! Call(p.[[Reject]], undefined, « r »)を実行。

promiseへの反応手順: Promise<T> promiseに対して、fulfilled/rejectedまたは両方の場合の処理手順を与えて以下を実行:

  1. 引数Vで呼ばれるonFulfilledStepsを以下とする:

    1. valueVを型TのIDL値に変換した結果とする。

    2. promiseがfulfilledの場合に実行する手順があれば、resultをその手順をvalueTundefined以外の場合のみ)で実行した結果とし、 それ以外はresultvalueとする。

    3. resultJavaScript値に変換して返す。

  2. onFulfilledCreateBuiltinFunction(onFulfilledSteps, « »)とする。

  3. 引数Rで呼ばれるonRejectedStepsを以下とする:

    1. reasonRを型anyのIDL値に変換した結果とする。

    2. promiseがrejectedの場合に実行する手順があれば、resultをその手順をreasonで実行した結果とし、 それ以外はresultreasonでrejectされたpromiseとする。

    3. resultJavaScript値に変換して返す。

  4. onRejectedCreateBuiltinFunction(onRejectedSteps, « »)とする。

  5. constructorpromise.[[Promise]].[[Realm]].[[Intrinsics]].[[%Promise%]]とする。

  6. newCapability? NewPromiseCapability(constructor)で初期化。

    注: 返したPromiseを 呼び出し側が必ず使うとは限りません。実装によってはnewCapabilityの生成を省略してよい場合があります。

  7. PerformPromiseThen(promise.[[Promise]], onFulfilled, onRejected, newCapability)を実行。

  8. newCapabilityを返す。

注: このアルゴリズムは promise.then() メソッドと非常に似た動作をします。 特に、手順が型UまたはPromise<U>値を返す場合、 このアルゴリズムもPromise<U>を返します。

fulfillment時の処理手順: Promise<T> promiseのfulfillment時に型Tの値を受け取る手順stepsを実行するには:

  1. promiseへの反応手順の結果を返す:

    • promiseが値vでfulfilledされた場合:

      1. stepsvで実行。

rejection時の処理手順: Promise<T> promiseのrejection時にJavaScript値を受け取る手順stepsを実行するには:

  1. promiseへの反応手順の結果を返す:

    • promiseが理由rでrejectedされた場合:

      1. stepsrで実行。

全てを待つ手順: listPromise<T>promises、成功時手順successStepslistT値を受け取る)、失敗時手順failureSteps(理由any値を受け取る)について:

  1. fullfilledCountを0で初期化。

  2. rejectedをfalseで初期化。

  3. rejectionHandlerStepsを引数argで呼ばれる以下の手順とする:

    1. rejectedがtrueならこの手順を中止。

    2. rejectedをtrueにする。

    3. failureStepsargで実行。

  4. rejectionHandlerCreateBuiltinFunction(rejectionHandlerSteps, « »)とする。

  5. totalpromisessizeとする。

  6. totalが0なら:

    1. マイクロタスクをキューしてsuccessStepsに« »を与えて実行。

    2. return。

  7. indexを0で初期化。

  8. resulttotal個のnull値のlistで初期化。

  9. promisesの各promiseについて:

    1. promiseIndexindexとする。

    2. fulfillmentHandlerを引数argで呼ばれる以下の手順とする:

      1. result[promiseIndex]にargをセット。

      2. fullfilledCountfullfilledCount+1に。

      3. fullfilledCounttotalと等しければsuccessStepsresultを与えて実行。

    3. fulfillmentHandlerCreateBuiltinFunction(fulfillmentHandler, « »)とする。

    4. PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler)を実行。

    5. indexindex+1に。

全てを待つpromiseの取得手順: listPromise<T>promisesrealm realmについて:

  1. promise新しいPromisePromise<sequence<T>>realmで生成した結果とする。

  2. successStepsを引数resultsで呼ばれる以下の手順とする:

    1. resolve promiseresultsで実行。

  3. failureStepsを引数reasonで呼ばれる以下の手順とする:

    1. reject promisereasonで実行。

  4. 全てを待つ手順に promisessuccessStepsfailureStepsを与えて実行。

  5. promiseを返す。

この定義は複数promiseの結果を集約して新たなpromiseを生成したい場合に有用です。 これはJavaScriptのPromise.all()と同様です。 新たなpromiseが不要なら全てを待つ手順の方が適しています。

handledとしてマーク手順: Promise<T> promiseについて promise.[[Promise]].[[PromiseIsHandled]]をtrueに設定する。

この定義はrejectされることが多く無視されるpromiseに有用です。 これによりunhandledrejectionイベントを発生させません。 よくある例はプロミスプロパティで、Web開発者が参照する場合と参照しない場合があります。 例としてwritableStreamWriter.closedプロパティのpromiseがあります。

3.2.24.2.

delay操作で、指定したミリ秒後にfulfilledされるpromiseを返します。 Promiseをresolveする方法のシンプルな例です。

interface I {
  Promise<undefined> delay(unrestricted double ms);
};

delay(ms)メソッドの手順:

  1. realmthis関連realmとする。

  2. taskSourceを適切なタスクソースとする。

  3. msがNaNならmsを+0とし、そうでなければmsと+0の大きい方にする。

  4. p新しいpromiserealmで生成したものとする。

  5. 以下の手順を並行して行う:

    1. msミリ秒待つ。

    2. タスクをキューしてtaskSource上でresolve pを行う。

  6. pを返す。

validatedDelay操作で、delay関数と似ていますが 引数のバリデーションを行います。 非同期処理開始前に即時rejectされたpromiseを使う例です。

interface I {
  Promise<undefined> validatedDelay(unrestricted double ms);
};

validatedDelay(ms)メソッドの手順:

  1. realmthis関連realmとする。

  2. taskSourceを適切なタスクソースとする。

  3. msがNaNならTypeErrorでrejectされたpromiserealmで返す。

  4. msが0未満ならRangeErrorでrejectされたpromiserealmで返す。

  5. p新しいpromiserealmで生成したものとする。

  6. 以下の手順を並行して行う:

    1. msミリ秒待つ。

    2. タスクをキューしてtaskSource上でresolve pを行う。

  7. pを返す。

addDelay操作で、promiseのsettle後に追加で指定した遅延(ms)を加えて 新しいpromiseのsettleを遅らせます。

interface I {
  Promise<any> addDelay(Promise<any> promise, unrestricted double ms);
};

addDelay(ms, promise)メソッドの手順:

  1. realmthis関連realmとする。

  2. taskSourceを適切なタスクソースとする。

  3. msがNaNならmsを+0とし、そうでなければmsと+0の大きい方にする。

  4. p新しいpromiserealmで生成したものとする。

  5. promiseへの反応promiseに対して行う:

    • promiseが値vでfulfilledされた場合:

      1. 以下の手順を並行して行う:

        1. msミリ秒待つ。

        2. タスクをキューしてtaskSource上でresolve pvで行う。

    • promiseが理由rでrejectedされた場合:

      1. 以下の手順を並行して行う:

        1. msミリ秒待つ。

        2. タスクをキューしてtaskSource上でreject prで行う。

  6. pを返す。

environment.ready属性で、環境(例: DOM documentなど)が「ready」状態になった時を通知します。 環境に依存した非同期状態のコーディング例です。

interface Environment {
  readonly attribute Promise<undefined> ready;
};

すべてのEnvironmentオブジェクトはready promise(型Promise<undefined>)を持ちます。

ready属性getterの手順:

  1. thisready promiseを返す。

Environmentオブジェクトをrealm realmで生成する手順:

  1. taskSourceを適切なタスクソースとする。

  2. environmentnew Environmentオブジェクトとしてrealmで生成する。

  3. environmentready promise新しいpromiseで初期化。

  4. 以下の手順を並行して行う:

    1. 非同期処理を実行する。

    2. environmentがreadyになったら、タスクをキューしてtaskSource上でresolve environmentready promiseを行う。

    3. environmentがreadyにならなかったら、タスクをキューしてtaskSource上でreject environmentready promiseを "NetworkError" DOMExceptionで行う。

  5. environmentを返す。

addBookmark操作で、ユーザーに現在のウェブページをブックマーク登録するようリクエストします。 設計検討の例からの実例で、 環境非同期性や即時rejectの現実的な使い方を示します。

interface I {
  Promise<undefined> addBookmark();
};

addBookmark()メソッドの手順:

  1. taskSourceを適切なタスクソースとする。

  2. このメソッドが明示的なユーザー操作によって呼び出されていなければ、 SecurityErrorでrejectされたpromise DOMExceptionを返す。

  3. ドキュメントの動作モードがスタンドアロンなら NotSupportedErrorでrejectされたpromise DOMExceptionを返す。

  4. promise新しいpromiseで初期化。

  5. infoをウェブアプリのメタデータ取得結果とする。

  6. 以下の手順を並行して行う:

    1. infoを使って、ユーザーエージェント依存で ユーザーがブックマーク追加するか選択できるようにする。

      1. ブックマーク追加リクエストをユーザーが中止したら(例: Escapeキーや「キャンセル」ボタンなど)、 タスクをキューしてtaskSource上でreject promiseを "AbortError" DOMExceptionで行う。

      2. それ以外の場合はタスクをキューしてtaskSource上でresolve promiseを行う。

  7. promiseを返す。

[SERVICE-WORKERS]の複数箇所でget a promise to wait for allが使われています。 batchRequestはその簡易バージョン例です。 入力としてURLのsequenceを受け取り、 各URLをfetchして得られるResponseオブジェクトのsequenceのpromiseを返します。 fetchのどれかが失敗した場合はその失敗でrejectされます。

interface I {
  Promise<sequence<Response>> batchRequest(sequence<USVString> urls);
};

batchRequest(urls)メソッドの手順:

  1. responsePromisesを空リスト« »で初期化。

  2. urlsの各urlについて:

    1. pfetch()urlを渡して呼び出した結果とする。

    2. responsePromisesにpを追加する。

  3. pget a promise to wait for allresponsePromisesを渡して呼び出した結果とする。

  4. pを返す。

3.2.25. ユニオン型

IDL ユニオン型値は JavaScriptの値で表現され、 それぞれユニオンのメンバー型に対応します。

JavaScript値VをIDL ユニオン型値に 変換する手順:

  1. ユニオン型がundefinedを含む場合でVundefinedなら、 一意なundefined値を返す。

  2. ユニオン型がnullable型を含む場合で Vnullまたはundefinedなら、 IDL値nullを返す。

  3. typesをユニオン型のフラット化メンバー型とする。

  4. Vnullまたはundefinedの場合:

    1. types辞書型が含まれていれば、 Vをその辞書型に変換した結果を返す。

  5. Vプラットフォームオブジェクトなら:

    1. typesV実装するインターフェイス型が含まれていれば、 Vへの参照を持つIDL値を返す。

    2. typesobjectが含まれていれば、 Vへの参照を持つIDL値を返す。

  6. VObject型で、Vが[[ArrayBufferData]] 内部スロットを持ち、 IsSharedArrayBuffer(V)がfalseなら:

    1. typesArrayBufferが含まれていれば、 VArrayBuffer変換した結果を返す。

    2. typesobjectが含まれていれば、 Vへの参照を持つIDL値を返す。

  7. VObject型で、Vが[[ArrayBufferData]] 内部スロットを持ち、 IsSharedArrayBuffer(V)がtrueなら:

    1. typesSharedArrayBufferが含まれていれば、 VSharedArrayBuffer変換した結果を返す。

    2. typesobjectが含まれていれば、 Vへの参照を持つIDL値を返す。

  8. VObject型で、Vが[[DataView]] 内部スロットを持つ場合:

    1. typesDataViewが含まれていれば、 VDataView変換した結果を返す。

    2. typesobjectが含まれていれば、 Vへの参照を持つIDL値を返す。

  9. VObject型で、Vが[[TypedArrayName]] 内部スロットを持つ場合:

    1. typesVの[[TypedArrayName]] 内部スロット値と一致する型付き配列型が含まれていれば、 Vをその型に変換した結果を返す。

    2. typesobjectが含まれていれば、 Vへの参照を持つIDL値を返す。

  10. IsCallable(V)がtrueなら:

    1. typesコールバック関数型が含まれていれば、 Vをその型に変換した結果を返す。

    2. typesobjectが含まれていれば、 Vへの参照を持つIDL値を返す。

  11. VObject型なら:

    1. typesasync sequence型が含まれていれば:

      1. types文字列型が含まれていないか、 Vが[[StringData]] 内部スロットを持たない場合:

        1. asyncMethod? GetMethod(V, %Symbol.asyncIterator%)の結果とする。

        2. asyncMethodundefinedでなければ、 async sequence型のIDL値を返す。 objectVmethodsyncMethodtypeに"async"を設定。

        3. syncMethod? GetMethod(V, %Symbol.iterator%)の結果とする。

        4. syncMethodundefinedでなければ、 async sequence型のIDL値を返す。 objectVmethodsyncMethodtypeに"sync"を設定。

    2. typessequence型が含まれていれば:

      1. method? GetMethod(V, %Symbol.iterator%)の結果とする。

      2. methodundefinedでなければ、 sequenceを生成した結果を返す。

    3. typesfrozen array型が含まれていれば:

      1. method? GetMethod(V, %Symbol.iterator%)の結果とする。

      2. methodundefinedでなければ、 frozen arrayを生成した結果を返す。

    4. types辞書型が含まれていれば、 Vをその型に変換した結果を返す。

    5. typesrecord型が含まれていれば、 Vをその型に変換した結果を返す。

    6. typesコールバックインターフェイス型が含まれていれば、 Vをその型に変換した結果を返す。

    7. typesobjectが含まれていれば、 Vへの参照を持つIDL値を返す。

  12. VBoolean型なら:

    1. typesbooleanが含まれていれば、 Vboolean変換した結果を返す。

  13. VNumber型なら:

    1. types数値型が含まれていれば、 Vをその型に変換した結果を返す。

  14. VBigInt型なら:

    1. typesbigintが含まれていれば、 Vbigint変換した結果を返す。

  15. types文字列型が含まれていれば、 Vをその型に変換した結果を返す。

  16. types数値型bigintが含まれていれば、 V数値型またはbigint型へ変換した結果を返す。

  17. types数値型が含まれていれば、 Vをその型に変換した結果を返す。

  18. typesbooleanが含まれていれば、 Vboolean変換した結果を返す。

  19. typesbigintが含まれていれば、 Vbigint変換した結果を返す。

  20. TypeErrorをthrowする。

IDLユニオン型値は JavaScript値へ変換されます。 変換方法は当該IDLユニオン型値の具体的な型の規則に従います(§ 3.2 JavaScript型マッピング参照)。

3.2.26. バッファソース型

IDL ArrayBuffer値は 対応するJavaScriptクラスのオブジェクトとして表現されます。 [AllowResizable]拡張属性に関連付けられていない場合は、JavaScript ArrayBuffer オブジェクトVのうち、IsResizableArrayBuffer(V)がfalseであるもののみ裏付けできます。

IDL SharedArrayBuffer値は 対応するJavaScriptクラスのオブジェクトとして表現されます。 [AllowResizable]拡張属性に関連付けられていない場合は、JavaScript SharedArrayBuffer オブジェクトVのうち、 IsResizableArrayBuffer(V)がfalseであるもののみ裏付けできます。

IDL バッファビュー型の値は 対応するJavaScriptクラスのオブジェクトとして表現され、さらに以下の制約が適用されます。

JavaScript値VをIDL ArrayBuffer値に 変換するアルゴリズム:

  1. VObject型でない、 またはVが[[ArrayBufferData]] 内部スロットを持たない場合、 throw TypeError

  2. IsSharedArrayBuffer(V)がtrueなら throw TypeError

  3. 変換先IDL型が[AllowResizable]拡張属性に関連付けられていない場合で、 IsResizableArrayBuffer(V)がtrueなら throw TypeError

  4. Vと同じオブジェクトへの参照を持つIDL ArrayBuffer値を返す。

JavaScript値VをIDL SharedArrayBuffer値に 変換するアルゴリズム:

  1. VObject型でない、 またはVが[[ArrayBufferData]] 内部スロットを持たない場合、 throw TypeError

  2. IsSharedArrayBuffer(V)がfalseなら throw TypeError

  3. 変換先IDL型が[AllowResizable]拡張属性に関連付けられていない場合で、 IsResizableArrayBuffer(V)がtrueなら throw TypeError

  4. Vと同じオブジェクトへの参照を持つIDL SharedArrayBuffer値を返す。

JavaScript値VをIDL DataView値に 変換するアルゴリズム:

  1. VObject型でない、 またはVが[[DataView]] 内部スロットを持たない場合、 throw TypeError

  2. 変換先IDL型が[AllowShared]拡張属性に関連付けられていない場合で、 IsSharedArrayBuffer(V.[[ViewedArrayBuffer]])がtrueなら throw TypeError

  3. 変換先IDL型が[AllowResizable]拡張属性に関連付けられていない場合で、 IsResizableArrayBuffer(V.[[ViewedArrayBuffer]])がtrueなら throw TypeError

  4. Vと同じオブジェクトへの参照を持つIDL DataView値を返す。

JavaScript値 V は、 変換 されて、IDLの Int8ArrayInt16ArrayInt32ArrayUint8ArrayUint16ArrayUint32ArrayUint8ClampedArrayBigInt64ArrayBigUint64ArrayFloat16ArrayFloat32Array、 または Float64Array 値に 変換されるため、次のアルゴリズムを実行する:

  1. T を、V が変換されようとしている IDL 型とする。

  2. もし VObject でない、 または V が [[TypedArrayName]] 内部スロットを持たず、その値が T の名前と等しくない場合、 throwTypeError をスローする。

  3. 変換先が [AllowShared] 拡張属性関連付けられていない IDL 型であり、IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) が true の場合、 throwTypeError をスローする。

  4. 変換先が [AllowResizable] 拡張属性関連付けられていない IDL 型であり、IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) が true の場合、 throwTypeError をスローする。

  5. T 型の IDL 値で、V と同じオブジェクトへの参照を返す。

任意のバッファソース型のIDL値をJavaScript値に変換した結果は、 そのIDL値が参照しているオブジェクトと同じオブジェクトへの参照を表すObject値である。

切り離す ArrayBuffer arrayBuffer を:
  1. jsArrayBuffer? AllocateArrayBuffer(realm.[[Intrinsics]].[[%ArrayBuffer%]], bytes長さ) とする。

  2. arrayBuffer を、jsArrayBufferArrayBuffer 型のIDL値に変換した結果とする。

  3. bytesarrayBuffer書き込む

  4. arrayBuffer を返す。

生成する SharedArrayBuffer バイト列 bytesrealm realm で:
  1. jsSharedArrayBuffer? AllocateSharedArrayBuffer(realm.[[Intrinsics]].[[%SharedArrayBuffer%]], bytes長さ) とする。

  2. sharedArrayBuffer を、jsSharedArrayBufferSharedArrayBuffer 型のIDL値に変換した結果とする。

  3. bytessharedArrayBuffer書き込む

  4. sharedArrayBuffer を返す。

生成する ArrayBufferView 型のいずれかを バイト列 bytesrealm realm で:
  1. 型が DataView でない場合、bytes長さ を、その型の 要素サイズ で割った余りが 0 であることを保証する。

  2. arrayBufferArrayBuffer を bytes から realm で作成した結果とする。

  3. jsArrayBufferarrayBuffer を JavaScript値に変換した結果とする。

  4. constructorrealm.[[Intrinsics]] から作成する ArrayBufferView 型に対応するコンストラクタとする。

  5. jsView! Construct(constructor, « jsArrayBuffer ») とする。

  6. jsView を与えられた型に 変換した結果を返す。

バッファソースが保持するバイト列のコピーを得るには、buffer source型 のインスタンス bufferSource を用い、以下の手順を実行する:
  1. jsBufferSourcebufferSource を JavaScript値に変換した結果とする。

  2. jsArrayBufferjsBufferSource とする。

  3. offset を 0 とする。

  4. length を 0 とする。

  5. jsBufferSource が [[ViewedArrayBuffer]] 内部スロット を持つ場合:

    1. jsArrayBufferjsBufferSource.[[ViewedArrayBuffer]] に設定する。

    2. offsetjsBufferSource.[[ByteOffset]] に設定する。

    3. lengthjsBufferSource.[[ByteLength]] に設定する。

  6. それ以外の場合:

    1. jsBufferSourceArrayBuffer または SharedArrayBuffer オブジェクトであることを保証する。

    2. lengthjsBufferSource.[[ArrayBufferByteLength]] に設定する。

  7. IsDetachedBuffer(jsArrayBuffer) が true なら、空の バイト列 を返す。

  8. bytesバイト列 の新規インスタンスで、長さlength とする。

  9. i範囲 offset から offset + length − 1 までの各値について、bytes[ioffset] に GetValueFromBuffer(jsArrayBuffer, i, Uint8, true, Unordered) の結果を設定する。

  10. bytes を返す。

バイト長は、buffer source型 のインスタンス bufferSource に対して、以下の手順で得られる値である:
  1. jsBufferSourcebufferSource を JavaScript値に変換した結果とする。

  2. jsBufferSource が [[ViewedArrayBuffer]] 内部スロットを持つ場合は、 jsBufferSource.[[ByteLength]] を返す。

  3. jsBufferSource.[[ArrayBufferByteLength]] を返す。

下層バッファは、buffer source型 のインスタンス bufferSource に対して、以下の手順で得られる値である:
  1. bufferSourcebuffer型 のインスタンスであれば bufferSource を返す。

  2. jsBufferViewbufferSource を JavaScript値に変換した結果とする。

  3. jsBufferjsBufferView.[[ViewedArrayBuffer]] とする。

  4. IsSharedArrayBuffer(jsBuffer) が false の場合、 jsBufferArrayBuffer 型のIDL値に変換した結果を返す。

  5. jsBufferSharedArrayBuffer 型のIDL値に変換した結果を返す。

書き込むには、 バイト列 bytesbuffer型 のインスタンス arrayBuffer に、オプションで startingOffset(デフォルト0)を指定して、以下の手順を実行する:
  1. jsArrayBufferarrayBuffer を JavaScript値に変換した結果とする。

  2. bytes長さjsArrayBuffer.[[ArrayBufferByteLength]] − startingOffset であることを保証する。

  3. istartingOffset から startingOffset + bytes長さ − 1 までの範囲で、SetValueInBuffer(jsArrayBuffer, i, Uint8, bytes[i - startingOffset], true, Unordered) を実行する。

書き込むには、バイト列 bytesArrayBufferView view に、オプションで startingOffset(デフォルト0)を指定して、以下の手順を実行する:
  1. jsViewview を JavaScript値に変換した結果とする。

  2. bytes長さjsView.[[ByteLength]] − startingOffset であることを保証する。

  3. もし viewDataView でなければ、 bytes長さ要素サイズで割った余りが0であることを保証する。

  4. arrayBuffer を、jsView.[[ViewedArrayBuffer]] を ArrayBuffer 型のIDL値に変換した結果とする。

  5. bytes を arrayBuffer に startingOffset = jsView.[[ByteOffset]] + startingOffset で書き込む

buffer source型 のインスタンスに書き込む仕様文を書く際は、 下層データがスクリプトの著者や他のAPIによって予期しないタイミングで容易に変更されうるため、十分に注意しなければならない。 特に SharedArrayBuffer オブジェクトが関与する場合は注意が必要である。

共有されていない場合は、より推奨されるパターンとして、まず ArrayBuffer を転送して、他の変更と重複して書き込みが発生しないことを保証し、 必要に応じて新しい ArrayBuffer インスタンスを著者コードに渡すことができる。 または、バイト列のコピーを取得し、そのバイト列を変更し、 それを使って新しい ArrayBuffer または ArrayBufferView を作成して著者コードに渡すこともできる。

生成する ArrayBuffer バイト列 bytesrealm realm で:
  1. jsArrayBufferarrayBuffer を JavaScript値に変換した結果とする。

  2. ? DetachArrayBuffer(jsArrayBuffer) を実行する。

この操作は、 jsArrayBuffer が [[ArrayBufferDetachKey]] を持ち、その値が undefined でない場合(例えば WebAssembly.Memorybuffer 属性の場合)には例外を投げる。 [WASM-JS-API-1]

すでに 切り離されたバッファを切り離す操作は何も起こらない(no-op)である。

buffer source型 のインスタンス bufferSource切り離されたかどうかは、以下の手順で true かどうか判定する:
  1. jsArrayBufferbufferSource を JavaScript値に変換した結果とする。

  2. jsArrayBuffer が [[ViewedArrayBuffer]] 内部スロットを持つ場合は、 jsArrayBufferjsArrayBuffer.[[ViewedArrayBuffer]] に設定する。

  3. IsDetachedBuffer(jsArrayBuffer) の結果を返す。

buffer source型 のインスタンス bufferSource転送可能かどうかは、以下の手順で true かどうか判定する:
  1. jsArrayBufferbufferSource を JavaScript値に変換した結果とする。

  2. jsArrayBuffer が [[ViewedArrayBuffer]] 内部スロットを持つ場合は、 jsArrayBufferjsArrayBuffer.[[ViewedArrayBuffer]] に設定する。

  3. IsSharedArrayBuffer(jsArrayBuffer) が true なら、false を返す。

  4. IsDetachedBuffer(jsArrayBuffer) が true なら、false を返す。

  5. jsArrayBuffer.[[ArrayBufferDetachKey]] が undefined でないなら、false を返す。

  6. true を返す。

転送には、ArrayBuffer arrayBuffer に対して、オプションで レルム targetRealm を指定して以下の手順を行う:
  1. jsArrayBufferarrayBuffer を JavaScript値に変換した結果とする。

  2. IsDetachedBuffer(jsArrayBuffer) が false なら、TypeError を投げる

  3. arrayBufferDatajsArrayBuffer.[[ArrayBufferData]] とする。

  4. arrayBufferByteLengthjsArrayBuffer.[[ArrayBufferByteLength]] とする。

  5. ? DetachArrayBuffer(jsArrayBuffer) を実行する。

  6. targetRealm が指定されていない場合は、targetRealm現在のレルムとする。

  7. jsTransferred? AllocateArrayBuffer(targetRealm.[[Intrinsics]].[[%ArrayBuffer%]], 0) とする。

  8. jsTransferred.[[ArrayBufferData]] を arrayBufferData に設定する。

  9. jsTransferred.[[ArrayBufferByteLength]] を arrayBufferByteLength に設定する。

  10. jsTransferredArrayBuffer 型のIDL値に変換した結果を返す。

この操作は、以下の場合に例外を投げる:

3.2.27. フローズン配列 — FrozenArray<T>

フローズン配列型の値は、フローズンされた JavaScript Array オブジェクトの参照として表現される。

JavaScript値 V変換 されて、IDL FrozenArray<T>値になる。以下のアルゴリズムを実行する:

  1. values を、V を IDL 型 sequence<T>変換した結果とする。

  2. フローズン配列を作成して values から得られた結果を返す。

値の列 T から フローズン配列を作成するには、以下の手順を実行する:

  1. arrayT の値の列を JavaScript 値に変換した結果とする。

  2. ! SetIntegrityLevel(array, "frozen") を実行する。

  3. array を返す。

IDL の FrozenArray<T> 値をJavaScript 値に変換した結果は、 その IDL の FrozenArray<T> が表すオブジェクトと同じオブジェクトへの参照を表す Object 値である。

3.2.27.1. イテラブルからフローズン配列を作成する

イテラブル iterable とイテレーター取得関数 method を用いて、型 FrozenArray<T> のIDL値を作成するには、以下の手順を実行する:

  1. values を、iterablemethod から sequence を生成し、型は sequence<T> とすることで得られる結果とする。

  2. values から frozen array を生成した結果を返す。

3.2.28. オブザーバブル配列 — ObservableArray<T>

オブザーバブル配列型の値は、オブザーバブル配列エキゾチックオブジェクトによって表現される。

通常の変換アルゴリズムの代わりに、オブザーバブル配列型は 属性ゲッター属性セッターアルゴリズムの一部として特別な処理を持つ。

JavaScript バインディングでは、プラットフォームオブジェクトを表す JavaScript オブジェクトは、 observable array 型通常属性ごとに 対応する observable array exotic object を持つ。 これらは 属性定義アルゴリズムの一部として生成・管理される。

JavaScriptバインディングにおけるオブザーバブル配列属性の裏リストは、プラットフォームオブジェクト objと属性 attribute が与えられたとき、以下のアルゴリズムで返される リストである:
  1. Assert: objインターフェイスinterfaceを実装し、その 通常属性 attribute を持つこと。

  2. oaobj裏で支えるオブザーバブル配列エキゾチックオブジェクトattribute用)とする。

  3. oa.[[ProxyHandler]].[[BackingList]] を返す。

3.3. 拡張属性

この節では、JavaScriptバインディングに影響を与える 拡張属性 を定義する。

3.3.1. [AllowResizable]

[AllowResizable] 拡張属性buffer型に付与されている場合、対応するJavaScript ArrayBuffer または SharedArrayBuffer オブジェクトが可変サイズとなる新しいIDL型を作成する。

[AllowResizable] 拡張属性buffer view型に付与されていて、 [AllowShared] 拡張属性が付与されていない場合、buffer view型が固定長の ArrayBuffer だけでなく、可変サイズの ArrayBuffer でバックされることを許可する新しいIDL型を作成する。

[AllowResizable] 拡張属性と [AllowShared] 拡張属性 の両方がbuffer view型に付与されている場合、buffer view型が可変サイズの SharedArrayBuffer でもバックされることを許可する新しいIDL型を作成する。

[AllowResizable] 拡張属性は引数を取ってはならない

buffer source型 でない型は [AllowResizable] 拡張属性と関連付けられてはならない

JavaScript値からIDL buffer source型への変換規則については、§ 3.2.26 現行標準 Buffer source型を参照のこと。[AllowResizable] を使う場合の具体的な要件が記載されている。

両方の[AllowResizable] と [AllowShared] の使用例については § 3.3.2 [AllowShared] で参照のこと。

3.3.2. [AllowShared]

[AllowShared] 拡張属性buffer view型に付与されている場合、オブジェクトが SharedArrayBuffer でバックされることを許可する新しいIDL型を作成する(従来は ArrayBuffer のみ)。

[AllowShared] 拡張属性は引数を取ってはならない

buffer view型 でない型は [AllowShared] 拡張属性と関連付けられてはならない

JavaScript値からIDL buffer view型への変換規則については、§ 3.2.26 現行標準 Buffer source型を参照のこと。[AllowShared] を使う場合の具体的な要件が記載されている。

次の IDL断片は、 [AllowResizable] と [AllowShared] 拡張属性の組み合わせ例を示す:
[Exposed=Window]
interface ExampleBufferFeature {
  undefined writeInto(ArrayBufferView dest);
  undefined writeIntoResizable([AllowResizable] ArrayBufferView dest);
  undefined writeIntoShared([AllowShared] ArrayBufferView dest);
  undefined writeIntoSharedResizable([AllowResizable, AllowShared] ArrayBufferView dest);
};

この定義により、

3.3.3. [Clamp]

[Clamp] 拡張属性整数型に付与された場合、JavaScript Number をそのIDL型に変換するとき、範囲外の値は有効な値の範囲にクランプされる新しいIDL型が作成される。これは、剰余演算子(ToInt32ToUint32 など)を使う場合とは異なる動作となる。

[Clamp] 拡張属性は引数を取ってはならない

[Clamp] 拡張属性が付与された型は readonly 属性に出現してはならない。また、[Clamp] と [EnforceRange] を両方付与してはならない。整数型以外の型は [Clamp] 拡張属性と関連付けてはならない

各IDL整数型へのJavaScript値変換規則については § 3.2.4 整数型 を参照。[Clamp] 使用時の具体的要件が記載されている。

次の IDL断片では、3つの octet 引数を取る2つの操作が宣言されている。1つは3つ全ての引数に [Clamp] 拡張属性を付与し、もう1つは付与していない:

[Exposed=Window]
interface GraphicsContext {
  undefined setColor(octet red, octet green, octet blue);
  undefined setColorClamped([Clamp] octet red, [Clamp] octet green, [Clamp] octet blue);
};

setColorClampedoctet の範囲外の Number 値で呼び出すと、値は [0, 255] の範囲にクランプされる。

// GraphicsContextのインスタンスを取得。
var context = getGraphicsContext();

// 非[Clamp]版は ToUint8 を使い Number をoctetに変換する。setColor(255, 255, 1) と等価。
context.setColor(-1, 255, 257);

// 範囲外値でsetColorClampedを呼び出す。setColorClamped(0, 255, 255) と等価。
context.setColorClamped(-1, 255, 257);

3.3.4. [CrossOriginIsolated]

[CrossOriginIsolated] 拡張属性インターフェイス部分インターフェイスインターフェイスミクシン部分インターフェイスミクシンコールバックインターフェイス名前空間部分名前空間インターフェイスメンバーインターフェイスミクシンメンバー名前空間メンバー に付与された場合、その構成要素は 環境クロスオリジン分離機能 が true の場合のみ公開されることを示す。その他の構成要素には使ってはならない。

[CrossOriginIsolated] 拡張属性は引数を取ってはならない

[CrossOriginIsolated] が オーバーロードされた 操作に付与されている場合、全てのオーバーロードに付与しなければならない。

[CrossOriginIsolated] 拡張属性は、以下の両方に指定してはならない:

注: これは、メンバーに[CrossOriginIsolated] 拡張属性を付与しても、包含定義にも同じ属性が付与されている場合は公開範囲がさらに制限されることはないためである。

[CrossOriginIsolated] 拡張属性を持たない インターフェイスは、[CrossOriginIsolated] を指定した別のインターフェイスから継承してはならない。

次の IDL断片は、全てのコンテキストから実行可能な1つの操作と、クロスオリジン分離コンテキストからのみ実行可能な2つの操作を持つインターフェイスを定義する。

[Exposed=Window]
interface ExampleFeature {
  // これは全てのコンテキストで成功する。
  Promise <Result> calculateNotSoSecretResult();

  // 非分離コンテキストではこの操作は公開されない。そうしたコンテキストではExampleFeature.prototypeに"calculateSecretResult"プロパティは存在しない。
  [CrossOriginIsolated] Promise<Result> calculateSecretResult();

  // 同様に、この属性も非分離コンテキストでは公開されず、ExampleFeature.prototypeに"secretBoolean"プロパティは存在しない。
  [CrossOriginIsolated] readonly attribute boolean secretBoolean;
};

// HighResolutionTimerは非分離コンテキストでは公開されず、そのメンバーも公開されない。その場合 Window に "HighResolutionTimer" プロパティは存在しない。
[Exposed=Window, CrossOriginIsolated]
interface HighResolutionTimer {
  DOMHighResTimeStamp getHighResolutionTime();
};

// 下記のインターフェイスミクシンメンバーは、ホストインターフェイスが非分離属性を持つかどうかに関わらず、非分離コンテキストでは公開されない。その場合ExampleFeature.prototypeに"snap"プロパティは存在しない。
[CrossOriginIsolated]
interface mixin Snapshotable {
  Promise<boolean> snap();
};
ExampleFeature includes Snapshotable;

// 一方、下記のインターフェイスミクシンメンバーは、ホストインターフェイスが[CrossOriginIsolated]拡張属性を持たなければ非分離コンテキストでも公開される。つまり、非分離コンテキストではExampleFeature.prototypeに"log"プロパティが存在する。
interface mixin Loggable {
  Promise<boolean> log();
};
ExampleFeature includes Loggable;

3.3.5. [Default]

[Default] 拡張属性通常操作に付与されている場合、その操作が呼び出されたときに適切なデフォルトメソッド手順を実行することを示す。

[Default] 拡張属性は引数を取ってはならない

[Default] 拡張属性は、通常操作以外や、デフォルトメソッド手順が定義されていないものには使用してはならない。

例として、[Default]拡張属性は toJSON 通常操作に付与するのに適している:

[Exposed=Window]
interface Animal {
  attribute DOMString name;
  attribute unsigned short age;
  [Default] object toJSON();
};

[Exposed=Window]
interface Human : Animal {
  attribute Dog? pet;
  [Default] object toJSON();
};

[Exposed=Window]
interface Dog : Animal {
  attribute DOMString? breed;
};

JavaScriptバインディングでは、Animal, HumanDog(継承経由)オブジェクトに toJSON() メソッドが存在する:

// Humanのインスタンスを取得。
var alice = getHuman();

// 評価結果は以下のようなオブジェクト(この時点で pet はDogインスタンス):
//
// {
//   name: "Alice",
//   age: 59,
//   pet: Dog
// }
alice.toJSON();

// DogインターフェイスはデフォルトtoJSON手順を使用しないため"breed"は欠落:
//
// {
//   name: "Tramp",
//   age: 6
// }
alice.pet.toJSON();

// 以下のような文字列になる:
// '{"name":"Alice","age":59,"pet":{"name":"Tramp","age":6}}'
JSON.stringify(alice);

3.3.6. [EnforceRange]

[EnforceRange] 拡張属性整数型に付与されている場合、JavaScript Number をそのIDL型に変換するとき、範囲外の値は剰余演算子(ToInt32ToUint32 など)を使って有効値に変換せず、例外を投げるIDL型が作成される。この時Numberはゼロ方向に丸めてから範囲判定される。

[EnforceRange] 拡張属性は引数を取ってはならない

[EnforceRange] 拡張属性が付与された型は readonly 属性に出現してはならない。また、[Clamp] と [EnforceRange] を両方付与してはならない。整数型以外の型は [EnforceRange] 拡張属性と関連付けてはならない

各IDL整数型へのJavaScript値変換規則については § 3.2 JavaScript型マッピング を参照。[EnforceRange] 使用時の具体的要件が記載されている。

次の IDL断片では、3つの octet 引数を取る2つの操作が宣言されている。1つは3つ全ての引数に [EnforceRange] 拡張属性を付与し、もう1つは付与していない:

[Exposed=Window]
interface GraphicsContext {
  undefined setColor(octet red, octet green, octet blue);
  undefined setColorEnforcedRange([EnforceRange] octet red, [EnforceRange] octet green, [EnforceRange] octet blue);
};

IDLのJavaScript実装では、setColorEnforcedRangeoctet の範囲外の Number 値で呼び出すと、例外が投げられる。

// GraphicsContextのインスタンスを取得。
var context = getGraphicsContext();

// 非[EnforceRange]版は ToUint8 を使い Number をoctetに変換する。setColor(255, 255, 1) と等価。
context.setColor(-1, 255, 257);

// setColorEnforcedRangeを呼び出すと、値はゼロ方向に丸められる。setColor(0, 255, 255) と等価。
context.setColorEnforcedRange(-0.9, 255, 255.2);

// 以下は例外(TypeError)が投げられる。丸め後も範囲外のため。
context.setColorEnforcedRange(-1, 255, 256);

3.3.7. [Exposed]

[Exposed] 拡張属性インターフェイス部分インターフェイスインターフェイスミクシン部分インターフェイスミクシンコールバックインターフェイス名前空間部分名前空間、 または個々の インターフェイスメンバーインターフェイスミクシンメンバー名前空間メンバー に付与された場合、その構成要素が指定したグローバルインターフェイス群で公開されることを示す。

[Exposed] 拡張属性識別子識別子リスト、 または ワイルドカードのいずれかを取る必要がある。 各識別子は何らかの インターフェイスグローバル名であり、重複してはならない。

自身の公開セットは、 識別子のセットまたは特別な値 * であり、次のように定義される:

[Exposed] 拡張属性識別子 I を取る場合

自身の公開セットセット « I » である。

[Exposed] 拡張属性識別子リスト I を取る場合

自身の公開セットセット I である。

[Exposed] 拡張属性ワイルドカードを取る場合

自身の公開セット* である。

[Exposed=*] の使用には注意が必要である。 APIが重要な新機能を公開しない場合のみ適している。 APIが環境によって制限・無効化される可能性がある場合は、グローバルを明示的に列挙する方が望ましい。

公開セットの共通部分は、構成要素 C と interface-or-null H に対し次のように定義される:

  1. Assert: Cインターフェイスメンバーインターフェイスミクシンメンバー名前空間メンバー部分インターフェイス部分インターフェイスミクシン部分名前空間インターフェイスミクシンであること。

  2. Assert: Hインターフェイスまたはnullである。

  3. H が null なら、C自身の公開セット を返す。

  4. C自身の公開セット* なら、H公開セット を返す。

  5. H公開セット* なら、C自身の公開セット を返す。

  6. C自身の公開セットH公開セット共通部分を返す。

構成要素 C公開セットを取得するには、以下の手順を実行する:
  1. Assert: Cインターフェイスコールバックインターフェイス名前空間インターフェイスメンバーインターフェイスミクシンメンバー、または名前空間メンバーであること。

  2. HCインターフェイスミクシンメンバーなら ホストインターフェイス、そうでなければ null とする。

  3. Cインターフェイスメンバーインターフェイスミクシンメンバー名前空間メンバーなら:

    1. [Exposed] 拡張属性C に指定されていれば、公開セットの共通部分(C, H) を返す。

    2. C を元の インターフェイス部分インターフェイスインターフェイスミクシン部分インターフェイスミクシン名前空間部分名前空間C に設定する。

  4. C部分インターフェイス部分インターフェイスミクシン部分名前空間なら:

    1. [Exposed] 拡張属性C に指定されていれば、公開セットの共通部分(C, H) を返す。

    2. C を元の インターフェイスインターフェイスミクシン名前空間の定義の C に設定する。

  5. Cインターフェイスミクシンなら:

    1. H は null ではないこと。

    2. [Exposed] 拡張属性C に指定されていれば、公開セットの共通部分(C, H) を返す。

    3. CH に設定する。

  6. Cインターフェイスコールバックインターフェイス名前空間であること。

  7. [Exposed] 拡張属性C に指定されていること。

  8. C自身の公開セットを返す。

[Exposed] が オーバーロードされた 操作に指定されている場合、全てのオーバーロードに同一に指定されなければならない。

[Exposed] 拡張属性は インターフェイスメンバーインターフェイスミクシンメンバー名前空間メンバー部分インターフェイス部分インターフェイスミクシン部分名前空間定義の両方に指定してはならない。

注: 部分インターフェイス、部分インターフェイスミクシン、部分名前空間に [Exposed] 拡張属性を付与するのは、各メンバーに個別に付与する省略表現であるためである。

[Exposed] が 部分インターフェイスまたは部分名前空間に指定されている場合、その 自身の公開セットは 元の インターフェイスまたは 名前空間公開セットの部分集合でなければならない。

[Exposed] が インターフェイスメンバーまたは名前空間メンバーに指定されている場合、その メンバー公開セットは 所属する インターフェイスまたは名前空間公開セットの部分集合でなければならない。

[Exposed] が 部分インターフェイスミクシンと元の インターフェイスミクシンの両方に指定されている場合、部分インターフェイスミクシンの 自身の公開セットはインターフェイスミクシンの 自身の公開セットの部分集合でなければならない。

[Exposed] が インターフェイスミクシンメンバーインターフェイスミクシンの両方に指定されている場合、そのインターフェイスミクシンメンバーの 自身の公開セットは インターフェイスミクシンの 自身の公開セットの部分集合でなければならない。

インターフェイス X が他のインターフェイス Y継承している場合、X公開セットY公開セットの部分集合でなければならない。

注: インターフェイスミクシンは複数の インターフェイスinclude できるので、そのメンバーの 公開セットは それを include した インターフェイスに依存する関数となる。 [Exposed] 拡張属性が インターフェイスミクシンメンバー、部分インターフェイスミクシン、インターフェイスミクシンに付与されていれば、そのメンバーの 公開セットは該当構成要素の 自身の公開セットホストインターフェイス公開セットの共通部分となる。そうでなければホストインターフェイスの 公開セットとなる。

インターフェイスコールバックインターフェイス名前空間、 またはメンバー construct が 与えられた レルム realm公開されているかどうかは、以下の手順で true になるか判定する:
  1. construct公開セット* でなく、 realm.[[GlobalObject]] が construct公開セット内の インターフェイスを実装していなければ false を返す。

  2. realm設定オブジェクトセキュアコンテキストでなく、かつ construct が [SecureContext] で条件付き公開されていれば false を返す。

  3. realm設定オブジェクトクロスオリジン分離機能が false で、construct が [CrossOriginIsolated] で条件付き公開されていれば false を返す。

  4. true を返す。

インターフェイスコールバックインターフェイス名前空間、 またはメンバー construct が 与えられた 拡張属性 exposure condition条件付き公開されているかどうかは、以下の手順で true になるか判定する:
  1. Assert: constructインターフェイスコールバックインターフェイス名前空間インターフェイスメンバーインターフェイスミクシンメンバー名前空間メンバーであること。

  2. Hconstructインターフェイスミクシンメンバーなら ホストインターフェイス、そうでなければ null とする。

  3. constructインターフェイスメンバーインターフェイスミクシンメンバー名前空間メンバーなら:

    1. exposure condition 拡張属性construct に指定されていれば true を返す。

    2. そうでなければ construct を元の インターフェイス部分インターフェイスインターフェイスミクシン部分インターフェイスミクシン名前空間部分名前空間construct に設定する。

  4. construct部分インターフェイス部分インターフェイスミクシン部分名前空間なら:

    1. exposure condition 拡張属性construct に指定されていれば true を返す。

    2. そうでなければ construct を元の インターフェイスインターフェイスミクシン名前空間の定義の construct に設定する。

  5. constructインターフェイスミクシンなら:

    1. exposure condition 拡張属性construct に指定されていれば true を返す。

    2. そうでなければ constructH に設定する。

  6. constructインターフェイスコールバックインターフェイス名前空間であること。

  7. exposure condition 拡張属性construct に指定されていれば true を返す。

  8. そうでなければ false を返す。

注: JavaScriptグローバルオブジェクトの関連設定オブジェクトがセキュアコンテキストやクロスオリジン分離機能の有無を後から変更できないため、インターフェイスやインターフェイスメンバーのプロパティ作成は初期オブジェクトが作成される時点で一度決定できる。

詳細は § 3.7 インターフェイス§ 3.7.5 定数§ 3.7.6 属性§ 3.7.7 操作 を参照。[Exposed] 使用時の具体的な要件が記載されている。

[Exposed] は、インターフェイスコールバックインターフェイス名前空間、または個々のインターフェイスミクシン名前空間メンバーが ワーカー、WorkletWindow、 あるいはその組み合わせで利用可能かを制御するために使うことを意図している。

以下のIDL断片はその使い方例である:

[Exposed=Window, Global=Window]
interface Window {
  // ...
};

// SharedWorkerGlobalScope と DedicatedWorkerGlobalScope の両方に同じ識別子 Worker を使うことで、[Exposed] 拡張属性で両方を一度に指定できる。
[Exposed=Worker, Global=Worker]
interface SharedWorkerGlobalScope : WorkerGlobalScope {
  // ...
};

[Exposed=Worker, Global=Worker]
interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
  // ...
};

// Dimensions はワーカーでもメインスレッドでも利用できる。
[Exposed=(Window,Worker)]
interface Dimensions {
  constructor(double width, double height);
  readonly attribute double width;
  readonly attribute double height;
};

// WorkerNavigator はワーカーのみで利用可能。ワーカーのグローバルスコープで WorkerNavigator を評価するとインターフェイスオブジェクトが得られるが、メインスレッドでは ReferenceError となる。
[Exposed=Worker]
interface WorkerNavigator {
  // ...
};

// Node はメインスレッドのみで利用可能。ワーカーのグローバルスコープで Node を評価すると ReferenceError となる。
[Exposed=Window]
interface Node {
  // ...
};

// MathUtils はワーカーでもメインスレッドでも利用できる。
[Exposed=(Window,Worker)]
namespace MathUtils {
  double someComplicatedFunction(double x, double y);
};

// WorkerUtils はワーカーのみで利用可能。ワーカーのグローバルスコープで WorkerUtils を評価すると名前空間オブジェクトが得られるが、メインスレッドでは ReferenceError となる。
[Exposed=Worker]
namespace WorkerUtils {
  undefined setPriority(double x);
};

// NodeUtils はメインスレッドのみで利用可能。ワーカーのグローバルスコープで NodeUtils を評価すると ReferenceError となる。
[Exposed=Window]
namespace NodeUtils {
  DOMString getAllText(Node node);
};

3.3.8. [Global]

[Global] 拡張属性インターフェイスに付与されている場合、このインターフェイスを実装するオブジェクトが レルムのグローバルオブジェクトとして使われることを示す。

[Global] 拡張属性はあわせて グローバル名インターフェイスに定義する:

[Global] 拡張属性識別子を取る場合

« 指定された識別子 »

[Global] 拡張属性識別子リストを取る場合

識別子リスト

[Global] 拡張属性は上記いずれかの形式でなければならない。

注: グローバル名インターフェイスを [Exposed] 拡張属性で参照するために使うことができる識別子である。 一つのグローバル名は複数の異なるグローバルインターフェイスで共有でき、[Exposed]を使って一度に全てに公開できる。 例えば「Worker」は複数種のスレッド関連グローバルインターフェイスを指すために使われている。

こうしたグローバルインターフェイスは、プロトタイプチェーンの構造や インターフェイスメンバーに対応するプロパティの反映方法が他のインターフェイスと異なる。具体的には:

  1. 名前付きプロパティは、オブジェクト自身ではなくプロトタイプチェーン上の 名前付きプロパティオブジェクト に公開される。

  2. インターフェイスメンバーインターフェイスから オブジェクト自身のプロパティとなり、 インターフェイスプロトタイプオブジェクトのプロパティにはならない。

全てのレルムグローバルプロトタイプチェーンが可変かどうかというブール値を持つ。 これはレルム生成時に設定され、その後は変更できない。デフォルトは false。

これにより ShadowRealm グローバルは可変プロトタイプを持てる。

名前付きプロパティをプロトタイプチェーン上のオブジェクトに置く理由は、変数宣言や裸の代入で グローバルオブジェクト自身のプロパティが名前付きプロパティを隠す(シャドウする)ためである。

インターフェイスメンバーに対応するプロパティをオブジェクト自身に置くことで、以下のような機能検出コードが機能する:

var indexedDB = window.indexedDB || window.webkitIndexedDB ||
                window.mozIndexedDB || window.msIndexedDB;

var requestAnimationFrame = window.requestAnimationFrame ||
                            window.mozRequestAnimationFrame || ...;

JavaScriptの変数宣言の扱いにより、上記コードは window.indexedDBwindow.requestAnimationFrame の評価結果が undefined となる。これはシャドウされる変数プロパティが代入の前に既に作成されているため。

[Global] 拡張属性インターフェイスに使われた場合:

[Global] が 部分インターフェイス 定義で指定された場合、その部分インターフェイスは 名前付きプロパティゲッターを定義する部分でなければならない。

[Global] 拡張属性は 同じインターフェイスで 同一レルム内で複数のオブジェクトが実装できる場合には使ってはならない。

注: これは名前付きプロパティオブジェクトがプロトタイプチェーン上にあり、 複数のオブジェクトの名前付きプロパティが同じ継承元オブジェクト上に公開されるのは意味がないため。

インターフェイスが[Global] 拡張属性で宣言された場合、 インターフェイス全体で同じ識別子を持つ メンバーが複数あってはならない。 また、stringifier反復宣言非同期反復宣言maplike宣言setlike宣言 も複数あってはならない。

注: これはインターフェイスの全てのメンバーが、インターフェイスを実装するオブジェクト上に直接配置されるためである。

名前付きプロパティの要件については § 3.7.4 名前付きプロパティオブジェクト§ 3.7.5 定数§ 3.7.6 属性§ 3.7.7 操作 を参照。

Window インターフェイスは Window オブジェクト上にフレームをプロパティとして公開する。 Window オブジェクトは JavaScriptグローバルオブジェクトも兼ねるため、変数宣言や名前付きプロパティへの代入によって それらの値が置き換えられることになる。属性への変数宣言では既存プロパティが置き換えられることはない。

[Exposed=Window, Global=Window]
interface Window {
  getter any (DOMString name);
  attribute DOMString name;
  // ...
};

以下のHTML文書は Window オブジェクトの名前付きプロパティがシャドウされる様子と、 属性のプロパティは同名の変数宣言でも置き換えられないことを示している:

<!DOCTYPE html>
<title>Window上の変数宣言と代入</title>
<iframe name=abc></iframe>
<!-- 名前付きプロパティのシャドウ -->
<script>
  window.abc;    // iframe の Window オブジェクトを評価。
  abc = 1;       // 名前付きプロパティをシャドウ。
  window.abc;    // 評価結果は 1。
</script>

<!-- IDL属性用プロパティの保持 -->
<script>
  Window.prototype.def = 2;         // プロトタイプにプロパティを追加。
  window.hasOwnProperty("length");  // 評価結果 true。
  length;                           // 評価結果 1。
  def;                              // 評価結果 2。
</script>
<script>
  var length;                       // 変数宣言は既存プロパティを変更しない。
  length;                           // 評価結果 1。
  var def;                          // 変数宣言でシャドウプロパティを作成。
  def;                              // 評価結果 undefined。
</script>

3.3.9. [NewObject]

[NewObject] 拡張属性通常 または static 操作に付与されている場合、 その操作を呼び出すと、必ず新しく生成されたオブジェクトへの参照が返されることを示す。

[NewObject] 拡張属性は 引数を取ってはならない

[NewObject] 拡張属性は 通常または static 操作で、 戻り値型インターフェイス型または Promise型 以外には使ってはならない。

例えば、この拡張属性は createElement() 操作(Documentインターフェイス)に付与するのが適切である。 この操作は呼び出すたびに必ず新しいオブジェクトが返されるためである。[DOM]

[Exposed=Window]
interface Document : Node {
  [NewObject] Element createElement(DOMString localName);
  // ...
};

3.3.10. [PutForwards]

[PutForwards] 拡張属性が、型が インターフェイス型readonly 通常属性宣言に付与されている場合、 その属性への代入は特定の動作になることを示す。 すなわち、代入は(拡張属性の引数で指定された)オブジェクトの属性への代入として「転送」される。

[PutForwards] 拡張属性は 識別子を取らなければならない。 前提として:

この場合、J には N という識別子属性 B が宣言されていなければならない。 Iを実装するオブジェクトの属性Aに値を代入すると、その値はAが参照するオブジェクトの属性Bに代入される。

[PutForwards]でアノテートされた属性はチェーン可能である。すなわち、[PutForwards]拡張属性を持つ属性が、同じくその拡張属性を持つ属性を参照することができる。 転送代入チェーンに循環(サイクル)があってはならない。循環とは、転送代入のチェーンをたどったとき、同じインターフェイス上の同じ属性に2回以上到達する場合である。

[PutForwards]拡張属性付き属性は、[LegacyLenientSetter]や [Replaceable]拡張属性と同時に宣言してはならない。

[PutForwards]拡張属性は 属性readonlyでない場合には使ってはならない。

[PutForwards]拡張属性は static属性には使ってはならない。

[PutForwards]拡張属性は 名前空間で宣言された属性には使ってはならない。

実装方法については 属性の節を参照。

次のIDL断片は、名前と人のインターフェイスを定義している。 Personインターフェイスのname属性には [PutForwards]拡張属性が付与されており、 この属性への代入がPersonオブジェクトのfull属性への代入になることを示している:

[Exposed=Window]
interface Name {
  attribute DOMString full;
  attribute DOMString family;
  attribute DOMString given;
};

[Exposed=Window]
interface Person {
  [PutForwards=full] readonly attribute Name name;
  attribute unsigned short age;
};

JavaScriptバインディングでは、以下のようにnameプロパティへ代入できる:

var p = getPerson();           // Personインスタンスを取得。

p.name = 'John Citizen';       // この文...
p.name.full = 'John Citizen';  // ...は上と同じ動作。

3.3.11. [Replaceable]

[Replaceable] 拡張属性readonly 通常属性に付与されている場合、 プラットフォームオブジェクト上でそのプロパティに代入を行うと 同じ名前の独自プロパティがそのオブジェクト上に生成され、代入された値がセットされる。 このプロパティはインターフェイスプロトタイプオブジェクト上の属性に対応するアクセサプロパティをシャドウする。

[Replaceable] 拡張属性は 引数を取ってはならない

[Replaceable] 拡張属性付き属性は、 [LegacyLenientSetter]や [PutForwards]拡張属性と同時に宣言してはならない。

[Replaceable]拡張属性は 属性readonlyでない場合には使ってはならない。

[Replaceable]拡張属性は static属性には使ってはならない。

[Replaceable]拡張属性は 名前空間で宣言された属性には使ってはならない。

詳細要件については § 3.7.6 属性 を参照。

次のIDL断片は、 カウンタをインクリメントする操作と、初期値0のカウンタ値を公開する属性を持つインターフェイスを定義する:

[Exposed=Window]
interface Counter {
  [Replaceable] readonly attribute unsigned long value;
  undefined increment();
};

Counterを実装するプラットフォームオブジェクト上でvalueプロパティに代入すると、 属性に対応するプロパティがシャドウされる:

var counter = getCounter();                              // Counterインスタンスを取得。
counter.value;                                           // 0。

counter.hasOwnProperty("value");                         // false。
Object.getPrototypeOf(counter).hasOwnProperty("value");  // true。

counter.increment();
counter.increment();
counter.value;                                           // 2。

counter.value = 'a';                                     // Counter::valueとは無関係のプロパティでシャドウ。
                                                         // 

counter.hasOwnProperty("value");                         // true。

counter.increment();
counter.value;                                           // 'a'。

delete counter.value;                                    // 元のプロパティが現れる。
counter.value;                                           // 3。

3.3.12. [SameObject]

[SameObject] 拡張属性readonly 属性に付与されている場合、 その属性の値を取得するたびに、常に同じ値が返されなければならないことを示す。

[SameObject] 拡張属性は 引数を取ってはならない

[SameObject]拡張属性は、 readonly 属性で型が インターフェイス型 または object 以外には使ってはならない。

例えば、この拡張属性は implementation 属性(Documentインターフェイス)に付与するのが適切である。 同じDocumentオブジェクトに対しては常に同じオブジェクトが返されるためである。[DOM]

[Exposed=Window]
interface Document : Node {
  [SameObject] readonly attribute DOMImplementation implementation;
  // ...
};

3.3.13. [SecureContext]

[SecureContext] 拡張属性インターフェイス部分インターフェイスインターフェイスミクシン部分インターフェイスミクシンコールバックインターフェイス名前空間部分名前空間インターフェイスメンバーインターフェイスミクシンメンバー名前空間メンバー に付与された場合、その構成要素は 安全なコンテキストでのみ公開されることを示す。 [SecureContext] 拡張属性は他の構成要素に使ってはならない。

[SecureContext] 拡張属性は、引数を取ってはならない

[SecureContext] が オーバーロードされた 操作に付与されている場合、全てのオーバーロードに付与しなければならない。

[SecureContext] 拡張属性は、以下の両方に指定してはならない:

注: これは、メンバーに[SecureContext]拡張属性を付与しても、包含定義にも同じ属性が付与されている場合は公開範囲がさらに制限されることはないためである。

[SecureContext] 拡張属性を持たない インターフェイスは、[SecureContext]を指定した別のインターフェイスから継承してはならない。

[SecureContext]は [CrossOriginIsolated]で条件付き公開される構成要素には指定してはならない。 (この場合は冗長であり、クロスオリジン分離環境は必ず安全なコンテキストでもあるため。)

次のIDL断片は、 全てのコンテキストから実行可能な操作ひとつと、安全なコンテキストからのみ実行可能な操作を2つ持つインターフェイスを定義する:

[Exposed=Window]
interface ExampleFeature {
  // これは全てのコンテキストで成功する。
  Promise <Result> calculateNotSoSecretResult();

  // 非安全コンテキストではこの操作は公開されない。そうしたコンテキストではExampleFeature.prototypeに"calculateSecretResult"プロパティは存在しない。
  [SecureContext] Promise<Result> calculateSecretResult();

  // 同様に、この属性も非安全コンテキストでは公開されず、ExampleFeature.prototypeに"secretBoolean"プロパティは存在しない。
  [SecureContext] readonly attribute boolean secretBoolean;
};

// HeartbeatSensorは非安全コンテキストでは公開されず、そのメンバーも公開されない。その場合 Window に "HeartbeatSensor" プロパティは存在しない。
[Exposed=Window, SecureContext]
interface HeartbeatSensor {
  Promise<float> getHeartbeatsPerMinute();
};

// 下記のインターフェイスミクシンメンバーは、ホストインターフェイスが安全属性を持つかどうかに関わらず、非安全コンテキストでは公開されない。その場合ExampleFeature.prototypeに"snap"プロパティは存在しない。
[SecureContext]
interface mixin Snapshotable {
  Promise<boolean> snap();
};
ExampleFeature includes Snapshotable;

// 一方、下記のインターフェイスミクシンメンバーは、ホストインターフェイスが[SecureContext]拡張属性を持たなければ非安全コンテキストでも公開される。つまり、非安全コンテキストではExampleFeature.prototypeに"log"プロパティが存在する。
interface mixin Loggable {
  Promise<boolean> log();
};
ExampleFeature includes Loggable;

3.3.14. [Unscopable]

[Unscopable] 拡張属性通常属性または通常操作に付与されている場合、 そのインターフェイスメンバーを持つインターフェイスを実装するオブジェクトは、そのプロパティ名を基底オブジェクトとするオブジェクト環境記録に含めない。 その結果、プロパティ名に一致する裸の識別子はwith文内ではそのプロパティに解決されない。 これはプロパティ名をインターフェイスプロトタイプオブジェクト%Symbol.unscopables% プロパティ値に含めることで実現される。

[Unscopable] 拡張属性は 引数を取ってはならない。

[Unscopable] 拡張属性は 通常属性または通常操作以外には使ってはならない。

[Unscopable] 拡張属性は 名前空間で宣言された属性に使ってはならない。

詳細要件については § 3.7.3 インターフェイスプロトタイプオブジェクト を参照。

例として、下記のIDL:

[Exposed=Window]
interface Thing {
  undefined f();
  [Unscopable] g();
};

fプロパティはwith文内の裸の識別子として参照できるが、gプロパティは参照できない:

var thing = getThing();  // Thingのインスタンス
with (thing) {
  f;                     // Functionオブジェクトとして評価。
  g;                     // ReferenceErrorが投げられる。
}

3.4. レガシー拡張属性

この節では、JavaScriptバインディングに影響を与える拡張属性のうち、§ 3.3 拡張属性とは異なり、 現行標準Webプラットフォーム機能のためだけに存在するものを定義する。 仕様書では、レガシーAPIの動作を定義するために必要な場合以外は使用しないこと。

これらの拡張属性の使用理由がある場合は、事前に issueを提出 して議論することを強く推奨する。

3.4.1. [LegacyFactoryFunction]

この機能の代わりに、インターフェイスにコンストラクタ操作を持たせること。

[LegacyFactoryFunction] 拡張属性インターフェイスに付与されている場合、 JavaScriptグローバルオブジェクトに指定された名前のプロパティができ、その値はインターフェイスを実装するオブジェクトを生成できる関数となる。 同じインターフェイスに複数の[LegacyFactoryFunction]拡張属性を付与できる。

[LegacyFactoryFunction] 拡張属性は 名前付き引数リストを取らなければならない。 identifierが「=」の後に出現した場合、それが[LegacyFactoryFunction]の 識別子となる。 インターフェイス上の各[LegacyFactoryFunction]拡張属性について、 指定された引数を上述のプロパティ値であるコンストラクタ関数に渡すことで インターフェイスを実装するオブジェクトを生成できる。

レガシーファクトリ関数の識別子は、他のインターフェイスの[LegacyFactoryFunction]拡張属性で使われているものと重複してはならず、 このインターフェイスや他のインターフェイスの[LegacyWindowAlias]拡張属性の識別子や、 インターフェイスオブジェクトidentifier、および 予約識別子とも重複してはならない。

[LegacyFactoryFunction]と[Global]拡張属性は同じインターフェイスに同時に指定してはならない。

レガシーファクトリ関数の実装詳細については § 3.7.2 レガシーファクトリ関数 を参照。

次のIDLは[LegacyFactoryFunction]拡張属性を使うインターフェイスを定義する:

[Exposed=Window,
 LegacyFactoryFunction=Audio(DOMString src)]
interface HTMLAudioElement : HTMLMediaElement {
  // ...
};

このインターフェイスをサポートするJavaScript実装ではHTMLAudioElementオブジェクトをAudio関数で生成できる:

typeof Audio;                   // 'function'。

var a2 = new Audio('a.flac');   // 引数1つのコンストラクタでHTMLAudioElementを生成。

追加のレガシー仕様として、これらのファクトリ関数はprototypeプロパティが元のインターフェイスのprototypeと等しくなる:

console.assert(Audio.prototype === HTMLAudioElement.prototype);

3.4.2. [LegacyLenientSetter]

[LegacyLenientSetter] 拡張属性readonly 通常属性に付与されている場合、 その属性のアクセサプロパティには何もしない(no-op)セッターが生成される。 これにより、strict modeでそのプロパティに誤って代入しても例外が投げられず無視されるようになる。

strict mode下で、IDL属性をポリフィルしようとプロパティへ代入した結果、プロパティが既に存在する場合に例外が投げられてページが壊れる事例が観測されている。 [LegacyLenientSetter]がないと、ブラウザはその機能を実装できなくなる場合がある。

[LegacyLenientSetter]拡張属性は 引数を取ってはならないreadonly 通常属性以外には使ってはならない。

[LegacyLenientSetter]拡張属性付き属性は、 [PutForwards]や [Replaceable]拡張属性と同時に宣言してはならない。

[LegacyLenientSetter]拡張属性は 名前空間で宣言された属性に使ってはならない。

実装方法については 属性の節を参照。

次のIDLは[LegacyLenientSetter]拡張属性を使うインターフェイスを定義する:

[Exposed=Window]
interface Example {
  [LegacyLenientSetter] readonly attribute DOMString x;
  readonly attribute DOMString y;
};

このインターフェイスをサポートするJavaScript実装では、xに対応するアクセサプロパティにはno-opのセッターがあり、strict modeでも代入しても無視される:

"use strict";

var example = getExample();  // Exampleのインスタンスを取得。

// strict modeでもセッターがno-opなので問題なし。
example.x = 1;

// strict modeでセッターがないためTypeErrorが投げられる。
example.y = 1;

3.4.3. [LegacyLenientThis]

[LegacyLenientThis] 拡張属性通常属性に付与されている場合、 その属性のgetterやsetterを、属性が属するインターフェイス実装していないオブジェクトで呼び出しても無視される。

[LegacyLenientThis] 拡張属性は引数を取ってはならないstatic属性には使ってはならない。

[LegacyLenientThis] 拡張属性は、名前空間で宣言された属性には使ってはならない。

実装方法については 属性の節を参照。

次のIDLは[LegacyLenientThis]拡張属性を使うインターフェイスを定義する:

[Exposed=Window]
interface Example {
  [LegacyLenientThis] attribute DOMString x;
  attribute DOMString y;
};

このインターフェイスをサポートするJavaScript実装では、xに対応するアクセサプロパティのgetter/setterはExampleオブジェクト以外でも呼び出せる:

var example = getExample();  // Exampleのインスタンスを取得。
var obj = { };

// 問題なし。
example.x;

// Exampleオブジェクト以外で呼び出しても無視される([LegacyLenientThis]使用時)。
Object.getOwnPropertyDescriptor(Example.prototype, "x").get.call(obj);

// Example.prototype自体でも無視される。
Example.prototype.x;

// y属性はTypeErrorになる(Example.prototypeはExampleオブジェクトではないため)。
Example.prototype.y;

3.4.4. [LegacyNamespace]

この機能の代わりに、インターフェイス名は特定の接頭辞で始める命名規則を使い、識別子にドットを入れず表現できる。

[LegacyNamespace] 拡張属性インターフェイスに付与されている場合、 インターフェイスオブジェクトがグローバルオブジェクトのプロパティとしてではなく、拡張属性引数で指定された名前空間のプロパティとして作成される。

[LegacyNamespace] 拡張属性は識別子を取らなければならない。 この識別子は名前空間定義の識別子でなければならない。

[LegacyNamespace]と[LegacyNoInterfaceObject]拡張属性は同じインターフェイスに同時に指定してはならない。

名前空間上にインターフェイスを公開する詳細については § 3.13.1 名前空間オブジェクト を参照。

次のIDL断片は、 名前空間と[LegacyNamespace]を使うインターフェイスを定義する:
namespace Foo { };

[LegacyNamespace=Foo]
interface Bar {
  constructor();
};

上記名前空間・インターフェイスをサポートするJavaScript実装では、Barコンストラクタは次のようにアクセスできる:

var instance = new Foo.Bar();

3.4.5. [LegacyNoInterfaceObject]

[LegacyNoInterfaceObject] 拡張属性インターフェイスに付与されている場合、 JavaScriptバインディングでそのインターフェイスのインターフェイスオブジェクトは作成されない。

[LegacyNoInterfaceObject] 拡張属性は引数を取ってはならない。

[LegacyNoInterfaceObject] 拡張属性は、 コンストラクタやstatic操作を持つインターフェイスには使ってはならない。

[LegacyNoInterfaceObject]拡張属性を持たないインターフェイスは、 [LegacyNoInterfaceObject]拡張属性を持つインターフェイスから継承してはならない。

詳細要件は § 3.7 インターフェイス を参照。

次のIDL断片は、インターフェイスオブジェクトがJavaScriptグローバルオブジェクトに公開されるものと、公開されないものの2つのインターフェイスを定義する:

[Exposed=Window]
interface Storage {
  undefined addEntry(unsigned long key, any value);
};

[Exposed=Window,
 LegacyNoInterfaceObject]
interface Query {
  any lookupEntry(unsigned long key);
};

このIDLのJavaScript実装では、Storageのプロトタイプは操作できるが、Queryのプロトタイプは操作できない:

typeof Storage;                        // "object"。

// Storage.addEntryにalert()を追加。
var fn = Storage.prototype.addEntry;
Storage.prototype.addEntry = function(key, value) {
  alert('Calling addEntry()');
  return fn.call(this, key, value);
};

typeof Query;                          // "undefined"。

var fn = Query.prototype.lookupEntry;  // 例外(Queryは定義されていない)

3.4.6. [LegacyNullToEmptyString]

[LegacyNullToEmptyString] 拡張属性DOMString またはUSVString型に付与されている場合、 JavaScriptのnullをIDL型に変換する際、デフォルトの"null"ではなく空文字列に変換される新しいIDL型が作成される。

[LegacyNullToEmptyString] 拡張属性は DOMStringまたはUSVString型以外には関連付けてはならない

注: DOMString?であっても[LegacyNullToEmptyString]は使えない。nullはその型の有効な値だから。

詳細要件については § 3.2.10 DOMString を参照。

次のIDL断片は、 拡張属性付き型の属性と、拡張属性付き型の引数を持つ操作を持つインターフェイスを定義する:
[Exposed=Window]
interface Dog {
  attribute DOMString name;
  attribute [LegacyNullToEmptyString] DOMString owner;

  boolean isMemberOfBreed([LegacyNullToEmptyString] DOMString breedName);
};

このインターフェイスを実装するJavaScriptでは、DogのownerプロパティやisMemberOfBreedの引数にnullを渡すと、"null"ではなく空文字列になる:

var d = getDog();         // Dogインターフェイスのプラットフォームオブジェクト。

d.name = null;            // .nameへの代入は文字列"null"になる。
d.owner = null;           // .ownerへの代入は空文字列になる。
d.isMemberOfBreed(null);  // 引数は空文字列になる。

3.4.7. [LegacyOverrideBuiltIns]

[LegacyOverrideBuiltIns] 拡張属性インターフェイスに付与されている場合、 そのインターフェイスを実装するレガシープラットフォームオブジェクトでは、全てのサポートプロパティ名に対応するプロパティが必ずオブジェクト上に現れる。 これは、他のプロパティやプロトタイプチェーン上のプロパティがあっても、名前付きプロパティが常にそれらをシャドウすることを意味する。 通常は、名前付きプロパティは、オブジェクトやプロトタイプチェーン上に同名プロパティがない場合にのみ公開される。

[LegacyOverrideBuiltIns] 拡張属性は引数を取ってはならず、名前付きプロパティゲッターを定義しないインターフェイスや、[Global]拡張属性と同時に宣言してはならない。 部分インターフェイス定義で指定する場合は、その部分インターフェイスが名前付きプロパティゲッターを定義する部分でなければならない。

部分インターフェイス定義で指定された場合は、インターフェイス本体にも付与されたものとみなす。

詳細要件については § 3.9 レガシープラットフォームオブジェクト§ 3.9.3 [[DefineOwnProperty]] を参照。

次のIDL断片は、名前付きプロパティゲッターを持つインターフェイスと、持たないインターフェイスを定義する:

[Exposed=Window]
interface StringMap {
  readonly attribute unsigned long length;
  getter DOMString lookup(DOMString key);
};

[Exposed=Window,
 LegacyOverrideBuiltIns]
interface StringMap2 {
  readonly attribute unsigned long length;
  getter DOMString lookup(DOMString key);
};

これらのインターフェイスを実装するJavaScriptでは、プロパティの取得結果が異なる:

// StringMapのインスタンスを取得。サポートプロパティ名は"abc", "length", "toString"とする。
var map1 = getStringMap();

// 名前付きプロパティゲッター呼び出し。
map1.abc;

// length属性に対応する"length"プロパティ。
map1.length;

// プロトタイプチェーン上のtoStringプロパティ。
map1.toString;

// StringMap2のインスタンス。"abc", "length", "toString"がサポートプロパティ名。
var map2 = getStringMap2();

// 名前付きプロパティゲッター呼び出し。
map2.abc;

// length属性に対応する"length"プロパティだが、名前付きプロパティゲッターが呼ばれる。
map2.length;

// toStringプロパティも名前付きプロパティゲッターが呼ばれる。
map2.toString;

3.4.8. [LegacyTreatNonObjectAsNull]

[LegacyTreatNonObjectAsNull] 拡張属性コールバック関数に付与されている場合、型がnullableコールバック関数型の属性へ値を代入する際の挙動が緩やかになる。すなわち、値がオブジェクトでなければnullに変換され、値がcallableでなければ、呼び出しても何もしないコールバック関数値に変換される。

詳細要件は § 3.2.20 Nullable型 — T?§ 3.2.19 コールバック関数型§ 3.12 コールバック関数の呼び出し を参照。[LegacyTreatNonObjectAsNull]使用時の具体的要件が記載されている。

次のIDL断片は、[LegacyTreatNonObjectAsNull]付きのコールバック関数型属性と、拡張属性無しのコールバック関数型属性を持つインターフェイスを定義する:

callback OccurrenceHandler = undefined (DOMString details);

[LegacyTreatNonObjectAsNull]
callback ErrorHandler = undefined (DOMString details);

[Exposed=Window]
interface Manager {
  attribute OccurrenceHandler? handler1;
  attribute ErrorHandler? handler2;
};

JavaScript実装では、オブジェクト以外(例: Number値)やcallableでない値をhandler1に代入すると、handler2への代入と挙動が異なる:

var manager = getManager();  // Managerインスタンスを取得。

manager.handler1 = function() { };
manager.handler1;            // 関数として評価。

try {
  manager.handler1 = 123;    // TypeErrorが投げられる。
} catch (e) {
}

try {
  manager.handler1 = {};     // TypeErrorが投げられる。
} catch (e) {
}

manager.handler2 = function() { };
manager.handler2;            // 関数として評価。

manager.handler2 = 123;
manager.handler2;            // nullとして評価。

manager.handler2 = {};
manager.handler2;            // オブジェクトとして評価。

3.4.9. [LegacyUnenumerableNamedProperties]

[LegacyUnenumerableNamedProperties] 拡張属性インターフェイスに付与されていて、そのインターフェイスが名前付きプロパティをサポートする場合、そのインターフェイスの名前付きプロパティは全て列挙不可(unenumerable)となる。

[LegacyUnenumerableNamedProperties] 拡張属性は引数を取ってはならず、名前付きプロパティゲッターを定義しないインターフェイスには使ってはならない。

[LegacyUnenumerableNamedProperties]拡張属性がインターフェイスに指定された場合、派生インターフェイスすべてに適用されるため、派生インターフェイスでは指定してはならない。

詳細要件は § 3.9.1 [[GetOwnProperty]] を参照。[LegacyUnenumerableNamedProperties]使用時の具体的要件が記載されている。

3.4.10. [LegacyUnforgeable]

[LegacyUnforgeable] 拡張属性通常属性または非static 操作に付与されている場合、その属性や操作はJavaScriptプロパティとして反映されるが、その挙動は変更できず、プロパティ検索は必ずその属性の値を返す。具体的には、プロパティはnon-configurableとなり、プロトタイプ上ではなくオブジェクト自体の独自プロパティとなる。

属性や操作は、インターフェイスA上で宣言され、[LegacyUnforgeable]拡張属性が付与されている場合、A上で 非偽造(unforgeable)とされる。

[LegacyUnforgeable] 拡張属性は、引数を取ってはならない

[LegacyUnforgeable]拡張属性は、通常属性または非static 操作以外には使ってはならない。また、操作に付与された場合は、そのインターフェイス上の同じ識別子を持つ全ての操作に付与しなければならない。

[LegacyUnforgeable]拡張属性は、名前空間で宣言された属性には使ってはならない。

属性や操作XがインターフェイスA上で非偽造とされ、Aが別のインターフェイスB継承インターフェイスの一つである場合、BXと同じ識別子の通常属性や非static操作を持ってはならない。

例:下記は許されない。

[Exposed=Window]
interface A1 {
  [LegacyUnforgeable] readonly attribute DOMString x;
};
[Exposed=Window]
interface B1 : A1 {
  undefined x();  // 不正:A1のxによってシャドウされる。
};

[Exposed=Window]
interface B2 : A1 { };
B2 includes M1;
interface mixin M1 {
  undefined x();  // 不正:B2のxはA1のxでシャドウされる。
};

詳細要件は § 3.7.6 属性§ 3.7.7 操作§ 3.8 インターフェイスを実装するプラットフォームオブジェクト§ 3.9 レガシープラットフォームオブジェクト§ 3.9.3 [[DefineOwnProperty]] を参照。[LegacyUnforgeable]使用時の具体的要件が記載されている。

次のIDL断片は、2つの属性を持つインターフェイスを定義し、1つは[LegacyUnforgeable]指定:

[Exposed=Window]
interface System {
  [LegacyUnforgeable] readonly attribute DOMString username;
  readonly attribute long long loginTime;
};

JavaScript実装では、username属性はオブジェクト自身のnon-configurableなプロパティとして公開される:

var system = getSystem();                      // Systemインスタンス取得。

system.hasOwnProperty("username");             // true。
system.hasOwnProperty("loginTime");            // false。
System.prototype.hasOwnProperty("username");   // false。
System.prototype.hasOwnProperty("loginTime");  // true。

try {
  // non-configurableなので失敗。
  Object.defineProperty(system, "username", { value: "administrator" });
} catch (e) { }

// System.prototype.loginTimeはconfigurableなのでdefinePropertyできる。
var forgedLoginTime = 5;
Object.defineProperty(System.prototype, "loginTime", { value: forgedLoginTime });

system.loginTime;  // forgedLoginTimeが返る。

3.4.11. [LegacyWindowAlias]

[LegacyWindowAlias] 拡張属性インターフェイスに付与されている場合、Windowインターフェイスは、拡張属性で指定された各識別子に対し、インターフェイスオブジェクトへの値を持つプロパティを持つことになる。

[LegacyWindowAlias] 拡張属性は 識別子または 識別子リストを取ることができる。 「=」の後に現れるidentifierは[LegacyWindowAlias]の 識別子となる。

[LegacyWindowAlias]の識別子は、このインターフェイスまたは他のインターフェイスの[LegacyWindowAlias]拡張属性、[LegacyFactoryFunction]拡張属性、インターフェイスオブジェクトの識別子、予約識別子と重複してはならない。

[LegacyWindowAlias]と[LegacyNoInterfaceObject]拡張属性は同じインターフェイスに同時に指定してはならない。

[LegacyWindowAlias]と[LegacyNamespace]拡張属性は同じインターフェイスに同時に指定してはならない。

[LegacyWindowAlias]拡張属性は、Windowインターフェイスを公開セットに含まないインターフェイスには指定してはならない。

インターフェイスに複数の[LegacyWindowAlias]拡張属性を指定してはならない。

レガシーwindowエイリアスの実装詳細については § 3.7 インターフェイス を参照。

下記IDLは[LegacyWindowAlias]を使うインターフェイスを定義する:

[Exposed=Window,
 LegacyWindowAlias=WebKitCSSMatrix]
interface DOMMatrix : DOMMatrixReadOnly {
  // ...
};

このインターフェイスをサポートするJavaScript実装では、Windowオブジェクト上に、同じ値・同じ特性を持つ2つのプロパティが公開される。一つは通常のインターフェイスオブジェクト用、もう一つはレガシー名用。

WebKitCSSMatrix === DOMMatrix;     // true。

var m = new WebKitCSSMatrix();     // DOMMatrixを実装する新しいオブジェクトを生成。

m.constructor === DOMMatrix;       // true。
m.constructor === WebKitCSSMatrix; // true。
{}.toString.call(m);               // '[object DOMMatrix]'。

3.5. セキュリティ

以下の節で定義される一部のアルゴリズムは、あるオブジェクトに対してセキュリティチェックを実行する。 このチェックは、操作の呼び出しや属性へのアクセスを許可すべきか判断するために用いられる。セキュリティチェックは次の3つの入力を取る:

  1. 操作呼び出しや属性アクセスが行われているプラットフォームオブジェクト

  2. 操作や属性の識別子

  3. 関数オブジェクトの種類 — 操作の場合は"method"、属性のgetter/setterの場合は"getter"または"setter"。

注: セキュリティチェックの実装方法はHTML標準で定義されている。[HTML]

3.6. オーバーロード解決アルゴリズム

関数呼び出しの解決方法を定義するため、オーバーロード解決アルゴリズムを定義する。入力は有効オーバーロード集合Sと、JavaScript値のリストargs。出力は、Sのいずれかのエントリの操作または拡張属性と、IDL値のリストまたは特別な値“missing”のペアである。アルゴリズムは以下のように動作する:

  1. maxargS内で最も長い型リストの長さとする。

  2. nargsサイズとする。

  3. argcountをmin(maxarg, n)で初期化する。

  4. argcount長でない型リストを持つSのエントリを全て除去する。

  5. もしSが空なら、TypeErrorをスローする。

  6. dを−1で初期化する。

  7. methodundefinedで初期化する。

  8. もしSに複数エントリがあれば、dSのエントリに対する識別引数インデックスで設定する。

  9. valuesを空リストで初期化する(各エントリはIDL値または“missing”になる)。

  10. iを0で初期化する。

  11. while i < d:

    1. Vargs[i]とする。

    2. typeS内いずれかのエントリの型リストのインデックスiの型とする。

      注: この時点のS内のエントリはインデックスiで同じ型・オプション性値を持つ。

    3. optionalityS内いずれかのエントリのオプション性値リストのインデックスiの値とする。

    4. もしoptionalityが“optional”かつVundefinedなら:

      1. インデックスiの引数がデフォルト値付きなら、valuesにそのデフォルト値を追加。

      2. それ以外はvaluesに“missing”を追加。

    5. それ以外はvaluesVをIDL型type変換した結果を追加。

    6. ii + 1にする。

  12. もしi = dなら:

    1. Vargs[i]とする。

      注: この引数でどのオーバーロードを選ぶか決定される。

    2. もしVundefinedで、Sにオプション性値リストがインデックスiで“optional”なエントリがあれば、他のエントリをSから除去。

    3. それ以外で、Vnullまたはundefinedで、Sに以下の型がインデックスiにあるエントリがあれば:

      他のエントリをSから除去。

    4. それ以外でVプラットフォームオブジェクトで、Sに以下型がインデックスiにあるエントリがあれば:

      • インターフェイス型V実装しているもの

      • object

      • 上記型のnullable版

      • 上記型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    5. それ以外でVObjectで[[ArrayBufferData]]内部スロットを持ち、Sに以下型がインデックスiにあるエントリがあれば:

      • ArrayBuffer

      • SharedArrayBuffer

      • object

      • 上記型のnullable版

      • 上記型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    6. それ以外でVObjectで[[DataView]]内部スロットを持ち、Sに以下型がインデックスiにあるエントリがあれば:

      • DataView

      • object

      • 上記型のnullable版

      • 上記型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    7. それ以外でVObjectで[[TypedArrayName]]内部スロットを持ち、Sに以下型がインデックスiにあるエントリがあれば:

      • TypedArray型で名前がVの[[TypedArrayName]]と一致するもの

      • object

      • 上記型のnullable版

      • 上記型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    8. それ以外でIsCallable(V)がtrueで、Sに以下型がインデックスiにあるエントリがあれば:

      • コールバック関数型

      • object

      • 上記型のnullable版

      • 上記型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    9. それ以外でVObjectで、Sに以下型がインデックスiにあるエントリがあれば:

      • async sequence型

      • 上記型のnullable版

      • 上記型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      かつ下記条件が全てfalseの場合:

      • Vが[[StringData]]内部スロットを持つ

      • Sがインデックスiで以下型を持つ:

        • string型

        • string型のnullable版

        • string型を内包する注釈付き型

        • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      さらに以下を実行:

      1. methodV%Symbol.asyncIterator%から取得。

      2. もしmethodundefinedなら、%Symbol.iterator%から取得。

      methodundefinedでなければ他のエントリをSから除去。

    10. それ以外でVObjectで、Sに以下型がインデックスiにあるエントリがあれば:

      • sequence型

      • 上記型のnullable版

      • 上記型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      以下を実行:

      1. methodV%Symbol.iterator%から取得。

      methodundefinedでなければ他のエントリをSから除去。

    11. それ以外でVObjectで、Sに以下型がインデックスiにあるエントリがあれば:

      他のエントリをSから除去。

    12. それ以外でVBooleanで、Sに以下型がインデックスiにあるエントリがあれば:

      • boolean

      • boolean型のnullable版

      • boolean型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    13. それ以外でVNumberで、Sに以下型がインデックスiにあるエントリがあれば:

      • 数値型

      • 数値型のnullable版

      • 数値型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    14. それ以外でVBigIntで、Sに以下型がインデックスiにあるエントリがあれば:

      • bigint

      • bigint型のnullable版

      • bigint型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    15. それ以外でSにインデックスiで以下型があるエントリがあれば:

      • string型

      • string型のnullable版

      • string型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    16. それ以外でSにインデックスiで以下型があるエントリがあれば:

      • 数値型

      • 数値型のnullable版

      • 数値型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    17. それ以外でSにインデックスiで以下型があるエントリがあれば:

      • boolean

      • boolean型のnullable版

      • boolean型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    18. それ以外でSにインデックスiで以下型があるエントリがあれば:

      • bigint

      • bigint型のnullable版

      • bigint型を内包する注釈付き型

      • 上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型

      他のエントリをSから除去。

    19. それ以外でSにインデックスiany型があるエントリがあれば、他のエントリをSから除去。

    20. それ以外はTypeErrorをスローする。

  13. callableSに唯一残ったエントリの操作または拡張属性とする。

  14. もしi = dかつmethodundefinedでない場合:

    1. Vargs[i]とする。

    2. TSに残ったエントリの型リストのインデックスiの型とする。

    3. Assert: Tsequence型である。

    4. valuesに、Vmethodから型Tシーケンス生成結果を追加。

    5. ii + 1にする。

  15. while i < argcount:

    1. Vargs[i]とする。

    2. typeSに残ったエントリの型リストのインデックスiの型とする。

    3. optionalitySに残ったエントリのオプション性値リストのインデックスiの値とする。

    4. もしoptionalityが“optional”かつVundefinedなら:

      1. インデックスiの引数がデフォルト値付きなら、valuesにそのデフォルト値を追加。

      2. それ以外はvaluesに“missing”を追加。

    5. それ以外はvaluesVをIDL型type変換した結果を追加。

    6. ii + 1にする。

  16. while icallableが宣言する引数の数より小さい間:

    1. もしcallableのインデックスiの引数がデフォルト値付きなら、valuesにそのデフォルト値を追加。

    2. それ以外でcallableのインデックスiの引数がvariadicでなければ、valuesに“missing”を追加。

    3. ii + 1にする。

  17. ペア <callable, values> を返す。

オーバーロード解決アルゴリズムは、呼び出されるオーバーロードされた操作やコンストラクタ等の特定と、JavaScript引数値の対応するIDL値への変換の両方を行う。非公式には以下のように動作する。

まず、関数に渡されたJavaScript引数の数で有効なオーバーロードを選択する:

正しい引数数の可能なオーバーロード集合が得られたら、JavaScript値を左から右へ変換する。オーバーロード時の制約により、この時点で複数の候補がある場合、引数リストの中でどの位置を使って最終的なオーバーロードを選択するかが決まる。この位置が識別引数インデックスである。

まず識別引数より左の引数を変換する(左側の引数は他のオーバーロードでも同じインデックスで同じ型である必要がある)。次に識別引数インデックスで渡されたJavaScript値の型を調べ、それがどのIDL型に対応するかを判定する。これにより最終的に呼び出すオーバーロードが決定される。ここで渡された値がundefinedで、その位置にoptional引数のオーバーロードがあれば、そのオーバーロードを選択する。ここで渡された値の型に対応する有効なオーバーロードがなければTypeErrorをスローする。一般的に、識別引数インデックスでの値検査は副作用を持たず、オーバーロード解決アルゴリズムでの副作用はJavaScript値のIDL値への変換のみである(例外として、識別引数インデックスがasync sequence型sequence型frozen array型のいずれかの場合、該当するオーバーロードを決めるために%Symbol.asyncIterator% / %Symbol.iterator%プロパティの取得を試み、識別引数の変換を個別に行う)。

この時点で使用するオーバーロードが決定したので、残りの引数(識別引数以降)も変換し、最後の可能な引数以降に渡された余分な引数は引き続き無視する。

optional引数のJavaScript値をIDL値に変換する際、undefinedoptional引数のデフォルト値(あれば)に変換され、なければ特別な値“missing”になる。

ただし、最終の可変長(variadic)引数に対応するoptional引数の場合は、undefinedは“missing”として特別扱いされず、非optional引数と同様に可変長引数型に変換される。

3.7. インターフェイス

あるインターフェイスが特定の公開レルムで公開されていて、かつ[LegacyNoInterfaceObject]や[LegacyNamespace]拡張属性が宣言されていない場合、そのインターフェイスに対応するプロパティがそのレルムのグローバルオブジェクトに存在する。 プロパティ名はインターフェイスの識別子であり、その値はインターフェイスオブジェクトというオブジェクトである。 インターフェイスオブジェクトの特性については§ 3.7.1 インターフェイスオブジェクトを参照。

もし LegacyWindowAlias 拡張属性が 公開されたインターフェイスに指定されている場合、 LegacyWindowAlias識別子ごとに、Window グローバルオブジェクト上に対応するプロパティが存在する。 プロパティ名は指定された 識別子 となり、 その値は インターフェイスオブジェクトへの参照である。

さらに、公開インターフェイス上の各[LegacyFactoryFunction]拡張属性ごとに、JavaScriptグローバルオブジェクト上に対応するプロパティが存在する。 プロパティ名は[LegacyFactoryFunction]の識別子であり、その値はレガシーファクトリ関数と呼ばれるオブジェクトで、インターフェイスを実装するオブジェクトの生成を可能にする。 レガシーファクトリ関数の特性については§ 3.7.2 レガシーファクトリ関数を参照。

本節で定義される一部のJavaScriptメソッドは、最初のステップで実装チェックを行い、呼び出し対象が正しい種類のオブジェクトであり、現在のコンテキストから呼び出し可能かどうか検証する。

オブジェクトの実装チェックを行うには、jsValueをインターフェイスinterface・識別子name・型typeに対して:

  1. object? ToObject(jsValue)とする。

  2. objectプラットフォームオブジェクトなら、以下を渡してセキュリティチェックを実行:

    • プラットフォームオブジェクトobject

    • 識別子name

    • type

  3. objectinterface実装していない場合、TypeErrorをスロー。

  4. objectを返す。

このアルゴリズムは現時点で一貫して使われているわけではない。

3.7.1. インターフェイスオブジェクト

あるインターフェイスオブジェクトは、そのインターフェイスに対応する組み込み関数オブジェクトとなる。 インターフェイスオブジェクトには、そのインターフェイス上で定義された定数static操作に対応するプロパティが存在する(詳細は§ 3.7.5 定数§ 3.7.7 操作参照)。

インターフェイスがコンストラクタ操作で宣言されている場合、そのインターフェイスオブジェクトコンストラクタとして呼び出すことができ、そのインターフェイスを実装するオブジェクトが生成される。 関数として呼び出すと例外が投げられる。

インターフェイスオブジェクトで、そのインターフェイスコンストラクタ操作で宣言されていない場合、関数としてもコンストラクタとしても呼び出すと例外が投げられる。

インターフェイスIインターフェイスオブジェクトは、インターフェイスプロトタイプオブジェクトを関連付けて持つ。 このプロトタイプオブジェクトには、インターフェイス上で定義された通常属性通常操作に対応するプロパティが存在し、詳細は§ 3.7.3 インターフェイスプロトタイプオブジェクト参照。

注: インターフェイスオブジェクトは関数オブジェクトなので、typeof演算子を適用すると"function"が返る。

インターフェイスはオーバーライドされたコンストラクタ手順を持ちうる。これによりインターフェイスオブジェクトの呼び出しや構築時の挙動が変更される。デフォルトではこの手順は持たない。

通常、コンストラクタはコンストラクタ操作とその挙動を定義することで記述される。 オーバーライドされたコンストラクタ手順は、より複雑な状況でのみ使用すること。 この機能を使いたい編集者は事前にissueを提出して議論することを強く推奨する。

インターフェイスI(識別子id)のインターフェイスオブジェクトrealm(レルム)で生成する手順:

  1. steps を、Iオーバーライドされたコンストラクタ手順が存在すればそれとし、存在しない場合は以下の手順とする:

    1. Iコンストラクタ操作で宣言されていなければ、TypeErrorをスローする。

    2. NewTargetundefinedなら、TypeErrorをスローする。

    3. argsを渡された引数とする。

    4. nargsサイズとする。

    5. idをインターフェイスIの識別子とする。

    6. コンストラクタの有効オーバーロード集合を、識別子id・インターフェイスI・引数数nで計算し、Sとする。

    7. Sargsオーバーロード解決アルゴリズムに渡し、結果を<constructor, values>とする。

    8. object内部的にインターフェイスIを実装する新しいオブジェクトを生成realmNewTargetを指定)し、得る。

    9. constructorコンストラクタ手順objectthisとして、valuesを引数として実行。

    10. OobjectJavaScript値に変換したものとする。

    11. Assert: OはインターフェイスI実装するオブジェクトである。

    12. Assert: O.[[Realm]]はrealmである。

    13. Oを返す。

  2. constructorProtorealm.[[Intrinsics]].[[%Function.prototype%]]とする。

  3. Iが他のインターフェイスPから継承していれば、constructorProtorealm内のPのインターフェイスオブジェクトとする。

  4. FCreateBuiltinFunction(steps, « [[Unforgeables]] » , realm, constructorProto)とする。

  5. unforgeablesOrdinaryObjectCreate(null)で生成。

  6. 非偽造通常操作Iからunforgeablesへ定義(realm指定)。

  7. 非偽造通常属性Iからunforgeablesへ定義(realm指定)。

  8. F.[[Unforgeables]]にunforgeablesをセットする。

    注: このオブジェクトはユーザーコードに公開されない。インターフェイスの非偽造メンバーがすべてのインスタンスで同じJavaScript関数オブジェクト(属性getter・setter・操作関数)を使うためだけに存在する。

  9. SetFunctionName(F, id)を実行。

  10. lengthを0で初期化。

  11. Iコンストラクタ操作で宣言されていれば:

    1. コンストラクタの有効オーバーロード集合を、識別子id・インターフェイスI・引数数0で計算し、Sとする。

    2. lengthS内で最も短い引数リストの長さにセット。

  12. SetFunctionLength(F, length)を実行。

  13. protoインターフェイスプロトタイプオブジェクト生成(インターフェイスIrealm指定)の結果とする。

  14. ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: proto, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false})を実行。

  15. 定数をインターフェイスIからFへ定義(realm指定)。

  16. static属性をインターフェイスIからFへ定義(realm指定)。

  17. static操作をインターフェイスIからFへ定義(realm指定)。

  18. Fを返す。

3.7.2. レガシーファクトリ関数

あるレガシーファクトリ関数は、1つ以上の[LegacyFactoryFunction]拡張属性が同じ識別子で定義されていることで存在し、組み込み関数オブジェクトとなる。 これは、その[LegacyFactoryFunction]拡張属性が現れるインターフェイスを実装するオブジェクトを生成できる。

インターフェイスI(識別子id)・realmでのレガシーファクトリ関数生成する手順:

  1. stepsを以下の手順とする:

    1. NewTargetundefinedなら、TypeErrorをスローする。

    2. argsを渡された引数とする。

    3. nargsサイズとする。

    4. レガシーファクトリ関数の有効オーバーロード集合を、識別子id・インターフェイスI・引数数nで計算し、Sとする。

    5. Sargsオーバーロード解決アルゴリズムに渡し、結果を<constructor, values>とする。

    6. object内部的にインターフェイスIを実装する新しいオブジェクトを生成realmNewTargetを指定)し、得る。

    7. constructorコンストラクタ手順objectthisとして、valuesを引数として実行。

    8. OobjectJavaScript値に変換したものとする。

    9. Assert: OはインターフェイスI実装するオブジェクトである。

    10. Assert: O.[[Realm]]はrealmである。

    11. Oを返す。

  2. FCreateBuiltinFunction(steps, « » , realm)とする。

  3. SetFunctionName(F, id)を実行。

  4. レガシーファクトリ関数の有効オーバーロード集合を、識別子id・インターフェイスI・引数数0で計算し、Sとする。

  5. lengthS内で最も短い引数リストの長さにセット。

  6. SetFunctionLength(F, length)を実行。

  7. protoをインターフェイスIインターフェイスプロトタイプオブジェクトrealm指定)の結果とする。

  8. ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: proto, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false})を実行。

  9. Fを返す。

3.7.3. インターフェイスプロトタイプオブジェクト

全てのインターフェイスに対して、[LegacyNoInterfaceObject]拡張属性で宣言されているかどうかに関わらず、インターフェイスプロトタイプオブジェクトが存在する。

インターフェイスinterfacerealmに対するインターフェイスプロトタイプオブジェクト生成手順:

  1. protoをnullで初期化。

  2. interfaceが[Global]拡張属性で宣言され、かつ名前付きプロパティをサポートする場合、protointerfacerealm名前付きプロパティオブジェクト生成の結果でセット。

  3. それ以外でinterfaceが他インターフェイスから継承していれば、protorealm内のその継承インターフェイスのインターフェイスプロトタイプオブジェクトでセット。

  4. それ以外でinterfaceDOMExceptionインターフェイスなら、protorealm.[[Intrinsics]].[[%Error.prototype%]]でセット。

  5. それ以外はprotorealm.[[Intrinsics]].[[%Object.prototype%]]でセット。

  6. Assert: protoはObjectである。

  7. interfaceProtoObjをnullで初期化。

  8. もしrealmグローバルプロトタイプチェーンがmutableなら:

    1. interfaceProtoObjOrdinaryObjectCreate(proto)で生成。

  9. それ以外でinterfaceが[Global]拡張属性で宣言されている、あるいはinterfaceが[Global]拡張属性で宣言されているインターフェイスの継承インターフェイス集合に含まれている場合:

    1. interfaceProtoObjMakeBasicObject(« [[Prototype]], [[Extensible]] »)で生成。

    2. interfaceProtoObj.[[Prototype]]にprotoをセット。

    3. interfaceProtoObjの内部メソッドをimmutable prototype exotic objectの定義に従ってセット。

  10. それ以外はinterfaceProtoObjOrdinaryObjectCreate(proto)で生成。

  11. interfaceに[Unscopable]拡張属性で宣言されたメンバーがあれば:

    1. unscopableObjectOrdinaryObjectCreate(null)で生成。

    2. 全ての公開メンバーmember([Unscopable]拡張属性付き)について:

      1. idmemberの識別子をセット。

      2. ! CreateDataPropertyOrThrow(unscopableObject, id, true)を実行。

    3. descにPropertyDescriptor{[[Value]]: unscopableObject, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}をセット。

    4. ! DefinePropertyOrThrow(interfaceProtoObj, %Symbol.unscopables%, desc)を実行。

  12. interfaceが[Global]拡張属性で宣言されていなければ:

    1. 通常属性定義interfaceからinterfaceProtoObjへ(realm指定)。

    2. 通常操作定義interfaceからinterfaceProtoObjへ(realm指定)。

    3. 反復メソッド定義interfaceからinterfaceProtoObjへ(realm指定)。

    4. 非同期反復メソッド定義interfaceからinterfaceProtoObjへ(realm指定)。

  13. 定数定義interfaceからinterfaceProtoObjへ(realm指定)。

  14. [LegacyNoInterfaceObject]拡張属性がinterfaceに指定されていなければ:

    1. constructorrealm内のinterfaceインターフェイスオブジェクトでセット。

    2. descにPropertyDescriptor{[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true, [[Value]]: constructor}をセット。

    3. ! DefinePropertyOrThrow(interfaceProtoObj, "constructor", desc)を実行。

  15. interfaceProtoObjを返す。

さらに、インターフェイスプロトタイプオブジェクトは以下から宣言的にプロパティを取得する:

これらのプロパティは命令的に定義すること。

[LegacyNoInterfaceObject]拡張属性で定義されたインターフェイスインターフェイスプロトタイプオブジェクトもアクセス可能である。 例えば以下のIDLの場合:

[Exposed=Window,
 LegacyNoInterfaceObject]
interface Foo {
};

partial interface Window {
  attribute Foo foo;
};

この場合、インターフェイスオブジェクト(window.Foo)は存在しないためインターフェイスプロトタイプオブジェクトに直接アクセスすることはできないが、Fooのインスタンスは[[GetPrototypeOf]]内部メソッドでプロトタイプオブジェクトを取得できる(この例ではObject.getPrototypeOf(window.foo))。

インターフェイスプロトタイプオブジェクトクラス文字列は、そのインターフェイス修飾名である。

3.7.4. 名前付きプロパティオブジェクト

[Global]拡張属性で宣言され、かつ名前付きプロパティをサポートする全てのインターフェイスに対して、そのインターフェイスが名前付きプロパティを公開する名前付きプロパティオブジェクトが存在する。

名前付きプロパティオブジェクト(インターフェイスinterfacerealm)の生成手順:
  1. protoをnullで初期化。

  2. interfaceが他インターフェイスから継承していれば、protorealm内の継承インターフェイスのインターフェイスプロトタイプオブジェクトでセット。

  3. それ以外はprotorealm.[[Intrinsics]].[[%Object.prototype%]]でセット。

  4. objMakeBasicObject(« [[Prototype]], [[Extensible]] »)で生成。

  5. obj.[[GetOwnProperty]]を§ 3.7.4.1 [[GetOwnProperty]]の定義に従ってセット。

  6. obj.[[DefineOwnProperty]]を§ 3.7.4.2 [[DefineOwnProperty]]の定義に従ってセット。

  7. obj.[[Delete]]を§ 3.7.4.3 [[Delete]]の定義に従ってセット。

  8. obj.[[SetPrototypeOf]]を§ 3.7.4.4 [[SetPrototypeOf]]の定義に従ってセット。

  9. obj.[[PreventExtensions]]を§ 3.7.4.5 [[PreventExtensions]]の定義に従ってセット。

  10. obj.[[Prototype]]にprotoをセット。

  11. objを返す。

注: 名前付きプロパティオブジェクトの[[OwnPropertyKeys]]内部メソッドはOrdinaryOwnPropertyKeysを使い続ける。レガシープラットフォームオブジェクトの対応物とは異なる。名前付きプロパティは「本当の」独自プロパティではないため、この内部メソッドでは返されない。

名前付きプロパティオブジェクトクラス文字列は、インターフェイスの識別子と文字列"Properties"を連結したもの。

3.7.4.1. [[GetOwnProperty]]

名前付きプロパティオブジェクトOの[[GetOwnProperty]]内部メソッドがプロパティキーPで呼ばれたとき、以下の手順を行う:

  1. AOに対応するインターフェイスとする。

  2. objectO.[[Realm]]のグローバルオブジェクトとする。

  3. Assert: objectA実装する。

  4. 名前付きプロパティ可視性アルゴリズムをプロパティ名P・オブジェクトobjectで実行した結果がtrueなら:

    1. operationを名前付きプロパティゲッター宣言に使われた操作とする。

    2. valueを未初期化変数とする。

    3. もしoperation識別子無しで定義されていれば、valueにインターフェイス記述の「名前付きプロパティの値決定」手順(Pをnameとして)を実行した結果をセット。

    4. それ以外の場合、operationが識別子付きで定義されていれば、valueに操作の記述の手順(Pを唯一の引数値として)を実行した結果をセット。

    5. descをフィールド無しの新しいProperty Descriptorとして生成。

    6. desc.[[Value]]にvalueJavaScript値へ変換した結果をセット。

    7. もしAが[LegacyUnenumerableNamedProperties]拡張属性を持つインターフェイスを実装していれば、desc.[[Enumerable]]にfalseをセット、それ以外はtrueをセット。

    8. desc.[[Writable]]にtrue、desc.[[Configurable]]にtrueをセット。

    9. descを返す。

  5. OrdinaryGetOwnProperty(O, P)を返す。

3.7.4.2. [[DefineOwnProperty]]

名前付きプロパティオブジェクトの[[DefineOwnProperty]]内部メソッドが呼び出されたとき、以下の手順を行う:

  1. falseを返す。

3.7.4.3. [[Delete]]

名前付きプロパティオブジェクトの[[Delete]]内部メソッドが呼び出されたとき、以下の手順を行う:

  1. falseを返す。

3.7.4.4. [[SetPrototypeOf]]

名前付きプロパティオブジェクトOの[[SetPrototypeOf]]内部メソッドがJavaScript値Vで呼び出されたとき、以下の手順を行う:

  1. もしO関連付けられたrealmグローバルプロトタイプチェーンがmutableなら、 ? OrdinarySetPrototypeOf(O, V)を返す。

  2. ? SetImmutablePrototype(O, V)を返す。

3.7.4.5. [[PreventExtensions]]

名前付きプロパティオブジェクトの[[PreventExtensions]]内部メソッドが呼び出されたとき、以下の手順を行う:

  1. falseを返す。

注: これにより[[PreventExtensions]]が失敗することで、名前付きプロパティオブジェクトを拡張可能なままに保つ。

3.7.5. 定数

定数インターフェイスオブジェクトレガシーコールバックインターフェイスオブジェクトインターフェイスプロトタイプオブジェクト、 そして[Global]拡張属性で宣言されたインターフェイスの場合は、 そのインターフェイスを実装する単一のオブジェクト上で公開される。

定数定義をインターフェイス・コールバックインターフェイス・名前空間definitiontargetrealm指定)に対して行うには、以下の手順:
  1. 全ての 定数constdefinitionメンバー)について:

    1. constrealm公開されていなければ、continue

    2. valueconstのIDL値をJavaScript値へ変換したものをセット。

    3. descにPropertyDescriptor{[[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false, [[Value]]: value}をセット。

    4. idconst識別子をセット。

    5. ! DefinePropertyOrThrow(target, id, desc)を実行。

3.7.6. 属性

静的属性インターフェースオブジェクト上に公開されます。 通常の属性インターフェースプロトタイプオブジェクト上に公開されますが、 属性が偽造不可である場合や インターフェースが [Global] 拡張属性で宣言された場合には、 それらはそのインターフェースを実装するすべてのオブジェクト上に公開されます。

通常の属性を定義するために、インターフェースまたは名前空間definitiontarget上に、 realmrealmを与えて、以下の手順を実行します:
  1. attributesを、リストとして、通常の属性であるdefinitionメンバーのリストとして初期化します。

  2. attributesから属性であり 偽造不可なものをすべて削除します。

  3. attributesattributesdefinitiontarget上にrealmを与えて定義します。

静的属性を定義するために、インターフェースまたは名前空間definitiontarget上に、 realmrealmを与えて、以下の手順を実行します:
  1. attributesを、リストとして、静的属性であるdefinitionメンバーのリストとして初期化します。

  2. attributesattributesdefinitiontarget上にrealmを与えて定義します。

偽造不可な通常の属性を定義するために、インターフェースまたは名前空間 definitiontarget上に、 realmrealmを与えて、以下の手順を実行します:
  1. attributesを、リストとして、偽造不可通常の属性であり メンバーであるもののリストとして初期化します。

  2. attributesattributesdefinitiontarget上にrealmを与えて定義します。

属性を定義するために、attributesインターフェースまたは名前空間definitiontarget上に、 realmrealmを与えて、以下の手順を実行します:
  1. attributesの各属性attrについて:

    1. もしattrrealm公開されていなければ、continueします。

    2. getterを、属性ゲッターの生成結果として、attrdefinitionrealmを与えて取得します。

    3. setterを、属性セッターの生成結果として、attrdefinitionrealmを与えて取得します。

      注:属性セッター生成アルゴリズムは、 attr読み取り専用の場合はundefinedを返します。

    4. もしattr偽造不可ならconfigurablefalseとし、 そうでなければtrueとします。

    5. descをPropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}とします。

    6. idattr識別子とします。

    7. ! DefinePropertyOrThrow(target, id, desc)を実行します。

    8. もしattrの型が型引数Tをもつオブザーバブル配列型なら、 targetバックエンドオブザーバブル配列エキゾチックオブジェクトattrのために、オブザーバブル配列エキゾチックオブジェクトの作成アルゴリズムの結果(realmTattrインデックス付き値の設定アルゴリズム、attrインデックス付き値の削除アルゴリズム)で設定します。

属性ゲッターは、以下のようにして生成されます。与えられるのは 属性 attribute名前空間またはインターフェースtargetrealmrealmです:

  1. stepsを以下の一連のステップとします:

    1. 以下のステップを試行します:

      1. idlObjectをnullとします。

      2. もしtargetインターフェースであり、attribute通常の属性なら:

        1. jsValuethisの値(nullまたはundefinedでなければ)、そうでなければrealmグローバルオブジェクトとします。 (この場合、グローバルオブジェクトがtargetを実装せず、かつ[LegacyLenientThis]が指定されていない場合は、 後のステップでTypeErrorが発生します。)

        2. もしjsValueプラットフォームオブジェクトなら、 セキュリティチェックを実行します。 引数はjsValueattribute識別子、および"getter"です。

        3. もしjsValuetarget実装しない場合:

          1. もしattributeが[LegacyLenientThis] 拡張属性で指定されていれば、 undefinedを返します。

          2. そうでなければ、throwし、TypeErrorを投げます。

        4. もしattributeの型がオブザーバブル配列型なら、 jsValueattributeに対する バックエンドオブザーバブル配列エキゾチックオブジェクトを返します。

        5. idlObjectに、jsValueへの参照を表すIDLインターフェース型値を設定します。

      3. Rattributegetter手順idlObjectthisとして実行した結果とします。

      4. RIDL値からJavaScript値への変換により attributeの宣言型としてJavaScript値に変換した結果を返します。

    そして、例外Eがスローされた場合

    1. もしattributeの型がPromise型なら、 ! Call(%Promise.reject%, %Promise%, «E»)を返します。

    2. それ以外の場合は、これらのステップを終了し、例外を伝播させます。

  2. FCreateBuiltinFunction(steps, « », realm)とします。

  3. nameを文字列"get "をattribute識別子の前につけたものとします。

  4. SetFunctionName(F, name)を実行します。

  5. SetFunctionLength(F, 0)を実行します。

  6. Fを返します。

属性セッターは、以下のようにして生成されます。与えられるのは 属性 attribute名前空間またはインターフェースtargetrealmrealmです:

  1. もしtarget名前空間なら:

    1. アサート: attribute読み取り専用です。

    2. undefinedを返します。

  2. もしattribute読み取り専用であり、 [LegacyLenientSetter]、 [PutForwards]、 または[Replaceable] 拡張属性を持たなければ、undefinedを返します。 属性セッター関数はありません。

  3. アサート: attributeの型はPromise型ではありません。

  4. stepsを以下の一連のステップとします:

    1. Vundefinedとします。

    2. 引数が渡されていれば、最初の引数の値をVに設定します。

    3. idattribute識別子とします。

    4. idlObjectをnullとします。

    5. もしattribute通常の属性なら:

      1. jsValuethisの値(nullやundefinedでなければ)、そうでなければrealmグローバルオブジェクトとします。 (この場合、グローバルオブジェクトがtargetを実装せず、かつ[LegacyLenientThis]が指定されていない場合は、 後のステップでTypeErrorが発生します。)

      2. もしjsValueプラットフォームオブジェクトなら、 セキュリティチェックjsValueid、"setter"で実行します。

      3. validThisを、jsValuetarget実装していればtrue、そうでなければfalseとします。

      4. もしvalidThisがfalseで、かつattributeが [LegacyLenientThis] 拡張属性で指定されていなければ、 throwし、 TypeErrorを投げます。

      5. もしattributeが[Replaceable] 拡張属性で宣言されていれば:

        1. ? CreateDataPropertyOrThrow(jsValue, id, V)を実行します。

        2. undefinedを返します。

      6. もしvalidThisがfalseなら、undefinedを返します。

      7. もしattributeが[LegacyLenientSetter] 拡張属性で宣言されていれば、undefinedを返します。

      8. もしattributeが[PutForwards] 拡張属性で宣言されていれば:

        1. Q? Get(jsValue, id)とします。

        2. もしQオブジェクトでなければthrowし、 TypeErrorを投げます。

        3. forwardIdを[PutForwards] 拡張属性の識別子引数とします。

        4. ? Set(Q, forwardId, V, false)を実行します。

        5. undefinedを返します。

      9. idlObjectに、jsValueへの参照を表すIDLインターフェース型値を設定します。

      10. もしattributeの型が型引数Tをもつオブザーバブル配列型なら:

        1. newValuesECMAScript値からIDL値への変換Vを型sequence<T>として変換した結果とします。

        2. oaidlObjectattributeに対するバックエンドオブザーバブル配列エキゾチックオブジェクトとします。

        3. 長さを設定し、 oa.[[ProxyHandler]]の長さを0にします。

        4. iを0とします。

        5. i < newValuesサイズの間、繰り返します:

          1. oa.[[ProxyHandler]].[[SetAlgorithm]]のアルゴリズムステップを newValues[i]とiを与えて実行します。

          2. Append newValues[i]を oa.[[ProxyHandler]].[[BackingList]]に追加します。

        6. undefinedを返します。

    6. idlValueを以下のように決定します:

      attributeの型が列挙型の場合
      1. S? ToString(V)とします。

      2. もしS列挙型の値のいずれでもなければ、 undefinedを返します。

      3. そうでなければ、idlValueSと等しい列挙値とします。

      その他の場合
      idlValueECMAScript値からIDL値への変換Vattributeの型として変換した結果とします。
    7. setter手順attributeに対して、 idlObjectthisとして、 idlValue与えられた値として実行します。

    8. undefinedを返します。

  5. FCreateBuiltinFunction(steps, « », realm)とします。

  6. nameを文字列"set "をidの前につけたものとします。

  7. SetFunctionName(F, name)を実行します。

  8. SetFunctionLength(F, 1)を実行します。

  9. Fを返します。

注: IDL属性にはプロパティは一つしかありませんが、 アクセサプロパティのgetter/setterは、プロパティに対応するIDL属性がアクセスされるオブジェクトのthis値を渡されるため、インスタンス固有のデータを公開できます。

注: 読み取り専用属性に対応するプロパティに代入しようとすると、 そのスクリプトがstrict modeかどうかで挙動が異なります。 strict modeの場合はTypeErrorがスローされ、 そうでない場合は代入は無視されます。

3.7.7. 操作

identifier が一意となる exposedoperationinterface 上に定義されている場合、 対応するプロパティが存在する。 Static operationinterface object 上に公開される。 Regular operationinterface prototype object 上に公開されるが、 operation が unforgeable である場合や interface が [Global] extended attribute で宣言されている場合には、 その interface を implements する各オブジェクト上に公開される。

define the regular operations interface または namespace definition の regular operations を target 上で定義するには、realm realm を与え、以下の手順を実行する:
  1. operations を、list のうち、 regular operationmembers であるものとして definition から取得する。

  2. Remove を用いて、operations から operation のうち unforgeable なものを除去する。

  3. Define the operations operations を、definition および target に対し、realm を用いて定義する。

define the static operations interface または namespace definition の static operations を target 上で定義するには、realm realm を与え、以下の手順を実行する:
  1. operations を、list のうち、 static operationmembers であるものとして definition から取得する。

  2. Define the operations operations を、definition および target に対し、realm を用いて定義する。

define the unforgeable regular operations interface または namespace definition の unforgeable regular operations を target 上で定義するには、realm realm を与え、以下の手順を実行する:
  1. operations を、list のうち、 unforgeableregular operationmembers であるものとして definition から取得する。

  2. Define the operations operations を、definition および target に対し、realm を用いて定義する。

define the operations operationsinterface または namespace definition のものとして target 上に、 realm realm を与え、以下の手順を実行する:
  1. For each operation opoperations の要素として:

    1. もし oprealm にて exposed でなければ、continue する。

    2. methodcreate an operation functionopdefinitionrealm に対して実行した結果とする。

    3. もし opunforgeable であれば modifiablefalse、 それ以外なら true とする。

    4. desc を PropertyDescriptor{[[Value]]: method, [[Writable]]: modifiable, [[Enumerable]]: true, [[Configurable]]: modifiable} とする。

    5. idopidentifier とする。

    6. ! DefinePropertyOrThrow(target, id, desc) を実行する。

create an operation function operation opnamespace または interface targetrealm realm を与え:
  1. idopidentifier とする。

  2. steps を、関数引数値 args を与えたときに実行する以下の手順とする:

    1. 以下を試みる:

      1. idlObject を null とする。

      2. もし targetinterface であり、かつ opstatic operation でなければ:

        1. jsValuethis の値(null または undefined でなければ)、 そうでなければ realmglobal object とする。 (この場合、global object が target を implements せず、 [LegacyLenientThis] が指定されていなければ、後続のステップで TypeError が発生する。)

        2. もし jsValueplatform object であれば、 perform a security checkjsValueid、"method" を渡して実行する。

        3. もし jsValue が interface targetimplements していなければ、 throw により TypeError を投げる。

        4. idlObjectinterface type の IDL 値で jsValue を参照するものに設定する。

      3. nsize of args とする。

      4. Compute the effective overload setregular operationop が regular の場合)または static operationop が static の場合)に対して、 identifier idtarget、引数数 n を渡して計算し、 結果を S とする。

      5. <operation, values> を、Sargsoverload resolution algorithm に渡した結果とする。

      6. Rnull とする。

      7. もし operation が [Default] extended attribute で宣言されているなら:

        1. Assert: operationhas default method steps を持つことを保証する。

        2. Rdefault method stepsoperationidlObjectthis)、values(引数値)を渡して実行した結果に設定する。

      8. それ以外の場合は、Rmethod stepsoperationidlObjectthis)、values(引数値)で実行した結果に設定する。

      9. RIDL から JavaScript 値への変換 を行った値として返す。

        Rop が宣言する型の IDL 値であることが想定されている。[whatwg/webidl Issue #674]

    そして、例外 E が投げられた場合

    1. もし opreturn typepromise type であれば、 ! Call(%Promise.reject%, %Promise%, «E») を返す。

    2. それ以外の場合は、これらの手順を終了し、例外を伝播させる。

  3. FCreateBuiltinFunction(steps, « », realm) の結果とする。

  4. SetFunctionName(F, id) を実行する。

  5. Compute the effective overload setregular operationop が regular の場合)または static operationop が static の場合)に対して、 identifier idtarget、引数数 0 を渡して計算し、結果を S とする。

  6. lengthS の各エントリの中で最も短い引数リストの長さとする。

  7. SetFunctionLength(F, length) を実行する。

  8. F を返す。

3.7.7.1. デフォルト操作

通常の操作 デフォルトメソッド手順を持つ とは、その 識別子 が下記の表の第一列に現れる場合を指す。 この場合、その デフォルトメソッド手順 は表の第二列に示されたアルゴリズムによって与えられ、操作は表の第三列で示された返却型を持たなければならない。

識別子 デフォルトメソッド手順 返却型
"toJSON" デフォルト toJSON 手順 object

通常の操作デフォルトメソッド手順を持たない 場合、[Default] 拡張属性 で宣言してはならない。

3.7.7.1.1. デフォルト toJSON 操作

デフォルト toJSON 手順は、インターフェース I に対して次の通り実行する:

  1. map を新しい 順序付きマップ とする。

  2. stack継承スタックを作成するインターフェース I を渡して得る。

  3. 継承スタックの属性値を収集するを、 this, stack, map を渡して呼び出す。

  4. resultOrdinaryObjectCreate(%Object.prototype%) の結果とする。

  5. map の各 keyvalue について、

    1. kkey IDL から JavaScript への値変換の結果とする。

    2. vvalue IDL から JavaScript への値変換の結果とする。

    3. ! CreateDataPropertyOrThrow(result, k, v) を実行する。

  6. result を返す。

継承スタックの属性値を収集するプラットフォームオブジェクト object, スタック stack, 順序付きマップ map を与えて実行する:

  1. Istack から pop する結果とする。

  2. 属性値を収集するobject, I, map で呼び出す。

  3. もし stack空でなければ継承スタックの属性値を収集するobject, stack, map で呼び出す。

属性値を収集するプラットフォームオブジェクト object, インターフェース I, 順序付きマップ map を与えて実行する:

  1. もし toJSON 操作が [Default] 拡張属性I 上に宣言されていれば、 公開された 通常属性 attrインターフェースメンバーであるものについて順に:

    1. idattr識別子とする。

    2. valuegetter 手順attr に対し objectthis として実行した結果とする。

    3. もし valueJSON 型であれば、set map[id] = value とする。

継承スタックを作成するインターフェース I に対して以下を実行する:

  1. stack を新しい スタックとする。

  2. stack に push するIstack に追加する。

  3. while I継承するインターフェースが存在する間、

    1. I をその インターフェースとする。

    2. stack に push するIstack に追加する。

  4. stack を返す。

[Default] 拡張属性付きの toJSON 操作を宣言した インターフェース のみ、その 通常属性が含まれる。継承したインターフェースで toJSON 操作が宣言されていても含まれない。例えば、次の IDL 断片を考える:

[Exposed=Window]
interface A {
  [Default] object toJSON();
  attribute DOMString a;
};

[Exposed=Window]
interface B : A {
  attribute DOMString b;
};

[Exposed=Window]
interface C : B {
  [Default] object toJSON();
  attribute DOMString c;
};

上記の C インターフェースを実装するオブジェクトで toJSON() メソッドを呼び出した場合、次の JSON オブジェクトが返る:

{
    "a": "...",
    "c": "..."
}

上記の A(または B)インターフェースを実装するオブジェクトで toJSON() メソッドを呼び出した場合は:

{
    "a": "..."
}

toJSON 操作は インターフェースミックスイン(または 部分インターフェース)にも宣言でき、元の インターフェースに宣言した場合と同じ意味となる。例として、次の IDL 断片を考える:

[Exposed=Window]
interface D {
  attribute DOMString d;
};

interface mixin M {
  [Default] object toJSON();
  attribute DOMString m;
};

D includes M;

上記の D インターフェースを実装するオブジェクトで toJSON() メソッドを呼び出した場合:

{
    "d": "...",
    "m": "..."
}

3.7.8. ストリンギファイア

もし インターフェース公開された stringifier を持つ場合、 以下の特性を持つプロパティが存在しなければならない:

3.7.9. イテラブル宣言

イテレーションメソッドを定義する インターフェース definitiontarget 上で、realm realm を与えて定義するには、以下の手順を実行する:
  1. もし definitionインデックス付きプロパティgetter を持つ場合:

    1. DefineMethodProperty(target, %Symbol.iterator%, %Array.prototype.values%, false) を実行する。

    2. もし definition値イテレーター を持つ場合:

      1. ! CreateDataPropertyOrThrow(target, "entries", %Array.prototype.entries%) を実行する。

      2. ! CreateDataPropertyOrThrow(target, "keys", %Array.prototype.keys%) を実行する。

      3. ! CreateDataPropertyOrThrow(target, "values", %Array.prototype.values%) を実行する。

      4. ! CreateDataPropertyOrThrow(target, "forEach", %Array.prototype.forEach%) を実行する。

  2. それ以外の場合、definitionペアイテレーター を持つ場合:

    1. %Symbol.iterator%entries メソッドを定義する:

      1. steps を次の手順列とする:

        1. jsValue? ToObject(this value) の結果とする。

        2. もし jsValueプラットフォームオブジェクト であれば、 セキュリティチェックを実施するjsValue, "%Symbol.iterator%", "method" を渡す)

        3. もし jsValuedefinitionimplements していなければ、TypeError を投げる

        4. 新しい デフォルトイテレーターオブジェクトdefinition 用、jsValuetarget、 "key+value" を kindindex は 0 で返す。

      2. FCreateBuiltinFunction(steps, « », realm) の結果とする。

      3. SetFunctionName(F, "entries") を実行する。

      4. SetFunctionLength(F, 0) を実行する。

      5. DefineMethodProperty(target, %Symbol.iterator%, F, false) を実行する。

      6. ! CreateDataPropertyOrThrow(target, "entries", F) を実行する。

    2. keys メソッドを定義する:

      1. steps を次の手順列とする:

        1. jsValue? ToObject(this value) の結果とする。

        2. もし jsValueプラットフォームオブジェクト であれば、 セキュリティチェックを実施するjsValue, "keys", "method" を渡す)

        3. もし jsValuedefinitionimplements していなければ、TypeError を投げる

        4. 新しい デフォルトイテレーターオブジェクトdefinition 用、jsValuetarget、 "key" を kindindex は 0 で返す。

      2. FCreateBuiltinFunction(steps, « », realm) の結果とする。

      3. SetFunctionName(F, "keys") を実行する。

      4. SetFunctionLength(F, 0) を実行する。

      5. ! CreateDataPropertyOrThrow(target, "keys", F) を実行する。

    3. values メソッドを定義する:

      1. steps を次の手順列とする:

        1. jsValue? ToObject(this value) の結果とする。

        2. もし jsValueプラットフォームオブジェクト であれば、 セキュリティチェックを実施するjsValue, "values", "method" を渡す)

        3. もし jsValuedefinitionimplements していなければ、TypeError を投げる

        4. 新しい デフォルトイテレーターオブジェクトdefinition 用、jsValuetarget、 "value" を kindindex は 0 で返す。

      2. FCreateBuiltinFunction(steps, « », realm) の結果とする。

      3. SetFunctionName(F, "values") を実行する。

      4. SetFunctionLength(F, 0) を実行する。

      5. ! CreateDataPropertyOrThrow(target, "values", F) を実行する。

    4. forEach メソッドを定義する:

      1. steps を関数引数値 callback および thisArg を与えて次の手順列とする:

        1. jsValue? ToObject(this value) の結果とする。

        2. もし jsValueプラットフォームオブジェクト であれば、 セキュリティチェックを実施するjsValue, "forEach", "method" を渡す)

        3. もし jsValuedefinitionimplements していなければ、TypeError を投げる

        4. idlCallbackcallbackIDL値に変換した Function とする。

        5. idlObjectインターフェース型 の IDL 値で jsValue を参照するものに設定する。

        6. pairsidlObjectイテレート対象の値ペアのリストとする。

        7. i を 0 とする。

        8. While i < pairsサイズ の間:

          1. pairpairs[i] とする。

          2. コールバック関数呼び出し idlCallback に « pairvalue, pairkey, idlObject » を渡し、 thisArgコールバックthis値とする。

          3. pairsidlObject の現在の イテレート対象の値ペアのリストに更新する(変更されている可能性がある)。

          4. ii + 1 にする。

      2. FCreateBuiltinFunction(steps, « », realm) の結果とする。

      3. SetFunctionName(F, "forEach") を実行する。

      4. SetFunctionLength(F, 1) を実行する。

      5. ! CreateDataPropertyOrThrow(target, "forEach", F) を実行する。

3.7.9.1. デフォルトイテレーターオブジェクト

ある インターフェース、target、イテレーションkindに対する デフォルトイテレーターオブジェクト は、 [[Prototype]] 内部スロット が その インターフェース用の イテレータープロトタイプオブジェクト となるオブジェクトである。

デフォルトイテレーターオブジェクト には、以下の3つの内部値がある:

注: デフォルトイテレーターオブジェクトは ペアイテレーター のみで使用される。 値イテレーターは、現状オブジェクトの サポートされるインデックス付きプロパティのみをイテレートするため、 標準のJavaScript Arrayイテレーターオブジェクトを利用する。

注: デフォルトイテレーターオブジェクトclass string を持たない。 インターフェースデフォルトイテレーターオブジェクトに対して Object.prototype.toString()が呼び出された場合、その イテレータープロトタイプオブジェクトclass string が使われる。

3.7.9.2. イテレータープロトタイプオブジェクト

イテレータープロトタイプオブジェクト とは、ある インターフェース に対して ペアイテレーター を持つ全てのインターフェースごとに存在するオブジェクトである。これは、そのインターフェース用の デフォルトイテレーターオブジェクト のプロトタイプとなる。

[[Prototype]] 内部スロットイテレータープロトタイプオブジェクトについて、 %Iterator.prototype%でなければならない。

イテレーター結果 値ペア pair と kind kind に対し、以下の手順で与えられる:
  1. resultkind の値に応じて決定する:

    "key"
    1. idlKeypairkey とする。

    2. keyIDL から JavaScript 値への変換idlKey を変換した結果とする。

    3. resultkey である。

    "value"
    1. idlValuepairvalue とする。

    2. valueIDL から JavaScript 値への変換idlValue を変換した結果とする。

    3. resultvalue である。

    "key+value"
    1. idlKeypairkey とする。

    2. idlValuepairvalue とする。

    3. keyIDL から JavaScript 値への変換idlKey を変換した結果とする。

    4. valueIDL から JavaScript 値への変換idlValue を変換した結果とする。

    5. array! ArrayCreate(2) の結果とする。

    6. ! CreateDataPropertyOrThrow(array, "0", key) を実行する。

    7. ! CreateDataPropertyOrThrow(array, "1", value) を実行する。

    8. resultarray である。

  2. CreateIteratorResultObject(result, false) を返す。

イテレータープロトタイプオブジェクトは、属性 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true } を持つ next データプロパティを持たなければならず、その値は以下のように動作する 組み込み関数オブジェクト である:

  1. interface を、イテレータプロトタイプオブジェクトが存在する インターフェイスとする。

  2. thisValuethis の値とする。

  3. object? ToObject(thisValue) の結果とする。

  4. もし objectプラットフォームオブジェクト であれば、 セキュリティチェックを実施する(以下を渡す):

    • プラットフォームオブジェクト object

    • 識別子 "next"

    • 型 "method"

  5. もし objectinterfaceデフォルトイテレーターオブジェクトでなければ、 TypeError を投げる

  6. indexobjectindex とする。

  7. kindobjectkind とする。

  8. valuesobjecttargetイテレート対象の値ペアとする。

  9. lenvalues の長さとする。

  10. もし indexlen 以上なら、 CreateIteratorResultObject(undefined, true) を返す。

  11. pairvaluesindex 番目のエントリとする。

  12. object の index を index + 1 に設定する。

  13. イテレーター結果pairkind で返す。

ある インターフェース 用の イテレータープロトタイプオブジェクトclass string は、 その インターフェース識別子 と文字列 " Iterator" を連結したものである。

3.7.10. 非同期イテラブル宣言

非同期イテレーションメソッドを定義するには、インターフェース definitiontarget 上に、realm realm を与えて、以下の手順を実行する:
  1. もし definition がいずれの 非同期イテラブル宣言(どちらの種類でも)も持たなければ、return する。

  2. Assert: definitionインデックス付きプロパティgetterイテラブル宣言 を持たないこと。

  3. もし definitionペア非同期イテラブル宣言 を持つ場合、以下の %Symbol.asyncIterator% および entries メソッドを定義する:

    1. steps を次の手順列とし、関数引数値 args を与える:

      1. jsValue? ToObject(this value) とする。

      2. もし jsValueプラットフォームオブジェクト であれば、セキュリティチェックを実施して jsValue, "%Symbol.asyncIterator%", "method" を渡す。

      3. もし jsValuedefinitionimplements していなければ、TypeError を投げる

      4. idlObject を IDL インターフェース型値で jsValue を参照するものとする。

      5. idlArgs非同期イテレーターメソッドの引数変換args を与えた結果とする。

      6. iterator を新しく作成した デフォルト非同期イテレーターオブジェクトdefinition 用、idlObjecttarget、 "key+value" を kindis finished は false)とする。

      7. もし存在すれば、非同期イテレーター初期化手順definitionidlObjectiteratoridlArgs で実行する。

      8. iterator を返す。

    2. FCreateBuiltinFunction(steps, « », realm) の結果とする。

    3. SetFunctionName(F, "entries") を実行する。

    4. SetFunctionLength(F, 0) を実行する。

    5. DefineMethodProperty(target, %Symbol.asyncIterator%, F, false) を実行する。

    6. ! CreateDataPropertyOrThrow(target, "entries", F) を実行する。

  4. もし definitionペア非同期イテラブル宣言を持つ場合、keys メソッドを定義する:

    1. steps を次の手順列とし、関数引数値 args を与える:

      1. jsValue? ToObject(this value) とする。

      2. もし jsValueプラットフォームオブジェクト であれば、セキュリティチェックを実施して jsValue, "keys", "method" を渡す。

      3. もし jsValuedefinitionimplements していなければ、TypeError を投げる

      4. idlObject を IDL インターフェース型値で jsValue を参照するものとする。

      5. idlArgs非同期イテレーターメソッドの引数変換args を与えた結果とする。

      6. iterator を新しく作成した デフォルト非同期イテレーターオブジェクトdefinition 用、idlObjecttarget、 "key" を kindis finished は false)とする。

      7. もし存在すれば、非同期イテレーター初期化手順definitionidlObjectiteratoridlArgs で実行する。

      8. iterator を返す。

    2. FCreateBuiltinFunction(steps, « », realm) の結果とする。

    3. SetFunctionName(F, "keys") を実行する。

    4. SetFunctionLength(F, 0) を実行する。

    5. ! CreateDataPropertyOrThrow(target, "keys", F) を実行する。

  5. values、および必要に応じて %Symbol.asyncIterator% メソッドを定義する:

    1. steps を次の手順列とし、関数引数値 args を与える:

      1. jsValue? ToObject(this value) とする。

      2. もし jsValueプラットフォームオブジェクト であれば、セキュリティチェックを実施して jsValue, "values", "method" を渡す。

      3. もし jsValuedefinitionimplements していなければ、TypeError を投げる

      4. idlObject を IDL インターフェース型値で jsValue を参照するものとする。

      5. idlArgs非同期イテレーターメソッドの引数変換args を与えた結果とする。

      6. iterator を新しく作成した デフォルト非同期イテレーターオブジェクトdefinition 用、idlObjecttarget、 "value" を kindis finished は false)とする。

      7. もし存在すれば、非同期イテレーター初期化手順definitionidlObjectiteratoridlArgs で実行する。

      8. iterator を返す。

    2. FCreateBuiltinFunction(steps, « », realm) の結果とする。

    3. SetFunctionName(F, "values") を実行する。

    4. SetFunctionLength(F, 0) を実行する。

    5. ! CreateDataPropertyOrThrow(target, "values", F) を実行する。

    6. もし definition値非同期イテラブル宣言 を持つ場合、! DefineMethodProperty(target, %Symbol.asyncIterator%, F, false) を実行する。

非同期イテレーターメソッドの引数変換 は、インターフェース definition非同期イテラブル宣言を持つ)と JavaScript値のリスト args を与えて:
  1. idlArgs を空のリストとする。

  2. argCountdefinition非同期イテラブル宣言 の引数数(もしくは引数リストがなければ0)とする。

  3. i を 0 とする。

  4. While i < argCount の間:

    1. もし iargsサイズ もしくは args[i] が undefined なら:

      1. もし 非同期イテラブル宣言 のその引数(インデックス i)が デフォルト値で宣言されていれば、 そのデフォルト値を idlArgs に追加する。

      2. それ以外の場合、idlArgs に特殊値 "missing" を追加する。

    2. それ以外の場合、idlArgs に追加する値は ECMAScript値からIDL型変換args[i] を 非同期イテラブル宣言の引数リスト(インデックスi)の型に変換した値とする。

    3. ii + 1 にする。

  5. idlArgs を返す。

これは、全ての引数がオプションでありオーバーロードが許可されない場合の オーバーロード解決アルゴリズム の特殊ケースである。

3.7.10.1. デフォルト非同期イテレーターオブジェクト

ある インターフェース、target、イテレーションkindに対する デフォルト非同期イテレーターオブジェクト は、 [[Prototype]] 内部スロット が その インターフェース用の 非同期イテレータープロトタイプオブジェクト となるオブジェクトである。

デフォルト非同期イテレーターオブジェクト には、以下の内部値がある:

注: デフォルト非同期イテレーターオブジェクトclass string を持たない。 インターフェースデフォルト非同期イテレーターオブジェクトに対して Object.prototype.toString()が呼び出された場合、その 非同期イテレータープロトタイプオブジェクトclass string が使われる。

3.7.10.2. 非同期イテレータープロトタイプオブジェクト

非同期イテレータープロトタイプオブジェクト とは、ある インターフェース に対して 非同期イテラブル宣言 を持つ全てのインターフェースごとに存在するオブジェクトである。 これは、そのインターフェース用の デフォルト非同期イテレーターオブジェクト のプロトタイプとなる。

[[Prototype]] 内部スロット非同期イテレータープロトタイプオブジェクトについて、 %AsyncIteratorPrototype%でなければならない。

非同期イテレータープロトタイプオブジェクト は、 属性 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true } を持つ next データプロパティを持たなければならず、その値は以下のように動作する 組み込み関数オブジェクト である:

  1. interface を、非同期イテレータプロトタイプオブジェクトが存在する インターフェイスとする。

  2. thisValidationPromiseCapability! NewPromiseCapability(%Promise%) とする。

  3. thisValuethis の値とする。

  4. objectCompletion(ToObject(thisValue)) とする。

  5. IfAbruptRejectPromise(object, thisValidationPromiseCapability) を実行する。

  6. もし objectプラットフォームオブジェクト であれば、セキュリティチェックを実施(以下を渡す):

    • プラットフォームオブジェクト object

    • 識別子 "next"

    • 型 "method"

    このとき例外 e が投げられた場合:

    1. ! Call(thisValidationPromiseCapability.[[Reject]], undefined, « e ») を実行する。

    2. thisValidationPromiseCapability.[[Promise]] を返す。

  7. もし objectinterfaceデフォルト非同期イテレーターオブジェクトでなければ:

    1. error を新しい TypeError とする。

    2. ! Call(thisValidationPromiseCapability.[[Reject]], undefined, « error ») を実行する。

    3. thisValidationPromiseCapability.[[Promise]] を返す。

  8. nextSteps を次の手順列とする:

    1. nextPromiseCapability! NewPromiseCapability(%Promise%) とする。

    2. もし objectis finished が true なら:

      1. resultCreateIteratorResultObject(undefined, true) とする。

      2. ! Call(nextPromiseCapability.[[Resolve]], undefined, « result ») を実行する。

      3. nextPromiseCapability.[[Promise]] を返す。

    3. kindobjectkind とする。

    4. nextPromise次のイテレーション結果を取得objecttarget および object を与えた結果とする。

    5. fulfillSteps を次の手順列(nextを与える)とする:

      1. objectongoing promise を null に設定する。

      2. もし nextイテレーション終了 なら:

        1. objectis finished を true に設定する。

        2. CreateIteratorResultObject(undefined, true) を返す。

      3. それ以外の場合、もし interfaceペア非同期イテラブル宣言 を持つ場合:

        1. Assert: next値ペア である。

        2. イテレーター結果nextkind で返す。

      4. それ以外の場合:

        1. Assert: interface値非同期イテラブル宣言 を持つ。

        2. Assert: next は宣言で示された型の値である。

        3. valuenextIDL から JavaScript値変換した結果とする。

        4. CreateIteratorResultObject(value, false) を返す。

    6. onFulfilledCreateBuiltinFunction(fulfillSteps, « ») の結果とする。

    7. rejectSteps を次の手順列(reasonを与える)とする:

      1. objectongoing promise を null に設定する。

      2. objectis finished を true に設定する。

      3. 例外を投げる reason を投げる。

    8. onRejectedCreateBuiltinFunction(rejectSteps, « ») の結果とする。

    9. PerformPromiseThen(nextPromise, onFulfilled, onRejected, nextPromiseCapability) を実行する。

    10. nextPromiseCapability.[[Promise]] を返す。

  9. ongoingPromiseobjectongoing promiseとする。

  10. もし ongoingPromise が null でなければ:

    1. afterOngoingPromiseCapability! NewPromiseCapability(%Promise%) とする。

    2. onSettledCreateBuiltinFunction(nextSteps, « ») の結果とする。

    3. PerformPromiseThen(ongoingPromise, onSettled, onSettled, afterOngoingPromiseCapability) を実行する。

    4. objectongoing promiseafterOngoingPromiseCapability.[[Promise]] に設定する。

  11. それ以外の場合:

    1. objectongoing promisenextSteps の実行結果に設定する。

  12. objectongoing promise を返す。

もし 非同期イテレーター return アルゴリズムが インターフェース に定義されていれば、 非同期イテレータープロトタイプオブジェクト は 属性 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true } を持つ return データプロパティを持ち、その値は引数valueを受け取り以下のように動作する 組み込み関数オブジェクト である:

  1. interface を、非同期イテレータプロトタイプオブジェクトが存在する インターフェイスとする。

  2. returnPromiseCapabilityNewPromiseCapability(%Promise%) の ! により得る。

  3. thisValuethis の値とする。

  4. objectToObject(thisValue) の Completion により得る。

  5. IfAbruptRejectPromise(object, returnPromiseCapability) を行う。

  6. もし objectプラットフォームオブジェクトであれば、 以下を引数として セキュリティチェックを実行する:

    • プラットフォームオブジェクト object

    • 識別子 "return"

    • 型 "method"

    これにより例外 e が投げられた場合:

    1. Call(returnPromiseCapability.[[Reject]], undefined, « e ») を ! で実行する。

    2. returnPromiseCapability.[[Promise]] を返す。

  7. もし objectinterface 用の default asynchronous iterator object でなければ、次を行う:

    1. error を新しい TypeError とする。

    2. Call(returnPromiseCapability.[[Reject]], undefined, « error ») を ! で実行する。

    3. returnPromiseCapability.[[Promise]] を返す。

  8. returnSteps を以下の手順とする:

    1. returnPromiseCapabilityNewPromiseCapability(%Promise%) の ! により得る。

    2. もし objectis finished が true なら、次を行う:

      1. resultCreateIteratorResultObject(value, true) により得る。

      2. Call(returnPromiseCapability.[[Resolve]], undefined, « result ») を ! で実行する。

      3. returnPromiseCapability.[[Promise]] を返す。

    3. objectis finished を true に設定する。

    4. interface 用の 非同期イテレータ return アルゴリズム を、 objecttargetobject、 そして value を与えて実行した結果を返す。

  9. ongoingPromiseobjectongoing promise とする。

  10. もし ongoingPromise が null でなければ、次を行う:

    1. afterOngoingPromiseCapabilityNewPromiseCapability(%Promise%) の ! により得る。

    2. onSettledCreateBuiltinFunction(returnSteps, « ») により得る。

    3. PerformPromiseThen(ongoingPromise, onSettled, onSettled, afterOngoingPromiseCapability) を実行する。

    4. objectongoing promiseafterOngoingPromiseCapability.[[Promise]] に設定する。

  11. それ以外の場合:

    1. objectongoing promisereturnSteps の実行結果に設定する。

  12. fulfillSteps を以下の手順とする:

    1. CreateIteratorResultObject(value, true) を返す。

  13. onFulfilledCreateBuiltinFunction(fulfillSteps, « ») により得る。

  14. PerformPromiseThen(objectongoing promise, onFulfilled, undefined, returnPromiseCapability) を実行する。

  15. returnPromiseCapability.[[Promise]] を返す。

ある インターフェース 用の 非同期イテレータープロトタイプオブジェクトclass string は、 その インターフェース識別子 と文字列 " AsyncIterator" を連結したものである。

3.7.11. マップライク宣言

ある インターフェース Amaplike宣言 で宣言されている場合、 Aインターフェースプロトタイプオブジェクト にいくつかの追加プロパティが存在する。 これらの追加プロパティについては、以下のサブセクションで説明する。

3.7.11.1. size

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ size プロパティが存在しなければならない:

3.7.11.2. %Symbol.iterator%

Aインターフェースプロトタイプオブジェクト 上に %Symbol.iterator% という名前のデータプロパティが属性 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } で存在しなければならず、その値は entries プロパティの値である 関数オブジェクト である。

マップイテレーターの生成 map mapkind("key+value"、"key"、"value"のいずれか)を与えて:
  1. closure を、 mapkind をキャプチャして、呼び出された際に以下の手順を実行する パラメータ無しの Abstract Closureとして新規作成する:

    1. map の全て keyvalue について:

      1. keyvalue をそれぞれ JavaScript値へ変換する。

      2. もし kind が "key" なら、resultkey とする。

      3. それ以外で kind が "value" なら、resultvalue とする。

      4. それ以外の場合、resultCreateArrayFromListkey, value ») とする。

      5. ? GeneratorYield(CreateIteratorResultObject(result, false)) を実行する。

      注: mapサイズやエントリの順序は、 Yield によりこの抽象操作の実行が一時停止された間に変更されている可能性がある。

    2. undefined を返す。

  2. CreateIteratorFromClosure(closure, "%MapIteratorPrototype%", %MapIteratorPrototype%) を返す。

3.7.11.3. entries

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ entries データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 0 である。

関数オブジェクトname プロパティ値は 文字列 "entries" である。

3.7.11.4. keys

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ keys データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 0 である。

関数オブジェクトname プロパティ値は 文字列 "keys" である。

3.7.11.5. values

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ values データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 0 である。

関数オブジェクトname プロパティ値は 文字列 "values" である。

3.7.11.6. forEach

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ forEach データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 1 である。

関数オブジェクトname プロパティ値は 文字列 "forEach" である。

3.7.11.7. get

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ get データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 1 である。

関数オブジェクトname プロパティ値は 文字列 "get" である。

3.7.11.8. has

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ has データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 1 である。

関数オブジェクトname プロパティ値は 文字列 "has" である。

3.7.11.9. set

もし A が識別子 "set" を持つ member を宣言していない場合で、 A がread–writeのmaplike宣言で宣言されている場合は、 Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ set データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 2 である。

関数オブジェクトname プロパティ値は 文字列 "set" である。

もしインターフェースが set メソッドを宣言している場合も、同様に -0 キーを +0 にマッピングし、 this を返さなければならない。

3.7.11.10. delete

もし A が識別子 "delete" を持つ member を宣言していない場合で、 A がread–writeのmaplike宣言で宣言されている場合は、 Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ delete データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 1 である。

関数オブジェクトname プロパティ値は 文字列 "delete" である。

もしインターフェースが delete メソッドを宣言している場合も、同様に -0 キーを +0 にマッピングし、 キーが存在したかどうかを示す boolean を返さなければならない。

3.7.11.11. clear

もし A が識別子 "clear" を持つ member を宣言していない場合で、 A がread–writeのmaplike宣言で宣言されている場合は、 Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ clear データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 0 である。

関数オブジェクトname プロパティ値は 文字列 "clear" である。

もしインターフェースが clear メソッドを宣言している場合も、map entries オブジェクトは(新しく生成せず)保持し、 undefined を返さなければならない。

3.7.12. setlike宣言

ある インターフェース Asetlike宣言 で宣言されている場合、 Aインターフェースプロトタイプオブジェクト にいくつかの追加プロパティが存在する。 これらの追加プロパティについては、以下のサブセクションで説明する。

3.7.12.1. size

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ size プロパティが存在しなければならない:

3.7.12.2. %Symbol.iterator%

Aインターフェースプロトタイプオブジェクト 上に %Symbol.iterator% という名前のデータプロパティが属性 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } で存在しなければならず、その値は values プロパティの値である 関数オブジェクト である。

セットイテレーターの生成 set setkind("key+value"、"value"のいずれか)を与えて:
  1. closure を、 setkind をキャプチャして、呼び出された際に以下の手順を実行する パラメータ無しの Abstract Closureとして新規作成する:

    1. set の全て entry について:

      1. entryJavaScript値へ変換する。

      2. もし kind が "value" なら、resultentry とする。

      3. それ以外の場合、resultCreateArrayFromListentry, entry ») とする。

      4. ? GeneratorYield(CreateIteratorResultObject(result, false)) を実行する。

      注: setサイズやエントリの順序は、 Yield によりこの抽象操作の実行が一時停止された間に変更されている可能性がある。

    2. undefined を返す。

  2. CreateIteratorFromClosure(closure, "%SetIteratorPrototype%", %SetIteratorPrototype%) を返す。

3.7.12.3. entries

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ entries データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 0 である。

関数オブジェクトname プロパティ値は 文字列 "entries" である。

3.7.12.4. keys

Aインターフェースプロトタイプオブジェクト 上に 属性 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true } を持つ keys データプロパティが存在しなければならず、その値は values プロパティの値である 関数オブジェクト である。

3.7.12.5. values

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ values データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 0 である。

関数オブジェクトname プロパティ値は 文字列 "values" である。

3.7.12.6. forEach

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ forEach データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 1 である。

関数オブジェクトname プロパティ値は 文字列 "forEach" である。

3.7.12.7. has

Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ has データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 1 である。

関数オブジェクトname プロパティ値は 文字列 "has" である。

3.7.12.8. add

もし A が識別子 "add" を持つ member を宣言していない場合で、 A がread–writeのsetlike宣言で宣言されている場合は、 Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ add データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 1 である。

関数オブジェクトname プロパティ値は 文字列 "add" である。

もしインターフェースが add メソッドを宣言している場合も、同様に -0 値を +0 にマッピングし、 設定された値を返さなければならない。

3.7.12.9. delete

もし A が識別子 "delete" を持つ member を宣言していない場合で、 A がread–writeのsetlike宣言で宣言されている場合は、 Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ delete データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 1 である。

関数オブジェクトname プロパティ値は 文字列 "delete" である。

もしインターフェースが delete メソッドを宣言している場合も、同様に -0 値を +0 にマッピングし、 値が存在したかどうかを示す boolean を返さなければならない。

3.7.12.10. clear

もし A が識別子 "clear" を持つ member を宣言していない場合で、 A がread–writeのsetlike宣言で宣言されている場合は、 Aインターフェースプロトタイプオブジェクト 上に 以下の特徴を持つ clear データプロパティが存在しなければならない:

関数オブジェクトlength プロパティ値は Number値 0 である。

関数オブジェクトname プロパティ値は 文字列 "clear" である。

もしインターフェースが clear メソッドを宣言している場合も、set entries オブジェクトは(新しく生成せず)保持し、 undefined を返さなければならない。

3.8. インターフェースを実装するプラットフォームオブジェクト

JavaScript値 valueプラットフォームオブジェクトであるのは、valueObjectである かつ value が [[PrimaryInterface]] 内部スロットを持つ場合である。
JavaScript値 valueimplements するインターフェース interface interface とは、 valueプラットフォームオブジェクトである かつ value.[[PrimaryInterface]] の 包括的な継承インターフェースinterface含む場合である。

仕様書では、「object implements interface」という概念を、「objectinterfaceオブジェクトである」など様々な形で参照されることがある。

全ての プラットフォームオブジェクトは、 realm と関連付けられている。これは 初期オブジェクトと同様である。 このrealmは プラットフォームオブジェクトの [[Realm]] スロットに格納される。 Web IDLを利用する仕様は、各プラットフォームオブジェクトがどのrealm(または間接的にどのグローバルオブジェクト)と関連付けられるのかを明示する責任がある。 特に、以下のアルゴリズムは新しい プラットフォームオブジェクト を引数で与えられたrealmと関連付ける。

インターフェースを実装する新しいオブジェクトの作成では interfacerealm realm を与え、以下の手順を実行する:
  1. インターフェースを内部的に実装する新しいオブジェクトを作成し、 interfacerealmundefined を与えた結果を返す。

インターフェースを内部的に実装する新しいオブジェクトを作成では interfacerealm realm、JavaScript値 newTarget を与え、以下の手順を実行する:
  1. Assert: interfacerealm公開されている

  2. もし newTargetundefined なら:

    1. prototyperealminterfaceインターフェースプロトタイプオブジェクトとする。

  3. それ以外の場合:

    1. Assert: IsCallable(newTarget) は true。

    2. prototype? Get(newTarget, "prototype") とする。

    3. もし prototypeObjectでない場合:

      1. targetRealm? GetFunctionRealm(newTarget) とする。

      2. prototypetargetRealminterfaceインターフェースプロトタイプオブジェクトに設定する。

  4. slots を « [[Prototype]], [[Extensible]], [[Realm]], [[PrimaryInterface]] » とする。

  5. もし interfaceDOMException なら、 [[ErrorData]] を slots に追加する。

  6. instanceMakeBasicObject(slots) とする。

  7. instance.[[Realm]] を realm に設定する。

  8. instance.[[PrimaryInterface]] を interface に設定する。

  9. instance.[[Prototype]] を prototype に設定する。

  10. interfacesinterface包括的な継承インターフェースとする。

  11. 全ての インターフェース ancestor interface in interfaces について:

    1. unforgeablesrealmancestor interfaceインターフェースオブジェクトの [[Unforgeables]] スロット値とする。

    2. keys! unforgeables.[[OwnPropertyKeys]]() の結果とする。

    3. key in keys について:

      1. descriptor! unforgeables.[[GetOwnProperty]](key) の結果とする。

      2. ! DefinePropertyOrThrow(instance, key, descriptor) を実行する。

  12. もし interface が [Global] 拡張属性で宣言されている場合:

    1. 通常の操作を定義するinterfaceinstancerealm で実行する。

    2. 通常の属性を定義するinterfaceinstancerealm で実行する。

    3. イテレーションメソッドを定義するinterfaceinstancerealm で実行する。

    4. 非同期イテレーションメソッドを定義するinterfaceinstancerealm で実行する。

    5. グローバルプロパティ参照を定義するinstancerealm で実行する。

    6. instance.[[SetPrototypeOf]] を § 3.8.1 [[SetPrototypeOf]] の定義に従って設定する。

  13. それ以外で、interfacesインターフェースインデックス付きプロパティ名前付きプロパティをサポートするものを含む場合:

    1. instance.[[GetOwnProperty]] を § 3.9.1 [[GetOwnProperty]] の定義に従って設定する。

    2. instance.[[Set]] を § 3.9.2 [[Set]] の定義に従って設定する。

    3. instance.[[DefineOwnProperty]] を § 3.9.3 [[DefineOwnProperty]] の定義に従って設定する。

    4. instance.[[Delete]] を § 3.9.4 [[Delete]] の定義に従って設定する。

    5. instance.[[PreventExtensions]] を § 3.9.5 [[PreventExtensions]] の定義に従って設定する。

    6. instance.[[OwnPropertyKeys]] を § 3.9.6 [[OwnPropertyKeys]] の定義に従って設定する。

  14. instance を返す。

グローバルプロパティ参照を定義するには targetrealm realm を与え、以下の手順を実行する:
  1. interfacesリストとし、realm公開されている全ての インターフェース を含める。

  2. もし ABinterfaces要素であり、 AB継承していたら、 A のインデックスは B よりも高くなるよう interfaces をソートする。

  3. 全ての interfacesinterface について:

    1. interface が [LegacyNoInterfaceObject] または [LegacyNamespace] 拡張属性で宣言されていなければ:

      1. idinterface識別子とする。

      2. interfaceObjectインターフェースオブジェクトの作成し、interfaceidrealmを与えた結果とする。

      3. DefineMethodProperty(target, id, interfaceObject, false) を実行する。

      4. もし interface が [LegacyWindowAlias] 拡張属性 で宣言されていて、 targetWindow インターフェースを実装している場合:

        1. 全ての [LegacyWindowAlias] の 識別子 id について:

          1. DefineMethodProperty(target, id, interfaceObject, false) を実行する。

    2. もし interface が [LegacyFactoryFunction] 拡張属性で宣言されている場合:

      1. 全ての [LegacyFactoryFunction] の 識別子 id について:

        1. legacyFactoryFunctionレガシーファクトリ関数の作成idinterfacerealm を与えた結果とする。

        2. DefineMethodProperty(target, id, legacyFactoryFunction, false) を実行する。

  4. 全ての コールバックインターフェース interfacerealm公開され、かつ 定数が定義されているものについて:

    1. idinterface識別子とする。

    2. interfaceObjectレガシーコールバックインターフェースオブジェクトの作成interfaceidrealm を与えた結果とする。

    3. DefineMethodProperty(target, id, interfaceObject, false) を実行する。

  5. 全ての 名前空間 namespacerealm公開されているものについて:

    1. idnamespace識別子とする。

    2. namespaceObject名前空間オブジェクトの作成namespacerealm を与えた結果とする。

    3. DefineMethodProperty(target, id, namespaceObject, false) を実行する。

プラットフォームオブジェクトimplements するインターフェースの集合は、そのオブジェクトのライフタイム中には変更されない。

異なる プラットフォームオブジェクト が 異なる グローバルオブジェクト を持っていても、 [[PrimaryInterface]] 内部スロットには同じ インターフェースへの参照を共有する。例えば、同一オリジンのiframeを含むページで、iframeのメソッドが メインページの同種の要素で呼ばれても例外は投げられない。

インターフェースミクスインimplementsアルゴリズムの評価に直接関与しない。 代わりに、インターフェースミクスインincludeされている各 インターフェースはミクスインの各 member の「コピー」を持ち、 対応する operation functionはレシーバがその インターフェースincludeしていることをチェックする。

プライマリインターフェースとは、 プラットフォームオブジェクトの [[PrimaryInterface]] 内部スロットの値であり、 そのオブジェクトが implements する最も派生した インターフェースである。

ある realm に関連付けられた プラットフォームオブジェクトは、作成後に グローバル環境を変更できる。 プラットフォームオブジェクトに関連付けられている realm が変更された場合、 その [[Prototype]] 内部スロットは 直ちに新しい関連realmの プライマリインターフェースインターフェースプロトタイプオブジェクトに更新されなければならない。

また、[Global] 拡張属性を持つ インターフェースを実装する プラットフォームオブジェクトは、 以下から宣言的にプロパティを取得する:

これらのプロパティは命令的に定義すること。

3.8.1. [[SetPrototypeOf]]

インターフェースが [Global] 拡張属性を持つ プラットフォームオブジェクト O の [[SetPrototypeOf]] 内部メソッドが JavaScript言語値 V で呼び出された場合、以下の手順を実行する:

  1. もし O関連realmグローバルプロトタイプチェーンがmutableか が true なら、 ? OrdinarySetPrototypeOf(O, V) を返す。

  2. ? SetImmutablePrototype(O, V) を返す。

注: Window オブジェクトについては、WindowProxy オブジェクトの存在により、[[SetPrototypeOf]] が Window オブジェクトに直接呼び出されることはないため、実装の有無は観測できない。他のグローバルオブジェクトではこの挙動が必要となる。

3.9. レガシープラットフォームオブジェクト

レガシープラットフォームオブジェクトは、 インデックス付き名前付きの プロパティに対応する追加プロパティを持つように見える。 これらのプロパティはオブジェクト上の「実際の」ownプロパティではなく、[[GetOwnProperty]] 内部メソッド によって 露出されているため、そう見えるだけである。

1つのオブジェクトがインデックス付きプロパティをサポートする複数のインターフェースを実装することは許容されている。 ただし、その場合、オブジェクトの サポートされるプロパティインデックス に関して定義が競合している場合は、 そのオブジェクトが持つ追加プロパティや、インデックス付きプロパティの正確な挙動は未定義となる。名前付きプロパティについても同様である。

インデックス付きプロパティgetterは、 レガシープラットフォームオブジェクトが実装する最も派生したインターフェース上で定義されたものが、 配列インデックスによるオブジェクトのインデックス参照時の挙動を定義する。同様に インデックス付きプロパティsetterも 最も派生したインターフェース上の定義が利用される。 このようにして、祖先インターフェースの特殊操作定義はオーバーライド可能になる。

プロパティ名が、あるプラットフォームオブジェクト O において unforgeable property name(偽造不可プロパティ名) であるとは、 Oインターフェースを実装していて、 そのインターフェースがその識別子の interface member を持ち、 そのinterface memberが O のいずれかの実装インターフェース上で unforgeable である場合を指す。

getter への対応は § 3.9.1 [[GetOwnProperty]]で、 setter への対応は § 3.9.3 [[DefineOwnProperty]] および § 3.9.2 [[Set]]で扱われる。

さらに、レガシープラットフォームオブジェクトは以下の内部メソッドを持つ:

3.9.1. [[GetOwnProperty]]

全ての レガシープラットフォームオブジェクト O の [[GetOwnProperty]] 内部メソッドは、 プロパティ名 P で呼び出された場合、以下のように動作しなければならない:

  1. ? LegacyPlatformObjectGetOwnProperty(O, P, false) を返す。

3.9.2. [[Set]]

全ての レガシープラットフォームオブジェクト O の [[Set]] 内部メソッドは、 プロパティ名 P、値 V、JavaScript言語値 Receiver で呼び出された場合、以下のように動作しなければならない:

  1. もし OReceiver が同一オブジェクトなら:

    1. もし Oインターフェースを実装していて、インデックス付きプロパティsetterを持ち、 P配列インデックスなら:

      1. インデックス付きプロパティsetterを呼び出すO, P, V)。

      2. true を返す。

    2. もし Oインターフェースを実装していて、名前付きプロパティsetterを持ち、 PString型なら:

      1. 名前付きプロパティsetterを呼び出すO, P, V)。

      2. true を返す。

  2. ownDesc? LegacyPlatformObjectGetOwnProperty(O, P, true) とする。

  3. ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc) を実行する。

3.9.3. [[DefineOwnProperty]]

全ての レガシープラットフォームオブジェクト O の [[DefineOwnProperty]] 内部メソッドがプロパティキー Pプロパティディスクリプタ Desc で呼び出された場合、以下の手順を実行する:

  1. もし Oインデックス付きプロパティをサポートしていて、 P配列インデックスなら:

    1. IsDataDescriptor(Desc) の結果が falseなら、false を返す。

    2. もし Oインデックス付きプロパティsetterを持つインターフェースを実装していなければ false を返す。

    3. インデックス付きプロパティsetterを呼び出すO, P, Desc.[[Value]])。

    4. true を返す。

  2. もし O名前付きプロパティをサポートしていて、 O が [Global] 拡張属性を持つインターフェースを実装しておらず、 PString型で、 PO偽造不可プロパティ名でない場合:

    1. creatingPサポートされるプロパティ名でなければ true、そうであれば false とする。

    2. もし O が [LegacyOverrideBuiltIns] 拡張属性を持つインターフェースを実装している場合、または OP というownプロパティを持たない場合:

      1. もし creating が false かつ O名前付きプロパティsetterを持つインターフェースを実装していなければ false を返す。

      2. もし O名前付きプロパティsetterを持つインターフェースを実装していれば:

        1. IsDataDescriptor(Desc) の結果が falseなら false を返す。

        2. 名前付きプロパティsetterを呼び出すO, P, Desc.[[Value]])。

        3. true を返す。

  3. ! OrdinaryDefineOwnProperty(O, P, Desc) を返す。

3.9.4. [[Delete]]

全ての レガシープラットフォームオブジェクト O の [[Delete]] 内部メソッドは、 プロパティ名 P で呼び出された場合、以下のように動作しなければならない。

  1. もし Oインデックス付きプロパティをサポートしていて、 P配列インデックスなら:

    1. index! ToUint32(P) の結果とする。

    2. もし indexサポートされるプロパティインデックスでなければ true を返す。

    3. false を返す。

  2. もし O名前付きプロパティをサポートしていて、 O が [Global] 拡張属性を持つインターフェースを実装しておらず、 named property visibility algorithm を プロパティ名 P とオブジェクト O で呼び出した結果が true なら:

    1. もし O名前付きプロパティdeleterを持つインターフェースを実装していなければ false を返す。

    2. operation を名前付きプロパティdeleterを宣言した際に使用したoperationとする。

    3. もし operation が識別子無しで定義されていれば:

      1. インターフェース記述の指示に従い 既存の名前付きプロパティを削除する手順を実行し、 P を名前とする。

      2. もし削除失敗であると指示された場合、false を返す。

    4. それ以外の場合、operation が識別子付きで定義されていれば:

      1. メソッド手順operation)を、Othis、«P» を引数値として実行する。

      2. もし operationboolean 型の戻り値で宣言されていて手順の戻り値が false なら false を返す。

    5. true を返す。

  3. もし OP というownプロパティを持っていれば:

    1. そのプロパティがconfigurableでなければ false を返す。

    2. それ以外なら O からそのプロパティを削除する。

  4. true を返す。

3.9.5. [[PreventExtensions]]

レガシープラットフォームオブジェクトの [[PreventExtensions]] 内部メソッドが呼び出された場合、以下の手順を実行する:

  1. false を返す。

注: これは レガシープラットフォームオブジェクト を 拡張可能(extensible)なままにし、[[PreventExtensions]] が失敗することを保証する。

3.9.6. [[OwnPropertyKeys]]

この文書では、インターフェースを実装するプラットフォームオブジェクト (または 例外を表すプラットフォームオブジェクト)の 完全なプロパティ列挙順を定義していない。 ただし、レガシープラットフォームオブジェクトについては [[OwnPropertyKeys]] 内部メソッドを以下の通り定義する。

レガシープラットフォームオブジェクト O の [[OwnPropertyKeys]] 内部メソッドが呼び出された場合、以下の手順を実行する:

  1. keys を JavaScriptのString値およびSymbol値の空リストとして新規作成する。

  2. もし Oインデックス付きプロパティをサポートしている場合は、 Oサポートされるプロパティインデックス index について、 昇順で append し、 ! ToString(index) を keys に追加する。

  3. もし O名前付きプロパティをサポートしている場合は、 Oサポートされるプロパティ名 P について、 named property visibility algorithm で 可視なら append し、Pkeys に追加する。

  4. O の ownプロパティキー(String型) P について、プロパティ作成の昇順で append し、Pkeys に追加する。

  5. O の ownプロパティキー(Symbol型) P について、プロパティ作成の昇順で append し、Pkeys に追加する。

  6. Assert: keys に重複はない。

  7. keys を返す。

3.9.7. 抽象操作

プロパティ名 P配列インデックスか判定するには、次のアルゴリズムを適用する:

  1. もし PString型でなければfalse を返す。

  2. indexCanonicalNumericIndexString(P) の結果とする。

  3. もし indexundefined なら false を返す。

  4. もし IsInteger(index) が false なら false を返す。

  5. もし index が −0 なら false を返す。

  6. もし index < 0 なら false を返す。

  7. もし index ≥ 232 − 1 なら false を返す。

    注: 232 − 1 は JavaScript の最大配列長である。

  8. true を返す。

名前付きプロパティ可視性アルゴリズム は、与えられた名前付きプロパティがオブジェクト上で公開されているかどうかを判定するために使用される。 一部の名前付きプロパティは、[LegacyOverrideBuiltIns] 拡張属性の有無により公開されない場合がある。 このアルゴリズムは、プロパティ名 P とオブジェクト O について次のように動作する:

  1. もし POサポートされるプロパティ名でなければ false を返す。

  2. もし OP というownプロパティを持っていれば false を返す。

    注: これには O が偽造不可プロパティを持つ場合も含まれる。実際、それらは常にサポートされるプロパティ名が設定される前にセットアップされるため、セットアップ後は対応する名前付きプロパティは不可視となる。

  3. もし O が [LegacyOverrideBuiltIns] 拡張属性を持つインターフェースを実装していれば true を返す。

  4. prototypeO.[[GetPrototypeOf]]() の値とする。

  5. prototype が null でない間:

    1. もし prototype名前付きプロパティオブジェクトでなく、 かつ prototypeP というownプロパティを持っていれば false を返す。

    2. prototypeprototype.[[GetPrototypeOf]]() に設定する。

  6. true を返す。

これにより、名前付きプロパティを持つオブジェクトに対してプロパティ解決が以下の順序で行われることが保証される:

  1. インデックス付きプロパティ。

  2. ownプロパティ(偽造不可属性や操作も含む)。

  3. [LegacyOverrideBuiltIns] の場合:

    1. 名前付きプロパティ。

    2. プロトタイプチェーンからのプロパティ。

  4. それ以外([LegacyOverrideBuiltIns] でない場合):

    1. プロトタイプチェーンからのプロパティ。

    2. 名前付きプロパティ。

インデックス付きプロパティsetterを呼び出す には、プラットフォームオブジェクト O、プロパティ名 P、JavaScript値 V を与え、以下の手順を実施する:

  1. index? ToUint32(P) の結果とする。

  2. creatingindexサポートされるプロパティインデックスでなければ true、そうであれば false とする。

  3. operation をインデックス付きプロパティsetterを宣言した際に使用したoperationとする。

  4. Toperation の第2引数の型とする。

  5. value を、V を型 T の IDL 値に変換した結果とする。

  6. もし operation が識別子無しで定義されていれば:

    1. もし creating が true なら、インターフェース記述の指示に従い 新しいインデックス付きプロパティの値を設定する手順を、 indexをインデックス、valueを値として実行する。

    2. それ以外の場合(creating が false)、インターフェース記述の指示に従い 既存のインデックス付きプロパティの値を設定する手順を、 indexをインデックス、valueを値として実行する。

  7. それ以外の場合、operation が識別子付きで定義されていれば、 メソッド手順operation)を Othis、« index, value » を引数値として実行する。

名前付きプロパティsetterを呼び出す には、プラットフォームオブジェクト O、プロパティ名 P、JavaScript値 V を与え、以下の手順を実施する:

  1. creatingPサポートされるプロパティ名でなければ true、そうであれば false とする。

  2. operation を名前付きプロパティsetterを宣言した際に使用したoperationとする。

  3. Toperation の第2引数の型とする。

  4. value を、V を型 T の IDL 値に変換した結果とする。

  5. もし operation が識別子無しで定義されていれば:

    1. もし creating が true なら、インターフェース記述の指示に従い 新しい名前付きプロパティの値を設定する手順を、 Pを名前、valueを値として実行する。

    2. それ以外の場合(creating が false)、インターフェース記述の指示に従い 既存の名前付きプロパティの値を設定する手順を、 Pを名前、valueを値として実行する。

  6. それ以外の場合、operation が識別子付きで定義されていれば、 メソッド手順operation)を Othis、« P, value » を引数値として実行する。

LegacyPlatformObjectGetOwnProperty 抽象操作は、 オブジェクト O、プロパティ名 P、boolean値 ignoreNamedProps を受けて次の手順を実行する:

  1. もし Oインデックス付きプロパティをサポートしていて、 P配列インデックスなら:

    1. index! ToUint32(P) の結果とする。

    2. もし indexサポートされるプロパティインデックスなら:

      1. operation をインデックス付きプロパティgetterを宣言した際に使用したoperationとする。

      2. value を未初期化変数とする。

      3. もし operation が識別子無しで定義されていれば、 value をインターフェース記述の指示に従い インデックス付きプロパティの値を取得する手順を indexをインデックスとして実行した結果に設定する。

      4. それ以外の場合、operation が識別子付きで定義されていれば valueメソッド手順operation)を Othis、« index » を引数値として実行した結果に設定する。

      5. desc をフィールド無しの新規 プロパティディスクリプタとして生成する。

      6. desc.[[Value]] を valueをJavaScript値へ変換した結果に設定する。

      7. もし Oインデックス付きプロパティsetterを持つインターフェースを実装していれば desc.[[Writable]] を true に、そうでなければ false に設定する。

      8. desc.[[Enumerable]] および desc.[[Configurable]] を true に設定する。

      9. desc を返す。

    3. ignoreNamedProps を true に設定する。

  2. もし O名前付きプロパティをサポートしていて、 ignoreNamedProps が false なら:

    1. もし 名前付きプロパティ可視性アルゴリズム(プロパティ名 P、オブジェクト O)の結果が true なら:

      1. operation を名前付きプロパティgetterを宣言した際に使用したoperationとする。

      2. value を未初期化変数とする。

      3. もし operation が識別子無しで定義されていれば、 value をインターフェース記述の指示に従い 名前付きプロパティの値を取得する手順を Pを名前として実行した結果に設定する。

      4. それ以外の場合、operation が識別子付きで定義されていれば valueメソッド手順operation)を Othis、« P » を引数値として実行した結果に設定する。

      5. desc をフィールド無しの新規 プロパティディスクリプタとして生成する。

      6. desc.[[Value]] を valueをJavaScript値へ変換した結果に設定する。

      7. もし O名前付きプロパティsetterを持つインターフェースを実装していれば desc.[[Writable]] を true に、そうでなければ false に設定する。

      8. もし O が [LegacyUnenumerableNamedProperties] 拡張属性を持つインターフェースを実装していれば desc.[[Enumerable]] を false に、そうでなければ true に設定する。

      9. desc.[[Configurable]] を true に設定する。

      10. desc を返す。

  3. OrdinaryGetOwnProperty(O, P) を返す。

3.10. オブザーバブル配列エキゾチックオブジェクト

オブザーバブル配列エキゾチックオブジェクトは、JavaScriptの Proxyエキゾチックオブジェクトの特定の型であり、本節で定義されたプロキシトラップを用いて作成される。 これは、JavaScript仕様が ArrayインスタンスをプロキシターゲットとするProxyエキゾチックオブジェクトに対し特別な扱いを行っているためであり、 オブザーバブル配列型がこの特別扱いを保ったままJavaScriptコードに公開されることを保証したいからである。

オブザーバブル配列エキゾチックオブジェクトで使われるプロキシトラップは、通常のArrayインスタンスの不変条件よりも多くの不変条件を保証する:

オブザーバブル配列エキゾチックオブジェクトの作成 を、realm realm、Web IDL型 T、アルゴリズム setAlgorithm および deleteAlgorithm を与えて行う:
  1. innerArray! ArrayCreate(0) とする。

  2. handlerOrdinaryObjectCreate(null, « [[Type]], [[SetAlgorithm]], [[DeleteAlgorithm]], [[BackingList]] ») とする。

  3. handler.[[Type]] に T を設定する。

  4. handler.[[SetAlgorithm]] に setAlgorithm を設定する。

  5. handler.[[DeleteAlgorithm]] に deleteAlgorithm を設定する。

  6. definePropertyCreateBuiltinFunction(§ 3.10.1 defineProperty の手順, « », realm) とする。

  7. ! CreateDataPropertyOrThrow(handler, "defineProperty", defineProperty) を実行する。

  8. deletePropertyCreateBuiltinFunction(§ 3.10.2 deleteProperty の手順, « », realm) とする。

  9. ! CreateDataPropertyOrThrow(handler, "deleteProperty", deleteProperty) を実行する。

  10. getCreateBuiltinFunction(§ 3.10.3 get の手順, « », realm) とする。

  11. ! CreateDataPropertyOrThrow(handler, "get", get) を実行する。

  12. getOwnPropertyDescriptorCreateBuiltinFunction(§ 3.10.4 getOwnPropertyDescriptor の手順, « », realm) とする。

  13. ! CreateDataPropertyOrThrow(handler, "getOwnPropertyDescriptor", getOwnPropertyDescriptor) を実行する。

  14. hasCreateBuiltinFunction(§ 3.10.5 has の手順, « », realm) とする。

  15. ! CreateDataPropertyOrThrow(handler, "has", has) を実行する。

  16. ownKeysCreateBuiltinFunction(§ 3.10.6 ownKeys の手順, « », realm) とする。

  17. ! CreateDataPropertyOrThrow(handler, "ownKeys", ownKeys) を実行する。

  18. preventExtensionsCreateBuiltinFunction(§ 3.10.7 preventExtensions の手順, « », realm) とする。

  19. ! CreateDataPropertyOrThrow(handler, "preventExtensions", preventExtensions) を実行する。

  20. setCreateBuiltinFunction(§ 3.10.8 set の手順, « », realm) とする。

  21. ! CreateDataPropertyOrThrow(handler, "set", set) を実行する。

  22. ! ProxyCreate(innerArray, handler) を返す。

3.10.1. defineProperty

definePropertyプロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O, P, descriptorObjを与える)は以下の通り:
  1. handlerthis の値とする。

  2. descriptor! ToPropertyDescriptor(descriptorObj) の結果とする。

  3. P が "length" なら:

    1. IsAccessorDescriptor(descriptor) が true なら false を返す。

    2. descriptor.[[Configurable]] が present かつ値が true なら false を返す。

    3. descriptor.[[Enumerable]] が present かつ値が true なら false を返す。

    4. descriptor.[[Writable]] が present かつ値が false なら false を返す。

    5. descriptor.[[Value]] が present なら、 lengthの設定handler, descriptor.[[Value]])の結果を返す。

    6. true を返す。

  4. P配列インデックスなら:

    1. IsAccessorDescriptor(descriptor) が true なら false を返す。

    2. descriptor.[[Configurable]] が present かつ値が false なら false を返す。

    3. descriptor.[[Enumerable]] が present かつ値が false なら false を返す。

    4. descriptor.[[Writable]] が present かつ値が false なら false を返す。

    5. descriptor.[[Value]] が present なら、 インデックス値の設定handler, P, descriptor.[[Value]])の結果を返す。

    6. true を返す。

  5. ? O.[[DefineOwnProperty]](P, descriptor) を返す。

3.10.2. deleteProperty

deletePropertyプロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O, Pを与える)は以下の通り:
  1. handlerthis の値とする。

  2. P が "length" なら false を返す。

  3. P配列インデックスなら:

    1. oldLenhandler.[[BackingList]] の サイズとする。

    2. index! ToUint32(P) の結果とする。

    3. indexoldLen − 1 なら false を返す。

    4. handler.[[DeleteAlgorithm]] のアルゴリズム手順を、handler.[[BackingList]][index] と index を与えて実行する。

    5. handler.[[BackingList]] から最後の要素を削除する。

    6. true を返す。

  4. ? O.[[Delete]](P) を返す。

3.10.3. get

getプロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O, P, Receiverを与える)は以下の通り:
  1. handlerthis の値とする。

  2. lengthhandler.[[BackingList]] の サイズとする。

  3. P が "length" なら length を返す。

  4. P配列インデックスなら:

    1. index! ToUint32(P) の結果とする。

    2. indexlength なら undefined を返す。

    3. jsValuehandler.[[BackingList]][index] をJavaScript値へ変換した結果とする。

    4. 上記のステップで例外が投げられることはない。

    5. jsValue を返す。

  5. ? O.[[Get]](P, Receiver) を返す。

3.10.4. getOwnPropertyDescriptor

getOwnPropertyDescriptorプロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O, Pを与える)は以下の通り:
  1. handlerthis の値とする。

  2. lengthhandler.[[BackingList]] の サイズとする。

  3. P が "length" なら ! FromPropertyDescriptor(PropertyDescriptor{[[Configurable]]: false, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: length }) を返す。

  4. P配列インデックスなら

    1. index! ToUint32(P) の結果とする。

    2. indexlength なら undefined を返す。

    3. jsValuehandler.[[BackingList]][index] をJavaScript値へ変換した結果とする。

    4. 上記のステップで例外が投げられることはない。

    5. FromPropertyDescriptor(PropertyDescriptor{[[Configurable]]: true, [[Enumerable]]: true, [[Writable]]: true, [[Value]]: jsValue }) を返す。

  5. FromPropertyDescriptor(? O.[[GetOwnProperty]](P)) を返す。

3.10.5. has

hasプロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O, Pを与える)は以下の通り:
  1. handlerthis の値とする。

  2. P が "length" なら true を返す。

  3. P配列インデックスなら:

    1. index! ToUint32(P) の結果とする。

    2. index < handler.[[BackingList]] の サイズ なら true を返す。

    3. false を返す。

  4. ? O.[[HasProperty]](P) を返す。

3.10.6. ownKeys

ownKeysプロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、Oを与える)は以下の通り:
  1. handlerthis の値とする。

  2. lengthhandler.[[BackingList]] の サイズとする。

  3. keys を空の リストとして初期化する。

  4. i を 0 とする。

  5. While i < length の間:

    1. Append ! ToString(i) を keys に追加する。

    2. ii + 1 にする。

  6. Extend keys! O.[[OwnPropertyKeys]]() の結果を追加する。

  7. CreateArrayFromList(keys) を返す。

3.10.7. preventExtensions

preventExtensionsプロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用)は以下の通り:
  1. false を返す。

3.10.8. set

setプロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O, P, V, Receiverを与える)は以下の通り:
  1. handlerthis の値とする。

  2. P が "length" なら lengthの設定handler, V)の結果を返す。

  3. P配列インデックスなら インデックス値の設定handler, P, V)の結果を返す。

  4. ? O.[[Set]](P, V, Receiver) を返す。

3.10.9. 抽象操作

lengthの設定 (オブザーバブル配列エキゾチックオブジェクトの handler, newLen を与える):
  1. uint32Len? ToUint32(newLen) の結果とする。

  2. numberLen? ToNumber(newLen) の結果とする。

  3. uint32LennumberLen なら RangeError 例外を投げる。

  4. oldLenhandler.[[BackingList]] の サイズとする。

  5. uint32Len > oldLen なら false を返す。

  6. indexToDeleteoldLen − 1 とする。

  7. While indexToDeleteuint32Len の間:

    1. handler.[[DeleteAlgorithm]] の手順を、handler.[[BackingList]][indexToDelete]、indexToDelete を与えて実行する。

    2. handler.[[BackingList]] から最後の要素を削除する。

    3. indexToDeleteindexToDelete − 1 にする。

  8. true を返す。

インデックス値の設定 (オブザーバブル配列エキゾチックオブジェクトの handler, P, V を与える):
  1. oldLenhandler.[[BackingList]] の サイズとする。

  2. index! ToUint32(P) の結果とする。

  3. index > oldLen なら false を返す。

  4. idlValueVを handler.[[Type]] 型のIDL値に変換した結果とする。

  5. index < oldLen なら:

    1. handler.[[DeleteAlgorithm]] の手順を、handler.[[BackingList]][index]、index を与えて実行する。

  6. handler.[[SetAlgorithm]] の手順を、idlValueindex を与えて実行する。

  7. index = oldLen なら idlValueを handler.[[BackingList]] に追加する。

  8. それ以外の場合、handler.[[BackingList]][index] を idlValue に設定する。

  9. true を返す。

3.11. コールバックインターフェース

§ 2.12 インターフェースを実装するオブジェクトで説明されている通り、 コールバックインターフェースは 任意のJavaScriptオブジェクトによってスクリプトで実装できる。 以下は、あるオブジェクトに対して コールバックインターフェースoperation を呼び出す場合のケースである:

JavaScriptオブジェクトは、定数に対応する プロパティを持っていなくても、 その定数を宣言している コールバックインターフェースを実装したとみなされることに注意。

Web IDL 引数リストは、 各値がIDL値または特殊値“missing”(省略されたオプション引数を表す)のいずれかである値の リストである。

Web IDL 引数リストを JavaScript 引数リストに変換するには、 Web IDL 引数リスト args を与え、以下の手順を行う:
  1. jsArgs を空の リストとする。

  2. i を 0 とする。

  3. count を 0 とする。

  4. i < argsサイズ の間:

    1. args[i] が特殊値“missing”なら、undefinedjsArgs に追加する。

    2. それ以外の場合、args[i] はIDL値:

      1. convertResultargs[i] をJavaScript値に変換した結果とする(例外は再スロー)。

      2. convertResultjsArgs に追加する。

      3. counti + 1 に設定する。

    3. ii + 1 にする。

  5. jsArgscount個の要素になるよう切り捨てる。

  6. jsArgs を返す。

ユーザーオブジェクトの operation を呼び出すには、 コールバックインターフェース型value、 operation名 opNameWeb IDL 引数リスト args、オプションの コールバックthis値 thisArg を与え、以下の手順を実行する。 これらの手順はIDL値を返すか例外を投げる。

  1. completion を未初期化変数とする。

  2. thisArg が与えられていなければ thisArgundefined にする。

  3. Ovalue に対応するJavaScriptオブジェクトとする。

  4. realmO関連realmとする。

  5. relevant settingsrealm設定オブジェクトとする。

  6. stored settingsvalueコールバックコンテキストとする。

  7. スクリプトの実行準備relevant settings で行う。

  8. コールバックの実行準備stored settings で行う。

  9. XO とする。

  10. IsCallable(O) が false なら:

    1. getResultCompletion(Get(O, opName)) とする。

    2. getResultabrupt completion なら completiongetResult を設定し return のステップへジャンプする。

    3. XgetResult.[[Value]] に設定する。

    4. IsCallable(X) が false なら completionCompletion Record { [[Type]]: throw, [[Value]]: 新規 TypeError オブジェクト, [[Target]]: 空 } を設定し return のステップへジャンプする。

    5. thisArgO に設定(与えられた値を上書き)。

  11. jsArgsargsをJavaScript引数リストに変換した結果とする。例外が投げられた場合、 completion に投げられた例外のcompletion値を設定し return のステップへジャンプする。

  12. callResultCompletion(Call(X, thisArg, jsArgs)) とする。

  13. callResultabrupt completion なら completioncallResult を設定し return のステップへジャンプする。

  14. completioncallResult.[[Value]] をoperationの戻り値型のIDL値に変換した結果に設定する。例外が投げられた場合はcompletionに例外のcompletion値を設定する。

  15. Return: この時点で completion はIDL値か abrupt completion となる。

    1. コールバック実行後のクリーンアップstored settings で行う。

    2. スクリプト実行後のクリーンアップrelevant settings で行う。

    3. completionがIDL値ならcompletionを返す。

    4. completionが abrupt completion で、operationの戻り値型が promise型でない場合、completion.[[Value]] をthrowする。

    5. rejectedPromise! Call(%Promise.reject%, %Promise%, «completion.[[Value]]») とする。

    6. rejectedPromise をoperationの戻り値型へ変換した結果を返す。

3.11.1. レガシーコールバックインターフェースオブジェクト

ある コールバックインターフェース が ある realmで公開されていて、 そのインターフェース上に 定数が定義されている場合、 対応するプロパティが realmグローバルオブジェクト 上に存在する。 このプロパティ名は コールバックインターフェースの識別子であり、 その値は レガシーコールバックインターフェースオブジェクトである。

特定の コールバックインターフェースレガシーコールバックインターフェースオブジェクト組み込み関数オブジェクトである。 そのプロパティには、そのインターフェースで定義されている 定数が対応しており、詳細は § 3.7.5 定数 に記載されている。

注: レガシーコールバックインターフェースオブジェクト関数オブジェクトであるため、 typeof演算子を適用すると "function" を返す。

特定の コールバックインターフェース interface識別子 idrealm realm)の レガシーコールバックインターフェースオブジェクトは、以下の手順で 生成される

  1. steps を以下のステップとする:

    1. TypeError例外を投げる。

  2. FCreateBuiltinFunction(steps, « », realm) とする。

  3. SetFunctionName(F, id) を実行する。

  4. SetFunctionLength(F, 0) を実行する。

  5. 定数の定義interface, F, realm)を実行する。

  6. F を返す。

3.12. コールバック関数の呼び出し

JavaScriptの 呼び出し可能オブジェクトが コールバック関数値として利用される場合は、 operationコールバックインターフェース値上で呼び出される場合(前節参照)と 似た方法で呼び出される。

呼び出す には コールバック関数型callableWeb IDL 引数リスト args、 例外動作 exceptionBehavior("report"または"rethrow")、 オプションの コールバックthis値 thisArg を与え、以下の手順を実行する。 これらの手順はIDL値を返すか例外を投げる。

exceptionBehavior 引数は、callable戻り値型promise型でない場合に限り必須となる。 callable の戻り値型が undefined または any 以外なら 必ず "rethrow" でなければならない。

呼び出し元がこれを正しく指定していない場合、現行標準では指定が必須な場面では "rethrow" を指定したものと見なすべきである。
  1. completion を未初期化変数とする。

  2. thisArg が与えられていなければ thisArgundefined にする。

  3. Fcallable に対応するJavaScriptオブジェクトとする。

  4. IsCallable(F) が false なら:

    1. 注: これはコールバック関数が [LegacyTreatNonObjectAsNull] 属性付きの属性から来た場合のみ起こり得る。

    2. undefined をコールバック関数の戻り値型に変換した結果を返す。

  5. realmF関連realmとする。

  6. relevant settingsrealm設定オブジェクトとする。

  7. stored settingscallableコールバックコンテキストとする。

  8. スクリプトの実行準備relevant settings で行う。

  9. コールバックの実行準備stored settings で行う。

  10. jsArgsargsをJavaScript引数リストに変換した結果とする。例外が投げられた場合、 completion に投げられた例外のcompletion値を設定し return のステップへジャンプする。

  11. callResultCompletion(Call(F, thisArg, jsArgs)) とする。

  12. callResultabrupt completion なら completioncallResult を設定し return のステップへジャンプする。

  13. completioncallResult.[[Value]] をコールバック関数の戻り値型のIDL値に変換した結果に設定する。例外が投げられた場合はcompletionに例外のcompletion値を設定する。

  14. Return: この時点で completion はIDL値か abrupt completion となる。

    1. コールバック実行後のクリーンアップstored settings で行う。

    2. スクリプト実行後のクリーンアップrelevant settings で行う。

    3. completionがIDL値ならcompletionを返す。

    4. Assert: completionは abrupt completion であること。

    5. exceptionBehaviorが"rethrow"なら completion.[[Value]] をthrowする。

    6. それ以外で exceptionBehaviorが"report"なら:

      1. Assert: callable の 戻り値型undefined または any であること。

      2. 例外の報告 completion.[[Value]] を realmグローバルオブジェクトに対して行う。

      3. 一意な undefined IDL値を返す。

    7. Assert: callable の 戻り値型promise型であること。

    8. rejectedPromise! Call(%Promise.reject%, %Promise%, «completion.[[Value]]») とする。

    9. rejectedPromise をコールバック関数の戻り値型へ変換した結果を返す。

一部のコールバック関数は コンストラクタとして使われる場合がある。その場合、戻り値型が promise型であってはならない。

コールバック関数を構築するには コールバック関数型callableWeb IDL 引数リスト args を与え、以下の手順を実行する。 これらの手順はIDL値を返すか例外を投げる。

  1. completion を未初期化変数とする。

  2. Fcallable に対応するJavaScriptオブジェクトとする。

  3. IsConstructor(F) が false なら TypeError 例外を投げる。

  4. realmF関連realmとする。

  5. relevant settingsrealm設定オブジェクトとする。

  6. stored settingscallableコールバックコンテキストとする。

  7. スクリプトの実行準備relevant settings で行う。

  8. コールバックの実行準備stored settings で行う。

  9. jsArgsargsをJavaScript引数リストに変換した結果とする。例外が投げられた場合、 completion に投げられた例外のcompletion値を設定し return のステップへジャンプする。

  10. callResultCompletion(Construct(F, jsArgs)) とする。

  11. callResultabrupt completion なら completioncallResult を設定し return のステップへジャンプする。

  12. completioncallResult.[[Value]] をコールバック関数の戻り値型のIDL値に変換した結果に設定する。例外が投げられた場合はcompletionに例外のcompletion値を設定する。

  13. Return: この時点で completion はIDL値か abrupt completion となる。

    1. コールバック実行後のクリーンアップstored settings で行う。

    2. スクリプト実行後のクリーンアップrelevant settings で行う。

    3. completionが abrupt completion なら completion.[[Value]] をthrowする。

    4. completionを返す。

3.13. 名前空間

ある 名前空間 が特定の realmで公開されている場合、 対応するプロパティがその realmグローバルオブジェクト上に存在する。 プロパティ名はその名前空間の 識別子であり、値は 名前空間オブジェクトと呼ばれるオブジェクトである。

名前空間オブジェクトの特徴は § 3.13.1 名前空間オブジェクト に記載されている。

3.13.1. 名前空間オブジェクト

特定の 名前空間 namespacerealm realm の 名前空間オブジェクトは、以下の手順で 生成される

  1. namespaceObjectOrdinaryObjectCreate(realm.[[Intrinsics]].[[%Object.prototype%]]) とする。

  2. 通常の属性を定義するnamespace, namespaceObject, realm)を実行する。

  3. 通常の操作を定義するnamespace, namespaceObject, realm)を実行する。

  4. 定数の定義namespace, namespaceObject, realm)を実行する。

  5. 公開された インターフェース interface で、 [LegacyNamespace] 拡張属性の引数として namespace の識別子が指定されているものについて:

    1. idinterface識別子とする。

    2. interfaceObjectインターフェースオブジェクトの生成interface, id, realm)の結果とする。

    3. DefineMethodProperty(namespaceObject, id, interfaceObject, false) を実行する。

  6. namespaceObject を返す。

クラス文字列(class string)は 名前空間オブジェクト名前空間識別子である。

3.14. 例外

3.14.1. DOMException のカスタムバインディング

JavaScriptバインディングにおいて、DOMExceptionインターフェースプロトタイプオブジェクトの [[Prototype]] 内部スロット%Error.prototype% に設定される(インターフェースプロトタイプオブジェクト生成抽象操作に従う)。 また、他の組み込み例外と同様に [[ErrorData]] スロットも持つ。

さらに、実装がネイティブの Error オブジェクトに特別な機能や非標準のプロパティ(例えば stack プロパティ)を与える場合、 それらも DOMException オブジェクト上で公開すべきである。

3.14.2. 例外オブジェクト

単純例外は 対応する型のネイティブJavaScriptオブジェクトとして表現される。

DOMExceptionプラットフォームオブジェクトとして DOMException インターフェースを実装する。

3.14.3. 例外の生成とthrow

単純例外の生成(型 T の場合):
  1. message を例外状況に適した 実装依存メッセージとする。呼び出し元仕様は、実装がこのメッセージを構築する際の参考情報を持つ場合がある。

    実装はこのメッセージを構築する際、クロスオリジンフレームのURLやユーザーを特定できる情報など、機密性やセキュリティに関する情報を漏らさないよう注意すること。

  2. args を « message » とする。

  3. constructor現行realm.[[Intrinsics]].[[%T%]] とする。

  4. ! Construct(constructor, args) を返す。

DOMExceptionの生成(文字列 name を与える):
  1. Assert: nameDOMException 名テーブルに含まれている。

  2. ex現行realmで新規作成した DOMException とする。

  3. exnamename に設定する。

  4. exmessage を例外状況に適した 実装依存メッセージに設定する。呼び出し元仕様は、実装がこのメッセージを構築する際の参考情報を持つ場合がある。

    実装はこのメッセージを構築する際、クロスオリジンフレームのURLやユーザーを特定できる情報など、機密性やセキュリティに関する情報を漏らさないよう注意すること。

  5. ex を返す。

DOMException派生インターフェースの生成インターフェース 識別子 type、追加の初期化指示を与える):
  1. ex現行realmで新規作成した type識別子の インターフェース インスタンスとする。

  2. exnametype に設定する。

  3. exmessage を例外状況に適した 実装依存メッセージに設定する。呼び出し元仕様は、実装がこのメッセージを構築する際の参考情報を持つ場合がある。

    実装はこのメッセージを構築する際、クロスオリジンフレームのURLやユーザーを特定できる情報など、機密性やセキュリティに関する情報を漏らさないよう注意すること。

  4. 呼び出し元による追加の初期化処理を ex に対して実施する。

  5. ex を返す。

例外のthrow例外の場合):
  1. O例外の生成(同じ引数)で得る。

  2. O をthrowする。

上記アルゴリズムにより、例外を表すオブジェクト関数オブジェクトの外に伝播する際は、その realm(関数オブジェクトのrealm、すなわち関数実行時の 現行realm)に紐づくものに限定される。 例えば以下のIDL定義を考える:

[Exposed=Window]
interface MathUtils {
  // xが負の場合は "NotSupportedError" DOMException をthrowする。
  double computeSquareRoot(double x);
};

もし異なる realmMathUtils オブジェクトに対して computeSquareRoot を適用した場合、 throwされる例外はメソッドのrealm(呼び出されたメソッドのrealm)に属するものであり、 適用されたオブジェクトのrealmではない:

const myMU = window.getMathUtils();          // このrealmのMathUtilsオブジェクト
const otherMU = otherWindow.getMathUtils();  // 異なるrealmのMathUtilsオブジェクト

myMU instanceof Object;                      // trueになる
otherMU instanceof Object;                   // falseになる
otherMU instanceof otherWindow.Object;       // trueになる

try {
  otherMU.doComputation.call(myMU, -1);
} catch (e) {
  console.assert(!(e instanceof DOMException));
  console.assert(e instanceof otherWindow.DOMException);
}

3.14.4. 例外の扱い

特に指定がない限り、 本書の要件によりJavaScriptランタイムセマンティクスが呼び出され、 例外がthrowされて終了した場合は、その例外は呼び出し元へ伝播し、そこでcatchされなければさらにその呼び出し元へ、以降も同様に伝播しなければならない。

文書の慣例に従い、本書で定義されるアルゴリズムはthrowされた例外を捕捉する場合があり、その際には 例外がthrowされた場合に取るべき具体的な手順を記述するか、 abrupt completionを明示的に扱う。

次のIDLフラグメントは2つのインターフェースと1つの例外を定義する。 ExceptionThrowervalueOf属性は、値の取得を試みるたびに例外をthrowするよう定義されている。

[Exposed=Window]
interface Dahut {
  attribute DOMString type;
};

[Exposed=Window]
interface ExceptionThrower {
  // この属性は常に NotSupportedError をthrowし値を返さない。
  attribute long valueOf;
};

このインターフェースをサポートするJavaScript実装があると仮定すると、以下のコードは例外の扱い方を示している:

var d = getDahut();              // Dahut のインスタンスを取得
var et = getExceptionThrower();  // ExceptionThrower のインスタンスを取得

try {
  d.type = { toString: function() { throw "abc"; } };
} catch (e) {
  // ここで文字列 "abc" がcatchされる。ネイティブオブジェクトから文字列へ変換する過程で無名関数が呼び出され、[[DefaultValue]]・ToPrimitive・ToStringアルゴリズムは例外をcatchしない。
}

try {
  d.type = { toString: { } };
} catch (e) {
  // ここで例外がcatchされる。toStringプロパティ値のネイティブオブジェクトに対して[[Call]]を呼ぶ際に例外が発生するため。
}

try {
  d.type = Symbol();
} catch (e) {
  // ここで例外がcatchされる。Symbol値に対してJavaScriptのToString抽象操作を呼ぶ際に例外が発生するため。
}

d.type = et;
// ここでは未catchの "NotSupportedError" DOMException がthrowされる。
// [[DefaultValue]]アルゴリズムがExceptionThrowerオブジェクトの"valueOf"プロパティ値の取得を試みるためで、この例外はこのコードブロックの外へ伝播する。

4. 共通定義

本節では、すべての適合実装がサポートしなければならない共通定義について記載する。

4.1. ArrayBufferView

typedef (Int8Array or Int16Array or Int32Array or
         Uint8Array or Uint16Array or Uint32Array or Uint8ClampedArray or
         BigInt64Array or BigUint64Array or
         Float16Array or Float32Array or Float64Array or DataView) ArrayBufferView;

ArrayBufferView typedefは ArrayBuffer または SharedArrayBuffer ([AllowShared]使用時)に対してビューを提供するオブジェクトを表すために使用される。

4.2. BufferSource

typedef (ArrayBufferView or ArrayBuffer) BufferSource;

BufferSource typedefは ArrayBuffer そのもの、または ArrayBuffer へのビューを提供するオブジェクトを表すために使用される。

注: [AllowShared] は BufferSource では利用できない。ArrayBufferが対応していないためである。 代わりに AllowSharedBufferSource を使用すること。

4.3. AllowSharedBufferSource

typedef (ArrayBuffer or SharedArrayBuffer or [AllowShared] ArrayBufferView) AllowSharedBufferSource;

AllowSharedBufferSource typedefは ArrayBuffer または SharedArrayBuffer そのもの、またはそれらへのビューを提供するオブジェクトを表すために使用される。

4.4. DOMException

DOMException 型は以下のIDLフラグメントで定義されるインターフェース型である:

[Exposed=*,
 Serializable]
interface DOMException { // JavaScriptバインディングの注意事項は後述
  constructor(optional DOMString message = "", optional DOMString name = "Error");
  readonly attribute DOMString name;
  readonly attribute DOMString message;
  readonly attribute unsigned short code;

  const unsigned short INDEX_SIZE_ERR = 1;
  const unsigned short DOMSTRING_SIZE_ERR = 2;
  const unsigned short HIERARCHY_REQUEST_ERR = 3;
  const unsigned short WRONG_DOCUMENT_ERR = 4;
  const unsigned short INVALID_CHARACTER_ERR = 5;
  const unsigned short NO_DATA_ALLOWED_ERR = 6;
  const unsigned short NO_MODIFICATION_ALLOWED_ERR = 7;
  const unsigned short NOT_FOUND_ERR = 8;
  const unsigned short NOT_SUPPORTED_ERR = 9;
  const unsigned short INUSE_ATTRIBUTE_ERR = 10;
  const unsigned short INVALID_STATE_ERR = 11;
  const unsigned short SYNTAX_ERR = 12;
  const unsigned short INVALID_MODIFICATION_ERR = 13;
  const unsigned short NAMESPACE_ERR = 14;
  const unsigned short INVALID_ACCESS_ERR = 15;
  const unsigned short VALIDATION_ERR = 16;
  const unsigned short TYPE_MISMATCH_ERR = 17;
  const unsigned short SECURITY_ERR = 18;
  const unsigned short NETWORK_ERR = 19;
  const unsigned short ABORT_ERR = 20;
  const unsigned short URL_MISMATCH_ERR = 21;
  const unsigned short QUOTA_EXCEEDED_ERR = 22;
  const unsigned short TIMEOUT_ERR = 23;
  const unsigned short INVALID_NODE_TYPE_ERR = 24;
  const unsigned short DATA_CLONE_ERR = 25;
};

注: § 3.14.1 DOMExceptionのカスタムバインディングで述べたように、JavaScriptバインディングは通常のインターフェース型に加えて追加要件を課す。

DOMException オブジェクトは nameおよび message(いずれも文字列)を持つ。

new DOMException(message, name) のコンストラクタ手順は以下の通り:

  1. thisnamename に設定する。

  2. thismessagemessage に設定する。

name のgetter手順は thisname を返す。

message のgetter手順は thismessage を返す。

code のgetter手順は、DOMException名テーブルthisname に対応するレガシーコード、該当エントリがなければ0を返す。

DOMException オブジェクトはシリアライズ可能オブジェクトである。

そのシリアライズ手順は、valueserializedを与え、次の通り:

  1. valuenameserialized.[[Name]] を設定する。
  2. valuemessageserialized.[[Message]] を設定する。
  3. もし serialized に他のデータが添付されていれば、それをデシリアライズして value に添付する。

4.5. Function

callback Function = any (any... arguments);

Function コールバック関数 型は、引数として何が渡されても、また返される値の種類にも制限がない関数値を表現するために使われる。

4.6. VoidFunction

callback VoidFunction = undefined ();

VoidFunction コールバック関数 型は、引数を取らず値も返さない関数値を表現するために使われる。

5. 拡張性

この節は参考情報です。

言語バインディング要件への拡張は、本書で定義されたものと衝突しない 拡張属性 を用いて指定できる。 プライベートやプロジェクト固有で使う拡張は、他の仕様書に現れる IDLフラグメント には含めるべきではない。他の仕様で利用が必要な拡張は、現行標準の次版への採用も視野に Web IDL の担当グループ(執筆時点では W3C Web Platform Working Group) と調整することを推奨する。

IDL言語の他の側面への拡張は強く推奨されない。

6. レガシー構造

この節は参考情報です。

レガシーWeb IDL構造は、レガシーWebプラットフォーム機能を仕様化するためだけに存在する。 これらは一般的に "Legacy" という文字列で始まる。 レガシーWeb IDL構造は、レガシーWebプラットフォーム機能の挙動を仕様化するため、またはその機能との整合性のために必要な場合以外は 仕様書で使用することは強く推奨されない。 レガシーWeb IDL構造の使用を検討する編集者は、事前に issueを登録 して議論することが強く推奨される。

構造をレガシーとマークすること自体は、その構造が現行標準からすぐに削除されることを意味するものではない。 ただし、様々な指標により、当該構造が仕様から削除可能になった場合や、 レガシーでないWeb IDL構造に置き換えられる場合は、削除候補となることを示唆するものである。

7. 本仕様書の参照方法

この節は参考情報です。

Webプラットフォームインターフェースを1つ以上の IDLフラグメント で定義する他の仕様書は、本仕様書を参照することが期待される。 それらの仕様書では、IDLが本仕様書に記載された通りに解釈されることを示すため、 以下のような文章を含めることが推奨される:

本仕様書の付録Aに記載されたIDLフラグメントは、本仕様書の標準参照に定義されたIDLフラグメントと併せて、 “Web IDL”現行標準に記載された 適合IDLフラグメント集合 として解釈される必要がある。 [WEBIDL]

さらに、参照仕様書のユーザーエージェントの適合クラスについても 本仕様書の 適合実装クラスとリンクすることが推奨される:

FooMLユーザーエージェントの適合実装は、本仕様書の付録AのIDLフラグメントについても、 “Web IDL”現行標準に記載された 適合実装 である必要がある。 [WEBIDL]

8. プライバシーおよびセキュリティに関する考慮事項

本仕様はJavaScriptとIDL値の間の変換層を定義する。不適切な実装はセキュリティ上の問題につながる可能性がある。

本仕様は、any型や object型のIDL型を通じて JavaScript値を直接扱う能力も提供する。これらの値を安全に扱わなければ、セキュリティ上の問題につながる。 特に、ユーザースクリプトは、これらの値のほぼすべての操作に応じて実行され、仕様や実装の期待を損なう可能性がある。

本仕様は SharedArrayBuffer オブジェクトとの相互作用も可能にしており、これらを用いたタイミング攻撃のリスクがある。 これらのオブジェクトを利用する仕様は、そのような攻撃への考慮が必要である。

謝辞

この節は参考情報です。

編集者は以下の方々の本仕様への貢献に感謝します: Glenn Adams, David Andersson, Jake Archibald, Tab Atkins-Bittner, L. David Baron, Art Barstow, Nils Barth, Robin Berjon, David Bruant, Jan-Ivar Bruaroey, Marcos Cáceres, Giovanni Campagna, François Daoust, Domenic Denicola, Chris Dumez, Michael Dyck, Daniel Ehrenberg, Brendan Eich, João Eiras, Gorm Haug Eriksen, Sigbjorn Finne, David Flanagan, Aryeh Gregor, Dimitry Golubovsky, James Graham, Aryeh Gregor, Tiancheng “Timothy” Gu, Kartikaya Gupta, Marcin Hanclik, Jed Hartman, Stefan Haustein, Dominique Hazaël-Massieux, Ian Hickson, Björn Höhrmann, Kyle Huey, Lachlan Hunt, Oliver Hunt, Jim Jewett, Wolfgang Keller, Anne van Kesteren, Olav Junker Kjær, Takayoshi Kochi, Magnus Kristiansen, Raphael Kubo da Costa, Takeshi Kurosawa, Yves Lafon, Travis Leithead, Jim Ley, Kevin Lindsey, Jens Lindström, Peter Linss, 呂康豪 (Kang-Hao Lu), Kyle Machulis, Darien Maillet Valentine, Mark Miller, Ms2ger, Andrew Oakley, 岡坂 史紀 (Shiki Okasaka), Jason Orendorff, Olli Pettay, Simon Pieters, Andrei Popescu, François Remy, Tim Renouf, Jeremy Roman, Tim Ruffles, Alex Russell, Takashi Sakamoto, Doug Schepers, Jonas Sicking, Garrett Smith, Sam Sneddon, Jungkee Song, Josh Soref, Maciej Stachowiak, Austin Sullivan, Anton Tayanovskyy, triple-underscore, Peter Van der Beken, Jeff Walden, Allen Wirfs-Brock, Jeffrey Yasskin, Collin Xu。

編集者が不在の間、本仕様の維持をしていただいたSam Weinig氏にも特に感謝します。

この標準は Edgar Chen (Mozilla, echen@mozilla.com) と Tiancheng "Timothy" Gu (timothygu99@gmail.com) によって執筆され、 Boris Zbarsky (bzbarsky@mit.edu), Cameron McCormack (cam@mcc.id.au), Tobie Langel (tobie@unlockopen.com) らによる大幅な貢献があります。

IDL文法

この節では、開始記号 Definitions が、全体の IDLフラグメント にマッチする LL(1)文法を定義する。

文法の各生成規則の右辺は、ゼロでない個数の終端記号と非終端記号の並び、または ε(何もないことを表す)である。 大文字で始まる記号は非終端記号である。 等幅フォントで記載された記号は終端記号である。 小文字で始まるサンセリフ体の記号は、Perl 5正規表現構文 [PERLRE] を用いた正規表現でマッチする終端記号である:

integer = /-?([1-9][0-9]*|0[Xx][0-9A-Fa-f]+|0[0-7]*)/
decimal = /-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)/
identifier = /[_-]?[A-Za-z][0-9A-Z_a-z-]*/
string = /"[^"]*"/
whitespace = /[\t\n\r ]+/
comment = /\/\/.*|\/\*(.|\n)*?\*\//
other = /[^\t\n\r 0-9A-Za-z]/

トークナイザは スカラー値の列で動作する。 トークナイズ時は、可能な限り最長一致でマッチを行う必要がある。例えば、入力テキストが「a1」の場合は、identifier 1つとしてトークナイズされ、 identifierintegerに分割されない。 最長一致が上記の名前付き終端記号または文法の他の終端記号いずれかに一致する場合は、後者としてトークナイズしなければならない。 したがって、入力「long」は終端記号 longとしてトークナイズされ、 "long"という identifier にはならない。 また「.」は終端記号 .としてトークナイズされ、 otherにはならない。

IDL構文は大文字・小文字を区別する。文法で使われる等幅フォント終端記号や identifier 終端の値も同様である。 例えば、入力「Const」は identifierとしてトークナイズされ、 終端記号 constにはならない。 interface識別子が "A"なら"a"とは区別される。 また 拡張属性 [legacyfactoryfunction]は [LegacyFactoryFunction] 拡張属性として認識されない。

暗黙的に、入力テキストの各終端記号の間には任意個数の whitespacecomment 終端が許される。これらの whitespacecomment 終端はパース時に無視される。

以下のLL(1)文法は、開始記号 Definitions から始まり、 IDLフラグメントにマッチする:

Definitions ::
    ExtendedAttributeList Definition Definitions
    ε

Definition ::
    CallbackOrInterfaceOrMixin
    Namespace
    Partial
    Dictionary
    Enum
    Typedef
    IncludesStatement

ArgumentNameKeyword ::
    attribute
    callback
    const
    constructor
    deleter
    dictionary
    enum
    getter
    includes
    inherit
    interface
    iterable
    maplike
    mixin
    namespace
    partial
    readonly
    required
    setlike
    setter
    static
    stringifier
    typedef
    unrestricted

CallbackOrInterfaceOrMixin ::
    callback CallbackRestOrInterface
    interface InterfaceOrMixin

InterfaceOrMixin ::
    InterfaceRest
    MixinRest

InterfaceRest ::
    identifier Inheritance { InterfaceMembers } ;

Partial ::
    partial PartialDefinition

PartialDefinition ::
    interface PartialInterfaceOrPartialMixin
    PartialDictionary
    Namespace

PartialInterfaceOrPartialMixin ::
    PartialInterfaceRest
    MixinRest

PartialInterfaceRest ::
    identifier { PartialInterfaceMembers } ;

InterfaceMembers ::
    ExtendedAttributeList InterfaceMember InterfaceMembers
    ε

InterfaceMember ::
    PartialInterfaceMember
    Constructor

PartialInterfaceMembers ::
    ExtendedAttributeList PartialInterfaceMember PartialInterfaceMembers
    ε

PartialInterfaceMember ::
    Const
    Operation
    Stringifier
    StaticMember
    Iterable
    AsyncIterable
    ReadOnlyMember
    ReadWriteAttribute
    ReadWriteMaplike
    ReadWriteSetlike
    InheritAttribute

Inheritance ::
    : identifier
    ε

MixinRest ::
    mixin identifier { MixinMembers } ;

MixinMembers ::
    ExtendedAttributeList MixinMember MixinMembers
    ε

MixinMember ::
    Const
    RegularOperation
    Stringifier
    OptionalReadOnly AttributeRest

IncludesStatement ::
    identifier includes identifier ;

CallbackRestOrInterface ::
    CallbackRest
    interface identifier { CallbackInterfaceMembers } ;

CallbackInterfaceMembers ::
    ExtendedAttributeList CallbackInterfaceMember CallbackInterfaceMembers
    ε

CallbackInterfaceMember ::
    Const
    RegularOperation

Const ::
    const ConstType identifier = ConstValue ;

ConstValue ::
    BooleanLiteral
    FloatLiteral
    integer

BooleanLiteral ::
    true
    false

FloatLiteral ::
    decimal
    -Infinity
    Infinity
    NaN

ConstType ::
    PrimitiveType
    identifier

ReadOnlyMember ::
    readonly ReadOnlyMemberRest

ReadOnlyMemberRest ::
    AttributeRest
    MaplikeRest
    SetlikeRest

ReadWriteAttribute ::
    AttributeRest

InheritAttribute ::
    inherit AttributeRest

AttributeRest ::
    attribute TypeWithExtendedAttributes AttributeName ;

AttributeName ::
    AttributeNameKeyword
    identifier

AttributeNameKeyword ::
    required

OptionalReadOnly ::
    readonly
    ε

DefaultValue ::
    ConstValue
    string
    [ ]
    { }
    null
    undefined

Operation ::
    RegularOperation
    SpecialOperation

RegularOperation ::
    Type OperationRest

SpecialOperation ::
    Special RegularOperation

Special ::
    getter
    setter
    deleter

OperationRest ::
    OptionalOperationName ( ArgumentList ) ;

OptionalOperationName ::
    OperationName
    ε

OperationName ::
    OperationNameKeyword
    identifier

OperationNameKeyword ::
    includes

ArgumentList ::
    Argument Arguments
    ε

Arguments ::
    , Argument Arguments
    ε

Argument ::
    ExtendedAttributeList ArgumentRest

ArgumentRest ::
    optional TypeWithExtendedAttributes ArgumentName Default
    Type Ellipsis ArgumentName

ArgumentName ::
    ArgumentNameKeyword
    identifier

Ellipsis ::
    ...
    ε

Constructor ::
    constructor ( ArgumentList ) ;

Stringifier ::
    stringifier StringifierRest

StringifierRest ::
    OptionalReadOnly AttributeRest
    ;

StaticMember ::
    static StaticMemberRest

StaticMemberRest ::
    OptionalReadOnly AttributeRest
    RegularOperation

Iterable ::
    iterable < TypeWithExtendedAttributes OptionalType > ;

OptionalType ::
    , TypeWithExtendedAttributes
    ε

AsyncIterable ::
    async_iterable < TypeWithExtendedAttributes OptionalType > OptionalArgumentList ;

OptionalArgumentList ::
    ( ArgumentList )
    ε

ReadWriteMaplike ::
    MaplikeRest

MaplikeRest ::
    maplike < TypeWithExtendedAttributes , TypeWithExtendedAttributes > ;

ReadWriteSetlike ::
    SetlikeRest

SetlikeRest ::
    setlike < TypeWithExtendedAttributes > ;

Namespace ::
    namespace identifier { NamespaceMembers } ;

NamespaceMembers ::
    ExtendedAttributeList NamespaceMember NamespaceMembers
    ε

NamespaceMember ::
    RegularOperation
    readonly AttributeRest
    Const

Dictionary ::
    dictionary identifier Inheritance { DictionaryMembers } ;

DictionaryMembers ::
    DictionaryMember DictionaryMembers
    ε

DictionaryMember ::
    ExtendedAttributeList DictionaryMemberRest

DictionaryMemberRest ::
    required TypeWithExtendedAttributes identifier ;
    Type identifier Default ;

PartialDictionary ::
    dictionary identifier { DictionaryMembers } ;

Default ::
    = DefaultValue
    ε

Enum ::
    enum identifier { EnumValueList } ;

EnumValueList ::
    string EnumValueListComma

EnumValueListComma ::
    , EnumValueListString
    ε

EnumValueListString ::
    string EnumValueListComma
    ε

CallbackRest ::
    identifier = Type ( ArgumentList ) ;

Typedef ::
    typedef TypeWithExtendedAttributes identifier ;

Type ::
    SingleType
    UnionType Null

TypeWithExtendedAttributes ::
    ExtendedAttributeList Type

SingleType ::
    DistinguishableType
    any
    PromiseType

UnionType ::
    ( UnionMemberType or UnionMemberType UnionMemberTypes )

UnionMemberType ::
    ExtendedAttributeList DistinguishableType
    UnionType Null

UnionMemberTypes ::
    or UnionMemberType UnionMemberTypes
    ε

DistinguishableType ::
    PrimitiveType Null
    StringType Null
    identifier Null
    sequence < TypeWithExtendedAttributes > Null
    async_sequence < TypeWithExtendedAttributes > Null
    object Null
    symbol Null
    BufferRelatedType Null
    FrozenArray < TypeWithExtendedAttributes > Null
    ObservableArray < TypeWithExtendedAttributes > Null
    RecordType Null
    undefined Null

PrimitiveType ::
    UnsignedIntegerType
    UnrestrictedFloatType
    boolean
    byte
    octet
    bigint

UnrestrictedFloatType ::
    unrestricted FloatType
    FloatType

FloatType ::
    float
    double

UnsignedIntegerType ::
    unsigned IntegerType
    IntegerType

IntegerType ::
    short
    long OptionalLong

OptionalLong ::
    long
    ε

StringType ::
    ByteString
    DOMString
    USVString

PromiseType ::
    Promise < Type >

RecordType ::
    record < StringType , TypeWithExtendedAttributes >

Null ::
    ?
    ε

BufferRelatedType ::
    ArrayBuffer
    SharedArrayBuffer
    DataView
    Int8Array
    Int16Array
    Int32Array
    Uint8Array
    Uint16Array
    Uint32Array
    Uint8ClampedArray
    BigInt64Array
    BigUint64Array
    Float16Array
    Float32Array
    Float64Array

ExtendedAttributeList ::
    [ ExtendedAttribute ExtendedAttributes ]
    ε

ExtendedAttributes ::
    , ExtendedAttribute ExtendedAttributes
    ε

ExtendedAttribute ::
    ( ExtendedAttributeInner ) ExtendedAttributeRest
    [ ExtendedAttributeInner ] ExtendedAttributeRest
    { ExtendedAttributeInner } ExtendedAttributeRest
    Other ExtendedAttributeRest

ExtendedAttributeRest ::
    ExtendedAttribute
    ε

ExtendedAttributeInner ::
    ( ExtendedAttributeInner ) ExtendedAttributeInner
    [ ExtendedAttributeInner ] ExtendedAttributeInner
    { ExtendedAttributeInner } ExtendedAttributeInner
    OtherOrComma ExtendedAttributeInner
    ε

Other ::
    integer
    decimal
    identifier
    string
    other
    -
    -Infinity
    .
    ...
    :
    ;
    <
    =
    >
    ?
    *
    ByteString
    DOMString
    FrozenArray
    Infinity
    NaN
    ObservableArray
    Promise
    USVString
    any
    bigint
    boolean
    byte
    double
    false
    float
    long
    null
    object
    octet
    or
    optional
    record
    sequence
    short
    symbol
    true
    unsigned
    undefined
    ArgumentNameKeyword
    BufferRelatedType

OtherOrComma ::
    Other
    ,

IdentifierList ::
    identifier Identifiers

Identifiers ::
    , identifier Identifiers
    ε

IntegerList ::
    integer Integers

Integers ::
    , integer Integers
    ε

ExtendedAttributeNoArgs ::
    identifier

ExtendedAttributeArgList ::
    identifier ( ArgumentList )

ExtendedAttributeIdent ::
    identifier = identifier

ExtendedAttributeString ::
    identifier = string

ExtendedAttributeInteger ::
    identifier = integer

ExtendedAttributeDecimal ::
    identifier = decimal

ExtendedAttributeWildcard ::
    identifier = *

ExtendedAttributeIdentList ::
    identifier = ( IdentifierList )

ExtendedAttributeIntegerList ::
    identifier = ( IntegerList )

ExtendedAttributeNamedArgList ::
    identifier = identifier ( ArgumentList )

注: Other 非終端記号は、 (, ), [, ], {, } および , を除く任意の単一終端記号にマッチします。

一方、ExtendedAttribute 非終端記号は、括弧、角括弧、波括弧がバランスしていて、, トークンがそのバランスした括弧内にのみ現れる限り、空でない終端記号の並びにマッチしますが、 そのような可能な並びのうち、 この仕様で定義されている 拡張属性 で使用されるものは一部のみです。 拡張属性で使用される構文については § 2.14 拡張属性 を参照してください。

文書の規約

本書では、以下の書式規約が使用されています。

本書のアルゴリズムでは、以下の規約が使用されています。

適合性

図、例、注記、および参考情報として明記されたセクションを除き、本仕様書のすべてが規範的です。

本仕様書は Infra Standard(基盤標準)に依存します。[INFRA]

本仕様書では、以下の適合クラスを定義します。

IDLフラグメントの適合セット

複数の IDLフラグメント の集合は、 この仕様書でIDLフラグメントに適用されるmust、required、およびshallレベルの基準をすべて満たす場合、 IDLフラグメントの適合セットとみなされます。

適合実装

ユーザーエージェントは、 適合実装 として、 IDLフラグメントの適合セットに対して、 ユーザーエージェントがサポートするすべての言語バインディングに関して、この仕様書のmust、required、およびshallレベルの基準をすべて満たす場合に該当します。

適合JavaScript実装

ユーザーエージェントは、 適合JavaScript実装 として、 IDLフラグメントの適合セットに対して、 JavaScript言語バインディングに関して、この仕様書のmust、required、およびshallレベルの基準をすべて満たす場合に該当します。

知的財産権

この現行標準には、W3Cの WebIDL [sic] Level 1 から複製された資料が含まれており、 W3C Software and Document Licenseの下で提供されています。

Copyright © WHATWG (Apple, Google, Mozilla, Microsoft)。この文書は クリエイティブ・コモンズ表示 4.0 国際ライセンス の下でライセンスされています。一部がソースコードに組み込まれる場合、その部分は BSD 3-Clause License の下でライセンスされます。

これは現行標準です。特許審査版については 現行標準審査ドラフトを参照してください。

索引

本仕様で定義されている用語

参照により定義される用語

参考文献

規範参考文献

[DOM]
Anne van Kesteren. DOM標準。現行標準。 URL: https://dom.spec.whatwg.org/
[ECMA-262]
ECMAScript言語仕様書。URL: https://tc39.es/ecma262/multipage/
[ECMA-402]
ECMAScript国際化API仕様書。URL: https://tc39.es/ecma402/
[HTML]
Anne van Kesteren; 他。HTML標準。 現行標準。URL: https://html.spec.whatwg.org/multipage/
[IEEE-754]
IEEE浮動小数点算術標準。2019年7月22日。URL: https://ieeexplore.ieee.org/document/8766229
[Infra]
Anne van Kesteren; Domenic Denicola. Infra標準。 現行標準。URL: https://infra.spec.whatwg.org/
[PERLRE]
Perl正規表現(Perl 5.8.8)。2006年2月。URL: http://search.cpan.org/dist/perl/pod/perlre.pod
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL標準。現行標準。URL: https://webidl.spec.whatwg.org/

参考情報文献

[API-DESIGN-PRINCIPLES]
Martin Thomson; Jeffrey Yasskin. Webプラットフォーム設計原則。URL: https://w3ctag.github.io/design-principles/
[CSS3-CONDITIONAL]
Chris Lilley; David Baron; Elika Etemad. CSS条件付き規則モジュール レベル3。URL: https://drafts.csswg.org/css-conditional-3/
[CSSOM]
Daniel Glazman; Emilio Cobos Álvarez. CSSオブジェクトモデル(CSSOM)。URL: https://drafts.csswg.org/cssom/
[FETCH]
Anne van Kesteren. Fetch標準。現行標準。 URL: https://fetch.spec.whatwg.org/
[INDEXEDDB]
Nikunj Mehta; 他。Indexed Database API。URL: https://w3c.github.io/IndexedDB/
[PROPOSAL-FLOAT16ARRAY]
JavaScriptにfloat16型付き配列追加提案。URL: https://tc39.es/proposal-float16array/
[SERVICE-WORKERS]
Yoshisato Yanagisawa; Monica CHINTALA. Service Workers。URL: https://w3c.github.io/ServiceWorker/
[STREAMS]
Adam Rice; 他。Streams標準。現行標準。URL: https://streams.spec.whatwg.org/
[WASM-JS-API-1]
Daniel Ehrenberg. WebAssembly JavaScriptインターフェース。URL: https://webassembly.github.io/spec/js-api/
[WASM-JS-API-2]
. Ms2ger. WebAssembly JavaScriptインターフェース。URL: https://webassembly.github.io/spec/js-api/
[XML-NAMES]
Tim Bray; 他。Namespaces in XML 1.0(第3版)。2009年12月8日。REC。URL: https://www.w3.org/TR/xml-names/

IDL索引

[Exposed=*, Serializable]
interface QuotaExceededError : DOMException {
  constructor(optional DOMString message = "", optional QuotaExceededErrorOptions options = {});

  readonly attribute double? quota;
  readonly attribute double? requested;
};

dictionary QuotaExceededErrorOptions {
  double quota;
  double requested;
};

typedef (Int8Array or Int16Array or Int32Array or
         Uint8Array or Uint16Array or Uint32Array or Uint8ClampedArray or
         BigInt64Array or BigUint64Array or
         Float16Array or Float32Array or Float64Array or DataView) ArrayBufferView;

typedef (ArrayBufferView or ArrayBuffer) BufferSource;
typedef (ArrayBuffer or SharedArrayBuffer or [AllowShared] ArrayBufferView) AllowSharedBufferSource;
[Exposed=*,
 Serializable]
interface DOMException { // but see below note about JavaScript binding
  constructor(optional DOMString message = "", optional DOMString name = "Error");
  readonly attribute DOMString name;
  readonly attribute DOMString message;
  readonly attribute unsigned short code;

  const unsigned short INDEX_SIZE_ERR = 1;
  const unsigned short DOMSTRING_SIZE_ERR = 2;
  const unsigned short HIERARCHY_REQUEST_ERR = 3;
  const unsigned short WRONG_DOCUMENT_ERR = 4;
  const unsigned short INVALID_CHARACTER_ERR = 5;
  const unsigned short NO_DATA_ALLOWED_ERR = 6;
  const unsigned short NO_MODIFICATION_ALLOWED_ERR = 7;
  const unsigned short NOT_FOUND_ERR = 8;
  const unsigned short NOT_SUPPORTED_ERR = 9;
  const unsigned short INUSE_ATTRIBUTE_ERR = 10;
  const unsigned short INVALID_STATE_ERR = 11;
  const unsigned short SYNTAX_ERR = 12;
  const unsigned short INVALID_MODIFICATION_ERR = 13;
  const unsigned short NAMESPACE_ERR = 14;
  const unsigned short INVALID_ACCESS_ERR = 15;
  const unsigned short VALIDATION_ERR = 16;
  const unsigned short TYPE_MISMATCH_ERR = 17;
  const unsigned short SECURITY_ERR = 18;
  const unsigned short NETWORK_ERR = 19;
  const unsigned short ABORT_ERR = 20;
  const unsigned short URL_MISMATCH_ERR = 21;
  const unsigned short QUOTA_EXCEEDED_ERR = 22;
  const unsigned short TIMEOUT_ERR = 23;
  const unsigned short INVALID_NODE_TYPE_ERR = 24;
  const unsigned short DATA_CLONE_ERR = 25;
};

callback Function = any (any... arguments);
callback VoidFunction = undefined ();
MDN

DOMException/DOMException

In all current engines.

Firefox37+Safari10.1+Chrome46+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DOMException/message

In all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

DOMException/name

In all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

DOMException

In all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
Node.js17.0.0+