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フラグメントは、
IDLフラグメントに現れることができる 定義の種類は以下の通りです: インターフェース、 パーシャルインターフェース定義、 インターフェースミックスイン、 パーシャルミックスイン定義、 コールバック関数、 コールバックインターフェース、 名前空間、 パーシャル名前空間定義、 辞書、 パーシャル辞書定義、 型定義、 includes文です。 これらはすべて以下の節で定義されています。
定義(
[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 トークンはinterface 、namespace 、dictionary 、enum 、 またはcallback キーワードの直後に現れ、 その定義の識別子を決定する。interface interface_identifier { /* interface_members... */ };partial interface interface_identifier { /* interface_members... */ };namespace namespace_identifier { /* namespace_members... */ };partial namespace namespace_identifier { /* namespace_members... */ };dictionary dictionary_identifier { /* dictionary_members... */ };partial dictionary dictionary_identifier { /* dictionary_members... */ };enum enumeration_identifier {"enum" ,"values" /* , ... */ };callback callback_identifier =return_type (/* arguments... */);callback interface callback_interface_identifier { /* interface_members... */ }; -
属性、 型定義、 辞書メンバーの場合、 宣言末尾のセミコロン直前に現れる最後の
identifier トークンが識別子となる。[
extended_attributes ]interface identifier {attribute type attribute_identifier ; };typedef type typedef_identifier ;dictionary identifier {type dictionary_member_identifier ; }; -
定数の場合、 等号の直前の
identifier トークンが識別子となる。const type constant_identifier = 42; -
操作の場合、 戻り値型の後、かつ括弧開きの前に現れる
identifier トークン(すなわちOptionalOperationName 文法記号で一致するもの)が操作の識別子となる。もし そのようなidentifier トークンがなければ、操作には識別子はない。interface interface_identifier {return_type operation_identifier (/* arguments... */); };
注: 操作は、getterやsetterなど特殊な操作を宣言する際には識別子を持たない場合がある。
これらすべての構造において、識別子は
注: 先頭のU+005F(_)は、識別子が予約語のように見えるのを回避するために使用される。たとえば「interface」という名前のインターフェースを定義できるようにするためである。識別子を元に戻すために先頭のU+005F(_)は削除される。
操作の引数は識別子としてやや広い範囲を取ることができる。操作宣言において、引数の識別子は型の直後に指定され、
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
もし
上記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フラグメントはオブジェクト指向システムの記述に用いられます。このようなシステムでは、オブジェクトは同一性を持ち、状態と振る舞いのカプセル化である実体です。
インターフェースは
(
[extended_attributes ]interface identifier { /* interface_members... */ };
インターフェースは
インターフェースメンバー
(
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を継承することもできません(そしてその先も同様)。
一般的なインターフェースの多重継承はサポートされません。また、オブジェクトが任意のインターフェース集合を実装することもできません。オブジェクトは単一のインターフェースAを実装すると定義でき、その場合Aの継承インターフェースすべても実装します。 さらに、includes文を用いることで、 インターフェースAを実装するオブジェクトが、 Aがincludeする インターフェースミックスインのメンバーも常に含むものとできます。
各インターフェースメンバーには、拡張属性(
[extended_attributes ]interface identifier { [extended_attributes ]const type constant_identifier = 42; [extended_attributes ]attribute type identifier ; [extended_attributes ]return_type identifier (/* arguments... */); };
インターフェースのIDLは、
パーシャルインターフェース
定義(
interface SomeInterface { /* interface_members... */ };partial interface SomeInterface { /* interface_members... */ };
注: パーシャルインターフェース定義は、仕様の編集上の補助として意図されており、インターフェース定義を文書の複数箇所や複数文書に分割するために利用されます。
インターフェース定義とそのパーシャルインターフェース定義の出現順は問いません。
注: パーシャルインターフェース定義では他のインターフェースの継承を指定できません。継承は元のインターフェース定義で指定します。
インターフェースが言語の構造にどう対応するかは、該当言語バインディングで定まります。
インターフェースに適用可能な拡張属性は以下の通りです:
[CrossOriginIsolated
]、
[Exposed
]、
[Global
]、
[LegacyFactoryFunction
]、
[LegacyNoInterfaceObject
]、
[LegacyOverrideBuiltIns
]、
[LegacyWindowAlias
]、
[SecureContext
]。
パーシャルインターフェースに適用可能な拡張属性は以下の通りです:
[CrossOriginIsolated
]、
[Exposed
]、
[LegacyOverrideBuiltIns
]、
[SecureContext
]。
インターフェースは必ず[Exposed
]
拡張属性で注釈されていなければなりません。
インターフェース interfaceの修飾名は以下のように定義されます:
-
identifierをinterfaceの識別子とする。
-
interfaceが[
LegacyNamespace
] 拡張属性を持つ場合:-
namespaceを[
LegacyNamespace
] 拡張属性の識別子引数とする。 -
« namespace, identifier »をU+002E(.)区切りで連結したものを返す。
-
-
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つのインターフェースの定義例です。
Human
とDog
はどちらも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 mixin identifier { /* mixin_members... */ };
注: インターフェースミックスインはパーシャルインターフェース同様、 仕様の編集補助として意図されており、機能のまとまりをグループ化し、複数のインターフェース(場合によっては複数文書)にincludeできるようにします。 これらは言語バインディングを介して公開されることを目的としたものではありません。 § 2.3.1 ミックスインとパーシャルの利用で、 パーシャルインターフェース、 インターフェースミックスイン、 パーシャルインターフェースミックスイン の使い分けについて案内しています。
インターフェースミックスインは、
インターフェースミックスインメンバー
(
これらの定数、 通常の操作、 通常の属性、 ストリギファイアは、 それらをincludeした インターフェース上に定義された場合と同様に、 オブジェクトが持つ振る舞いを記述します。
静的属性、 静的操作、 特殊操作、 イテラブル宣言、 非同期イテラブル宣言、 Maplike宣言、 Setlike宣言 は、インターフェースミックスイン宣言には現れません。
インターフェース同様、インターフェースミックスインのIDLは、
パーシャルインターフェースミックスイン
定義(
interface mixin SomeMixin { /* mixin_members... */ };partial interface mixin SomeMixin { /* mixin_members... */ };
メンバーの出現順はJavaScriptバインディングのプロパティ列挙に影響します。
なお、インターフェースや辞書とは異なり、 インターフェースミックスインは型を生成しません。
この仕様で定義されている拡張属性のうち、
インターフェースミックスインに適用できるのは
[CrossOriginIsolated
]、
[Exposed
]、
[SecureContext
]
のみです。
includes文は
(
interface_identifier includes mixin_identifier ;
最初の識別子はインターフェースIを参照しなければなりません。 2番目の識別子はインターフェースミックスインMを参照しなければなりません。
Mの各メンバーは、 Mをincludeするすべての インターフェースI、J、K…の メンバーとみなされ、 まるで各メンバーのコピーが作られたかのように扱われます。 つまり、Mのメンバーmについて、インターフェースIはmIという メンバーを持ち、 インターフェースJはmJを、 インターフェースKはmKを持つことになります。 ホストインターフェースは、 mI、mJ、mKに対して、それぞれI、J、Kです。
注: JavaScriptでは、メンバーとして宣言された通常の操作は、 それぞれのインターフェースプロトタイプオブジェクトごとに インターフェースがMをincludeしている場合、 異なる組み込み関数オブジェクトとして データプロパティで公開されます。 属性についても、各アクセサプロパティの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
Partial ::partial PartialDefinition
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 { /* 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. メンバー
インターフェース、インターフェースミックスイン、名前空間は、それぞれ
メンバー
(それぞれ
あるインターフェースがインターフェースミックスインをincludeすると、 ミックスインの各メンバーはそのインターフェースのメンバーとみなされます。 対照的に、継承されたインターフェースメンバーは そのインターフェースのメンバーとはみなされません。
各種インターフェースやインターフェースミックスインで定義されるメンバーの コンストラクタ手順、 getter手順、 setter手順、 メソッド手順は、 this値(そのメンバーが宣言されるインターフェース型、またはそのメンバーが宣言されるミックスインをincludeするインターフェース型のIDL値)にアクセスできます。
setter手順は、 与えられた値にもアクセスでき、 これは属性が宣言された型のIDL値です。
インターフェース、 インターフェースミックスイン、 コールバックインターフェース、 名前空間は それぞれ異なるセットのメンバーをサポートします。 詳細は§ 2.2 インターフェース、 § 2.3 インターフェースミックスイン、 § 2.4 コールバックインターフェース、 § 2.6 名前空間で規定されており、次の参考表にまとめます:
インターフェース | コールバックインターフェース | インターフェースミックスイン | 名前空間 | |
---|---|---|---|---|
定数 | ● | ● | ● | |
通常の属性 | ● | ● | 読み取り専用属性のみ | |
静的属性 | ● | |||
通常の操作 | ● | ● | ● | ● |
ストリギファイア | ● | ● | ||
特殊操作 | ● | |||
静的操作 | ● | |||
イテラブル宣言 | ● | |||
非同期イテラブル宣言 | ● | |||
Maplike宣言 | ● | |||
Setlike宣言 | ● |
2.5.1. 定数
定数は、
(
定数はこれまで主に、列挙型スタイルの名前付き整数コードの定義に使われてきましたが、Webプラットフォームではこの設計パターンから文字列の利用へと移行しています。 この機能を使用したい編集者は、進める前に issueを提出 して議論することが強く推奨されます。
const type constant_identifier = 42;
定数の識別子は、
同じインターフェースメンバーやコールバックインターフェースメンバーの識別子と重複してはなりません(同じインターフェース、
またはコールバックインターフェース上)。
また、"length
"、"name
"、"prototype
"であってはなりません。
注: これら3つの名前はJavaScriptバインディングのインターフェースオブジェクト上のプロパティ名です。
定数の型(
定数宣言の
注: これらの値(文字列と空のシーケンスも含む)は、辞書メンバーのデフォルト値やオプション引数のデフォルト値にも使えます。
ただし、文字列、空のシーケンス
booleanリテラルトークンboolean
値true
とfalse
です。
-
SをJavaScriptの
NumericLiteral としてパースした結果をresultとする。 -
型が
float
またはunrestricted float
の場合、 resultに最も近いIEEE 754単精度浮動小数点数が値となる。 -
それ以外の場合(型が
double
またはunrestricted double
)、 resultに最も近いIEEE 754倍精度浮動小数点数が値となる。[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)。
float
やdouble
の値として使えません。
定数に割り当てる値の型VTと、定数・辞書メンバー・オプション引数自体の型DTについて、型が互換でなければなりません。 互換とは、DTとVTが一致するか、DTがVTを内包するヌラブル型であり、その内側の型が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
[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. 属性
属性は、
インターフェースメンバーまたは
名前空間メンバー
(
-
通常の属性:オブジェクトがそのインターフェースを実装する際、指定された識別子のデータフィールドメンバーを持つことを宣言します。
interface interface_identifier {attribute type identifier ; }; -
静的属性:インターフェースを実装する特定のオブジェクトとは関連しない属性を宣言するために使われます。
interface interface_identifier {static attribute type identifier ; };
属性に
属性attrのgetter手順は、「attr
getter手順は次の通り:」という文+リスト、または「attr
getter手順は...」という文+インライン説明で記述します。
属性attrのsetter手順は、「attr
setter手順は次の通り:」という文+リスト、または「attr
setter手順は...」という文+インライン説明で記述します。
注: getter手順を定義するときは、暗黙的にthisにアクセスできます。 setter手順の場合は、暗黙的にthisと与えられた値にアクセスできます。
属性の識別子は、
同じインターフェース上の他のインターフェースメンバーと重複してはなりません。
静的属性の識別子は"prototype
"であってはなりません。
属性の型は、
typedefを解決した後の属性の型は、以下のいずれかの型(ヌラブル/非ヌラブル)であってはなりません:
interface interface_identifier {readonly attribute type identifier ; };
型がPromise型の属性は必ず読み取り専用でなければなりません。また、[LegacyLenientSetter
]、
[PutForwards
]、
[Replaceable
]、
[SameObject
]の
いずれの拡張属性も持てません。
通常の属性で読み取り専用でないものは、
祖先インターフェースからgetterを継承するよう宣言できます。これにより、祖先インターフェースで読み取り専用の属性を派生インターフェースで書き込み可能にできます。
属性が
注: 文法により
[Exposed =Window ]interface Ancestor {readonly attribute TheType theIdentifier ; }; [Exposed =Window ]interface Derived :Ancestor {inherit attribute TheType theIdentifier ; };
通常の属性宣言に
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. 操作
操作は、
インターフェースメンバー、
コールバックインターフェースメンバー、
名前空間メンバー
(
-
通常の操作: インターフェースを実装するオブジェクトが、指定された識別子のメソッドを持つことを宣言します。
interface interface_identifier {return_type identifier (/* arguments... */); }; -
特殊操作: インターフェースを実装するオブジェクト上で、インデックス付きやストリング化などの特殊な振る舞いを宣言します。
interface interface_identifier { /* special_keyword */return_type identifier (/* arguments... */); /* special_keyword */return_type (/* arguments... */); }; -
静的操作: インターフェースを実装する特定のオブジェクトとは関連しない操作を宣言します。
interface interface_identifier {static return_type identifier (/* arguments... */); };
操作に識別子があり、
操作に識別子がない場合、特殊キーワードを用いて特殊操作として宣言しなければなりません。
通常の操作や静的操作の識別子は、
同じインターフェース、
コールバックインターフェース、
名前空間上の定数や属性と重複してはなりません。
静的操作の識別子は"prototype
"であってはなりません。
注: 識別子は同じインターフェース内の他の操作と重複しても構いません。 これが操作のオーバーロード指定方法です。
注: 静的操作の識別子は、 同じインターフェース上の通常の操作と重複しても構いません。
操作の戻り値型は、
宣言で識別子の前に現れる型(
操作の引数(
注: 表現力のため、操作引数の識別子は
操作引数の型が識別子+
typedef解決後、引数型がヌラブル型なら、 内側の型は辞書型であってはなりません。
interface interface_identifier {return_type identifier (type identifier ,type identifier /* , ... */); };
各引数の識別子は、同じ操作宣言内の他の引数の識別子と重複してはなりません。
各引数には、拡張属性(
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引数
可変長関数非対応の言語バインディングでは、明示的な配列やリストを渡す仕様となる場合もあります。
引数が
interface interface_identifier {return_type identifier (type identifier ,optional type identifier ); };
オプション引数にはデフォルト値も指定できます。引数識別子の後にU+003D(=)と値(
interface interface_identifier {return_type identifier (type identifier ,optional type identifier = "value"); };
デフォルト値として
引数型が辞書型または辞書型メンバーを持つユニオン型で、辞書型や祖先に required メンバーがなく、 引数が最後または以降がオプション引数のみの場合は、その引数をオプション・デフォルト値付きで宣言しなければなりません。
これはAPI設計上、空の辞書値を渡さずデフォルト値だけ使いたい場合に著者が明示的に空辞書を渡す必要がないようにするためです。
多くの場合デフォルト値は
booleanリテラル(
undefined
値となります。
オプション引数の型が列挙型の場合、 デフォルト値はその列挙型値のいずれかでなければなりません。
オプション引数のデフォルト値として、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
辞書が渡され、caseSensitive
は
操作に適用可能な拡張属性は以下の通りです:
[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型は次の通りです:
-
型定義(新しい名前が与えられている型がJSON型)
-
シーケンス型(パラメータ化型がJSON型)
-
フローズン配列型(パラメータ化型がJSON型)
-
レコード(すべての値がJSON型)
-
インターフェース型(自身または継承インターフェースに
toJSON
操作を持つもの)
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()
メソッド手順:
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. コンストラクター操作
あるインターフェースに
コンストラクター操作メンバー(
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 ) ;
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. ストリギファイア
あるインターフェースにストリギファイアがある場合、
そのインターフェースを実装するオブジェクトはデフォルト以外の文字列変換を持つことを意味します。ストリギファイアは
interface interface_identifier {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 ; };
したがって、本文でストリギファイ挙動を説明する必要があります。
familyName
・givenName
属性がそれぞれ家族名・名前概念に裏付けられていると仮定します。
ストリギファイ挙動手順:
この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種類あります。以下の表は、各特殊操作の種類ごとに宣言に使う特殊キーワードとその目的を示します:
特殊操作 | キーワード | 目的 |
---|---|---|
ゲッター | オブジェクトがプロパティ取得でインデックスされた時の挙動を定義 | |
セッター | オブジェクトがプロパティ代入や作成でインデックスされた時の挙動を定義 | |
デリーター | オブジェクトがプロパティ削除でインデックスされた時の挙動を定義 |
すべての言語バインディングが全ての特殊オブジェクト挙動をサポートするわけではありません。識別子なしで宣言された特殊操作は、その挙動をサポートしない言語バインディングでは単に機能しません。
次の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
で存在しないエントリを検索した場合は
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. 静的属性および操作
静的属性
および
静的操作
とは、
宣言された
インターフェイス
の特定のインスタンスには関連付けられず、インターフェイス自体に関連付けられるものです。
静的属性および操作は宣言に
静的操作や静的属性をインターフェイスのインスタンス参照を通じて呼び出すことができるかどうかは、言語バインディングごとに異なります。
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. オーバーロード
インターフェイス上に定義された 通常の操作 または 静的操作 が、同じ種類(通常または静的)の操作として同じ 識別子を持つ別の操作と重複している場合、 その操作は オーバーロードされていると言います。 オーバーロードされた操作の識別子を使って、 インターフェイスを実装するオブジェクト上で操作を呼び出した場合、 渡された引数の数や型によって、どのオーバーロードされた操作が実際に呼び出されるかが決定されます。 コンストラクタ操作も オーバーロード可能です。 オーバーロードされた操作やコンストラクタが取ることができる引数にはいくつか制約があり、 これらの制約を説明するために 有効なオーバーロード集合 という概念が使われます。
オーバーロードされた 操作の集合は、次のいずれかでなければなりません:
操作は インターフェイス、 部分インターフェイス、 インターフェイスミックスイン、 部分インターフェイスミックスイン の定義をまたいでオーバーロードしてはなりません。
例えば、f と g の両方のオーバーロードは許可されません:
[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構成要素のいずれかに対して動作し、必要な入力は以下の通りです。
- 通常の操作の場合
- 静的操作の場合
- コンストラクタの場合
-
-
コンストラクタ操作が見つかる インターフェイス
-
渡される引数の数
-
- レガシーファクトリ関数の場合
-
-
[
LegacyFactoryFunction
] 拡張属性 が見つかるインターフェイス -
レガシーファクトリ関数の 識別子
-
渡される引数の数
-
有効なオーバーロード集合は、インターフェイス上で指定されたオーバーロード操作やコンストラクタに 曖昧さがないかどうかなどを判断するために使われます。
項目は 有効なオーバーロード集合の タプルであり、 (呼び出し可能, 型リスト, オプショナリティリスト) という形式です。それぞれの 項目は以下の通りです:
-
呼び出し可能は、 有効なオーバーロード集合が 通常の操作、 静的操作、 コンストラクタ操作の場合は 操作です。 有効なオーバーロード集合が レガシーファクトリ関数の場合は 拡張属性 です。
-
型リストは IDL型の リスト です。
-
オプショナリティリストは 3つの オプショナリティ値 ("required"、"optional"、"variadic")の リストです。 これは、引数が オプションか、 可変長か、 インデックスごとに示します。
各タプルは、 その操作・コンストラクタ・コールバック関数を、指定された型の引数値リストで呼び出せることを表します。 オプション引数 や 可変長操作・コンストラクタにより、 同じ操作やコンストラクタを識別する 有効なオーバーロード集合に 複数の項目が含まれる場合があります。
-
操作またはレガシーファクトリ関数の識別子は A
-
引数の数は N
-
インターフェイスは I
拡張属性の引数について言及される場合、それは拡張属性の 名前付き引数リストの引数を指します。
-
S を 順序付き集合とする。
-
F を 順序付き集合とし、 項目は 有効なオーバーロード集合の種類ごとに以下とする:
-
maxargを、F内の操作・レガシーファクトリ関数・コールバック関数が宣言で取る最大の引数数とする。 可変長操作やレガシーファクトリ関数では、 エリプシスが付く引数も1つとして数える。
注:
undefined f(long x, long... y);
は2引数とみなされる。 -
max = max(maxarg, N) とする。
-
各操作または拡張属性Xについて、F内で:
-
argumentsを、Xが宣言で取る引数の リストとする。
-
nを、argumentsの サイズ とする。
-
typesを 型リストとする。
-
optionalityValuesを オプショナリティリストとする。
-
各 argument について、arguments内で:
-
types に argument の型を追加。
-
optionalityValues に argument が最後の可変長引数なら "variadic"、 optional なら "optional"、 それ以外は "required" を追加。
-
-
もしXが 可変長として宣言されていれば:
-
i = n − 1 とする。
-
i ≥ 0 の間:
-
-
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 ); };
Node
とEvent
がどちらも実装できるオブジェクトが存在しない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を返す場合、 識別可能と言います。
-
一方の型がnullable型を含み、 もう一方もnullable型を含むか、 ユニオン型であり フラット化されたメンバー型が 辞書型を含むか、 辞書型なら、 falseを返す。
-
両方の型がユニオン型またはnullableなユニオン型なら、 一方の各メンバー型が他方の各メンバー型と識別可能であればtrue、そうでなければfalseを返す。
-
一方の型がユニオン型またはnullableなユニオン型なら、 そのユニオン型の各 メンバー型 が非ユニオン型と識別可能であればtrue、そうでなければfalseを返す。
-
各型のinner type が注釈付き型ならそれを取り、 さらにinner typeがnullable型ならそれを取った2つの「最も内側の型」を考える。 これら2つの型が次の表に現れるかカテゴリに属し、対応する欄に「●」があるか、文字があり追加要件を満たすならtrueを返す。 そうでなければfalseを返す。
カテゴリ:
- interface-like
- dictionary-like
- sequence-like
undefinedbooleannumeric typesbigintstring typesobjectsymbolinterface-likecallback functiondictionary-likeasync sequencesequence-likeundefined ● ● ● ● ● ● ● ● ● ● boolean ● ● ● ● ● ● ● ● ● ● numeric types (b) ● ● ● ● ● ● ● ● bigint ● ● ● ● ● ● ● ● string types ● ● ● ● ● (d) ● object ● symbol ● ● ● ● ● interface-like (a) ● ● ● ● callback function (c) ● ● dictionary-like ● ● ● async sequence sequence-like -
識別された2つのinterface-like型が同じでなく、どのプラットフォームオブジェクトも両方の型を実装しない場合。
-
型は識別可能だが、オーバーロードでの利用には別の制約があり、 これら型のユニオン利用についての助言も参照。
-
コールバック関数が [
LegacyTreatNonObjectAsNull
] 拡張属性を持たない場合、辞書型カテゴリの型と識別可能。 -
型は識別可能だが、ECMAScript値から変換する際、 文字列オブジェクトは 非同期シーケンスタイプ には変換されない(%Symbol.iterator%メソッドがあっても)。 文字列型が集合やユニオンに含まれる場合も同様。
例:callback interface CBIface {undefined handle (); }; [Exposed =Window ]interface Iface {attribute DOMString attr2 ; };dictionary Dict {DOMString field1 ; };CBIface
はIface
とは識別可能ですが(dictionary-likeとinterface-likeの交差点に●があるため)、Dict
とは識別できません(dictionary-like同士の交差点に●がないため)。Promise型は上記の表に現れず、 他の型とは識別できません。
有効なオーバーロード集合に 型リストサイズが同じ 項目が複数ある場合、 それらの項目について、各ペアの型リストのインデックスiの型が 識別可能である 必要がある。 この最も小さいインデックスを、 識別引数インデックス と呼ぶ。
有効なオーバーロード集合には、
型リストサイズが同じ
項目が
2つ以上含まれてはならず、
そのうち一方の
識別引数インデックス位置に
bigint
型の引数があり、
他方にはnumeric型の引数がある場合は不可。
前述の有効なオーバーロード集合では、
型リストサイズ2, 3, 4に複数の項目があります。
これらの型リストサイズに対し、
識別引数インデックスは0です。
Node
とEvent
は
識別可能だからです。
次のようなオーバーロードの利用は無効です:
[Exposed =Window ]interface B {undefined f (DOMString x );undefined f (USVString x ); };
さらに、型リストサイズが同じアイテム群について、 識別引数インデックスより小さい各インデックス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です。
Node
と
DOMString
が識別可能だからです。
しかし、これら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番目のオーバーロードが呼ばれ、
Path2D
に変換できないため
TypeError
となります。
しかし、操作がオプション引数で統合されていた場合、
interface CanvasDrawPathExcerptOptional {undefined stroke (optional Path2D path ); };
オーバーロード解決アルゴリズムは path引数が未指定とみなし、例外を投げません。
注: この例では、後者の挙動がWeb開発者の期待に沿っています。
CanvasDrawPath
が現在設計されるなら、オプション引数でstroke()
が定義されるでしょう。
さらに、意味論的な違いもあります。ユニオン型は通常「どの型でもほぼ同じように動作する」場合に使われますが、 オーバーロード操作はC++のオーバーロードのような言語機能に適合しやすく、 異なる型の引数で本質的に異なる挙動を持つ操作に向いています。 とはいえ、そうした操作はJavaScript言語では明示的なオーバーロードがないため、混乱を避けるためにも別名の操作にしたほうが良い場合が多いです。 そのため、オーバーロードは新しいAPIにはほとんど適さず、レガシーAPIや特殊な事情で現れることが多いです。
以下に、どのWeb IDL言語機能を使うべきか迷った場合の推奨例を挙げます:
-
引数型ごとに返す値の型も異なる場合は、オーバーロードの方が表現力豊かなIDL断片になります。 こうしたAPI設計はほぼ推奨されず、通常は名前を分けたほうが良いです。
例えば、
calculate()
操作がlong
,DOMString
,CalculatableInterface
(インターフェイスタイプ)のいずれかを引数に取り、 戻り値も引数と同じ型になる場合、IDL断片はオーバーロードで書く方が明快です:interface A {long calculate (long input );DOMString calculate (DOMString input );CalculatableInterface calculate (CalculatableInterface input ); };ユニオン型とtypedefを使うとこうなります:
typedef (long or DOMString or CalculatableInterface )Calculatable ;interface A {Calculatable calculate (Calculatable input ); };これでは戻り値がinputと同じ型であることが伝わりません。
互換性を気にしない新APIなら、操作名を分けるのが推奨されます:
interface A {long calculateNumber (long input );DOMString calculateString (DOMString input );CalculatableInterface calculateCalculatableInterface (CalculatableInterface input ); };こうすればWeb開発者は明確なコードを書けます。
-
引数型や長さごとに意味が大きく異なる場合は、オーバーロードが推奨されます。 とはいえ、こうした場合も名前を分ける方がよく、レガシーAPIで多いパターンです。
例として、
supports(property, value)
とsupports(conditionText)
操作は、CSS
インターフェイスで次のIDL断片として定義されています [CSS3-CONDITIONAL] [CSSOM]。partial interface CSS {static boolean supports (CSSOMString property ,CSSOMString value );static boolean supports (CSSOMString conditionText ); };オプション引数で書き換えると:
partial interface CSSExcerptOptional {static boolean supports (CSSOMString propertyOrConditionText ,optional CSSOMString value ); };2つ目のIDLの方が短いですが、1つ目の引数に2つの異なる概念が混在してしまいます。 オーバーロード無しでは 「propertyやconditionTextがvalueとペアになるか?」は操作の手順を読まないと分かりません。 2つ目のバージョンは可読性が著しく落ちます。
さらに、手順が オーバーロード操作ごとに分けて書ける利点もあります。 オプション引数ではそうはできません。 1つ目の場合、仕様者は操作ごとに手順を分けて書けます:
supports(property, value)
の手順:-
…
supports(conditionText)
の手順:-
…
一方valueをオプション引数にすると、仕様者はより冗長な記述で オーバーロード解決アルゴリズムを再現する必要があります。
supports(propertyOrConditionText, value)
の手順:-
valueが与えられていれば:
-
property = propertyOrConditionTextとする。
-
…
-
-
それ以外:
-
conditionText = propertyOrConditionTextとする。
-
…
-
2つのオーバーロードに共通部分が少なければ、IDLのオーバーロード機構に任せる方がよいです。
-
-
引数ごとに複数型を受け付け、異なる引数で型の連携がない場合は、ユニオン型が唯一の解決策になることもあります。
typedef (long long or DOMString or CalculatableInterface )SupportedArgument ;interface A {undefined add (SupportedArgument operand1 ,SupportedArgument operand2 ); };上記の
add()
操作をオーバーロードで表現しようとすると、interface A {undefined add (long long operand1 ,long long operand2 );undefined add (long long operand1 ,DOMString operand2 );undefined add (long long operand1 ,CalculatableInterface operand2 );undefined add (DOMString operand1 ,long long operand2 );undefined add (DOMString operand1 ,DOMString operand2 );undefined add (DOMString operand1 ,CalculatableInterface operand2 );undefined add (CalculatableInterface operand1 ,long long operand2 );undefined add (CalculatableInterface operand1 ,DOMString operand2 );undefined add (CalculatableInterface operand1 ,CalculatableInterface operand2 ); };記述も9倍になります!
-
仕様作成者は、JavaScript言語バインディングでは引数が省略された場合と
undefined の場合を同じように扱うことを推奨します。次のIDL断片:
interface A {undefined foo ();undefined foo (Node ?arg ); };JavaScript言語バインディングでは、
foo(undefined)
やfoo(null)
はfoo(arg)
の手順が実行されargはnullになりますが、foo()
だけの場合は最初のオーバーロードになります。これはAPI利用者にとって驚きやすい挙動です。 代わりに、オプション引数を使うことで、foo()
とfoo(undefined)
の両方を「argが未指定」とみなせます。interface A {undefined foo (optional Node ?arg ); };一般的には、オプション性は
optional キーワードで表すのがベストで、オーバーロードを使うべきではありません。
上記のいずれにも当てはまらない場合は、仕様作成者がスタイルを選択できますが、たいていどちらでも十分に意図した挙動を記述できます。 ただし、変換アルゴリズムを含め、ユニオン型やオプション引数の方が オーバーロードより 実装・理解が容易であり、JavaScriptのAPIにもより適しています。 したがって特別な事情がなければ、ユニオン型やオプション引数、またはその両方がデフォルトの選択肢です。
仕様では、ユニオン型とオーバーロードを混ぜて使うことも自由です。適切かつ便利と思えばそのようにしてください。
2.5.9. イテラブル宣言
インターフェイスは、インターフェイス本体内で
イテラブル
をイテラブル宣言
(
interface interface_identifier {iterable <value_type >;iterable <key_type ,value_type >; };
イテラブルとして宣言されたインターフェイスを実装するオブジェクトは、値の列として反復処理(イテレーション)できます。
注: JavaScript言語バインディングでは、イテラブルなインターフェイスは
entries
, forEach
,
keys
, values
, %Symbol.iterator%
プロパティをインターフェイスプロトタイプオブジェクト上に持ちます。
型パラメータが1つだけ指定されている場合、そのインターフェイスは 値イテレータとなり、指定された型の値を提供します。 型パラメータが2つ指定されている場合、そのインターフェイスは ペアイテレータとなり、 指定された型の値ペアを提供します。
値ペアとは、キー型と値型が与えられた場合、 2つの構造体アイテムを持つ アイテムのことです:
値イテレータは、必ず インデックス付きプロパティをサポートする インターフェイスにのみ宣言できます。 この値イテレータの値型は、 インデックス付きプロパティゲッターが返す型と同じでなければなりません。 値イテレータは、 オブジェクトのインデックス付きプロパティをイテレートするものとして暗黙的に定義されます。
ペアイテレータは、 インデックス付きプロパティをサポートする インターフェイスには宣言できません。
ペアイテレータを持つインターフェースに付随する説明文では、 インターフェースの各インスタンスごとに リストとして 値ペアを定義する必要があります。 このリストがイテレートする値ペアです。
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
メソッドがあり、次の値を返します。
keys
やentries
メソッドはセッションオブジェクトのユーザー名やユーザー名/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 usernameof 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. 非同期イテラブル宣言
インターフェイスは、インターフェイス本体内で
非同期イテラブル宣言
(
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つの場合、そのインターフェイスは ペア非同期イテラブル宣言となり、指定した型の 値ペアを非同期で提供します。
引数が指定されている場合、非同期イテラブル宣言の引数(
%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()
メソッド呼び出し時の挙動をカスタマイズできます。
break
やreturn
でfor
-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の 非同期イテレータ初期化手順:
iteratorの現在状態を「まだ開始されていない」に設定。
SessionManager
のmanagerとその非同期イテレータiteratorの 次のイテレーション結果を取得する:
promise を新しい promise とする。
key を次の値(該当すれば)、そうでなければ null とする:
- もし iterator の current state が "not yet started" である場合
manager の open sessions における、辞書順で最も小さい username
- それ以外の場合
manager の open sessions における、iterator の current state より大きい username のうち、辞書順で最も小さいもの
注: iterator の current state は、open sessions に存在しなくなっている場合があります。
key が null なら:
promise を end of iteration で解決する。
それ以外の場合:
session を key に対応する
Session
オブジェクトとする。promise を (username, session) で解決する。
iterator の current state を username に設定する。
promise を返す。
JavaScript言語バインディングでは、SessionManager
の
インターフェイスプロトタイプオブジェクトには
values
メソッド(関数)があり、呼び出すと非同期イテレータオブジェクトを返し、
そのイテレータオブジェクトにはnext
メソッドがある。
keys
・entries
はセッションオブジェクトのユーザー名や(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 usernameof 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宣言
インターフェイスは、
インターフェイス本体内で
maplike
をmaplike宣言
(
interface interface_identifier {readonly maplike <key_type ,value_type >;maplike <key_type ,value_type >; };
maplikeとして宣言されたインターフェイスを実装するオブジェクトは、 最初は空の順序付きマップ(key–valueペア)を表します。 これはそのオブジェクトのマップエントリです。 キーと値の型はmaplike宣言の山括弧内で指定されます。キーは一意でなければなりません。
仕様策定者はマップエントリの内容を変更できます。 この変更はJavaScriptコードからオブジェクトの内容を観測した時にも自動的に反映されます。
maplikeインターフェイスは、言語バインディングに応じてマップエントリの問い合わせAPIをサポートします。
注: JavaScript言語バインディングでは、
マップエントリ操作APIはJavaScriptの
Map
オブジェクトに似ています。
entries
、
forEach
、get
、
has
、keys
、
values
、
%Symbol.iterator%
メソッド、およびsize
ゲッターが含まれます。
読み書き可能なmaplikeにはさらにclear
、
delete
、set
メソッドも含まれます。
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
ReadWriteMaplike ::MaplikeRest
MaplikeRest ::maplike < TypeWithExtendedAttributes , TypeWithExtendedAttributes > ;
この仕様で定義された拡張属性は、 maplike宣言 には適用できません。
例を追加。
2.5.12. setlike宣言
インターフェイスは、
インターフェイス本体内で
setlike
をsetlike宣言
(
interface interface_identifier {readonly setlike <type >;setlike <type >; };
setlikeとして宣言されたインターフェイスを実装するオブジェクトは、 最初は空の順序付き集合(値のセット)を表します。 これはそのオブジェクトのセットエントリです。 値の型はsetlike宣言の山括弧内で指定されます。値は一意でなければなりません。
仕様策定者はセットエントリの内容を変更できます。 この変更はJavaScriptコードからオブジェクトの内容を観測した時にも自動的に反映されます。
setlikeインターフェイスは、言語バインディングに応じてセットエントリの問い合わせAPIをサポートします。
注: JavaScript言語バインディングでは、
セットエントリ操作APIはJavaScriptの
Set
オブジェクトに似ています。
entries
、
forEach
、has
、
keys
、values
、
%Symbol.iterator%
メソッド、およびsize
ゲッターが含まれます。
読み書き可能なsetlikeにはさらにadd
、
clear
、delete
メソッドも含まれます。
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
ReadWriteSetlike ::SetlikeRest
SetlikeRest ::setlike < TypeWithExtendedAttributes > ;
この仕様で定義された拡張属性は、 setlike宣言 には適用できません。
例を追加。
2.6. 名前空間
名前空間は、グローバルなシングルトンと関連する振る舞いを宣言する定義(
namespace identifier { /* namespace_members... */ };
名前空間は、名前空間メンバー(
インターフェイスと同様に、名前空間のIDLはpartial namespace定義(
namespace SomeNamespace { /* namespace_members... */ };partial namespace SomeNamespace { /* namespace_members... */ };
注: partial interface定義と同様、partial namespace定義は仕様編集上の補助を目的としており、 名前空間の定義を文書の複数のセクションや複数文書に分散できます。
メンバーの出現順は、JavaScriptバインディングにおけるプロパティの列挙で意味を持ちます。
インターフェイスや辞書型とは異なり、名前空間は型を生成しません。
この仕様で定義された拡張属性のうち、
[CrossOriginIsolated
]、
[Exposed
]、
[SecureContext
]
拡張属性のみが名前空間に適用可能です。
名前空間は必ず
[Exposed
] 拡張属性を注釈しなければなりません。
Partial ::partial PartialDefinition
Namespace ::namespace identifier { NamespaceMembers } ;
NamespaceMembers ::ExtendedAttributeList NamespaceMember NamespaceMembers ε
NamespaceMember ::RegularOperation readonly AttributeRest Const
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 identifier { /* dictionary_members... */ };
辞書インスタンスは、その言語固有の表現(例:対応するJavaScriptオブジェクト)への参照を保持しません。 たとえば、操作から辞書を返す場合は、 辞書の現在の値から新しいJavaScriptオブジェクトが作成されます。 また、操作が引数として辞書を受け取る場合は、 渡されたJavaScript値から一度だけ変換が行われ、辞書が作成されます。 辞書の変更は対応するJavaScriptオブジェクトには反映されず、逆も同様です。
辞書型は、他の辞書型から継承するように定義できます。 辞書型の識別子の後にコロンと識別子が続く場合、 その識別子が継承元の辞書型を表します。識別子は必ず辞書型を指す必要があります。
辞書型は、その継承階層に循環があってはなりません。 つまり、辞書型Aが自分自身を継承してはならず、 また他の辞書型BがAを継承し、AがBを継承するような循環も不可です。
dictionary Base { /* dictionary_members... */ };dictionary Derived :Base { /* dictionary_members... */ };
継承辞書型とは、 辞書型Dが直接または間接的に継承する全ての辞書型の集合です。 Dが他の辞書型を継承しなければ空集合です。 そうでなければ、Dが継承するEと、そのEの 継承辞書型も含みます。
辞書メンバーは 必須 として指定できます。言語固有値を辞書型に変換する際、そのメンバーの値を必ず指定する必要があります。 必須でない辞書メンバーは オプション です。
辞書メンバーを必須と指定しても、 それが観測可能になるのは他の表現(例えば操作の引数としてJavaScript値を渡す場合)をIDL辞書型に変換するときのみです。 仕様策定者は、辞書型が操作の戻り値としてのみ使われる場合などは、メンバーはすべて オプションにするべきです。
辞書型Dの値は、Dおよびその 継承辞書型 に定義された各辞書メンバーに対するエントリを持ちます。 必須メンバーや デフォルト値を持つメンバーには必ず対応する エントリが存在します。 それ以外のメンバーのエントリは辞書値に存在する場合としない場合があります。
JavaScriptバインディングでは、辞書メンバーに対応するプロパティの値が
操作引数のデフォルト値と同様に、
boolean
型
辞書メンバーのデフォルト値に
文字列キーの順序付きマップは、 すべてのエントリが 辞書型Dの辞書メンバーに対応し、 それらの型が正しく、かつ必須またはデフォルト値付きメンバーに対応する エントリが存在すれば、暗黙的にその辞書型の値とみなされます。
dictionary Descriptor {DOMString name ;sequence <unsigned long >serviceIdentifiers ; };
Descriptor
辞書型は次の手順で作成できます:
-
identifiers = « 1, 3, 7 » とする。
-
«[ "name" → "test", "serviceIdentifiers" → identifiers ]» を返す。
各辞書メンバー
(
辞書メンバーの型(typedef展開後)がnullable型の場合、 そのinner typeは 辞書型であってはなりません。
dictionary identifier {type identifier ; };
オプションの辞書メンバーの識別子の後に
U+003D(=)と値(
dictionary identifier {type identifier = "value"; };
デフォルト値としてbooleanリテラル(
辞書メンバーの型が列挙型の場合、 デフォルト値(指定されていれば)は列挙型の値のいずれかでなければなりません。
辞書メンバーの型の前に
dictionary identifier {required type identifier ; };
辞書メンバーの型は、その辞書型自身を含んではなりません。型が辞書型Dを含むとは、以下のいずれかが真である場合です:
-
型がDそのものである
-
型が辞書型で、継承先がDである
-
型がnullable型で、 inner typeがDを含む
-
型がsequence型または frozen array型で、 要素型がDを含む
-
型がユニオン型で、 メンバー型のいずれかがDを含む
-
型が辞書型で、そのメンバーや継承メンバーの型がDを含む
-
型が
record<K, V>
で、 VがDを含む
インターフェイスと同様に、辞書型のIDLは
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
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
はデフォルト値を利用でき、明示的な省略時処理を記述する必要はありません。
strokePattern
やposition
が省略された場合は
drawRectangle
側で明示的に省略時処理を行う必要があります。
2.8. 例外
例外は、
エラーを表すオブジェクトの一種であり、実装によってthrowされたり第一級値として扱われたりします。
Web IDLには仕様が参照・throwできる多くの事前定義された例外があり、
操作や属性等の定義で使用できます。カスタム例外型も、
インターフェイスとして
DOMException
を継承することで定義可能です。
単純例外は、 以下の型で識別されます:
-
EvalError
-
RangeError
-
ReferenceError
-
TypeError
-
URIError
これらはJavaScriptのエラーオブジェクト
(ただし
SyntaxError
および Error
は除く。前者はJSパーサ用、後者は著者用として予約されているため)に対応します。
各単純例外の意味は
JavaScript仕様の対応するエラーオブジェクトと一致します。
2番目の例外はDOMException
であり、
発生したエラーに関する詳細情報(name)をプログラム的に取得できます。
これらnameは
以下のDOMException
名テーブルから選ばれます。
DOMException
はインターフェイスタイプなので、
IDLで型として使えます。
例えば操作の戻り値型として
DOMException
を宣言できます。ただし例外はthrowされるべきものであり、戻り値で返すべきではないため、通常は推奨されません。
最後の例外はDOMException
の派生インターフェイスです。
これらはより複雑なため、専用の節§ 2.8.2 DOMException派生インターフェイスで説明します。
単純例外は
型名を指定することで生成できます。
DOMException
はnameと
DOMException
を指定して生成できます。
例外はまたthrowすることもでき、
生成時と同じ情報を指定します。両ケースとも、例外の意味を説明する追加情報を指定可能であり、
これは例外メッセージの構築に有用です。
例外の生成・throwの文言例:
TypeError をthrowする。
新しい DOMException
を name "NotAllowedError
"
でスローするには:
"NotAllowedError" DOMException をthrowする。
新しい DOMException
を name "SyntaxError
"
で作成するには:
object を新たに "SyntaxError" DOMException で 生成する。
新しい DOMException
を name "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
派生インターフェイス
例外がDOMException
の
name以上の情報をプログラム的に取得できる必要がある場合、仕様策定者は
インターフェイスを定義し、
DOMExceptionを継承できます。
このようなインターフェイスは、開発者に予測可能な形を提供するため、以下の規則に従う必要があります。具体的には:
-
インターフェイスの 識別子は
Error
で終わり、かつDOMException
名テーブルに載っている名前であってはなりません。 -
インターフェイスは コンストラクタ操作を持ち、 インスタンスのnameを インターフェイスの識別子に設定する必要があります。
-
そのコンストラクタ操作は 最初の引数に
DOMString
型の optionalなmessage(デフォルトは空文字列)を取り、インスタンスの messageを messageで設定する必要があります。 -
シリアライズ可能オブジェクトであり、 シリアライズ手順と デシリアライズ手順が追加情報も保持するべきです。
これらの要件により、これらインターフェイスに継承されたcode
プロパティは常に0を返します。
DOMException
派生インターフェイスを生成・
throwするには、
インターフェイスの識別子と
構築に必要な追加情報を指定します。
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
インスタンスは、requestedと
quota(いずれも数値またはnull)を持ち、初期値はnullです。
new QuotaExceededError(message, options)
のコンストラクタ手順は以下の通りです:
-
もしoptions["
quota
"] が存在する場合:-
options["
quota
"] が0未満の場合、RangeError
をスローする。
-
-
もしoptions["
requested
"] が存在する場合:-
options["
requested
"] が0未満の場合、RangeError
をスローする。
-
-
this の quota が null でなく、this の requested が null でなく、 さらに this の requested が this の quota より小さい場合、
RangeError
をスローする。
quota
のgetter手順は
thisのquotaを返す。
requested
のgetter手順は
thisのrequestedを返す。
QuotaExceededError
インターフェイスはDOMException
インターフェイスのcode
getterを継承し、常に22を返します。ただしこの値に依存するのは非推奨です(QuotaExceededError
でもDOMException
でも)。
name
getterを使う方がよいです。
QuotaExceededError
オブジェクトはシリアライズ可能オブジェクトです。
-
DOMException
のシリアライズ手順をvalue・serializedで実行。 -
serialized.[[Quota]]にvalueのquotaを設定。
-
serialized.[[Requested]]にvalueのrequestedを設定。
-
DOMException
のデシリアライズ手順をserialized・valueで実行。 -
valueのquotaにserialized.[[Quota]]を設定。
-
valueのrequestedにserialized.[[Requested]]を設定。
作成またはスローによってQuotaExceededError
を生成する仕様は、
requestedおよびquotaの両方がnullでなく、
かつrequestedがquotaより小さい場合を提供してはならない。
2.9. 列挙型
列挙型は、
DOMString
に割り当てられる値や
属性、
操作の引数として渡される値を制限できます。
enum identifier {"enum" ,"values" /* , ... */ };
列挙値は、
カンマ区切りの
列挙値はすべて小文字で、複数語はハイフン区切りまたは区切りなしとすることが強く推奨されます。 別の命名方式を使う特別な理由がなければこの推奨に従ってください。 例えば「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 gramsundefined 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 identifier =return_type (/* arguments... */);
注: 類似名のコールバックインターフェイスも参照ください。
イコール記号の左側の識別子が
コールバック関数の名前となり、
右側の戻り値型・引数リスト(
コールバック関数型に適用可能な拡張属性は以下のみです:
[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 type identifier ;
新しい名前が与えられる型は
この仕様で定義された拡張属性は 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オブジェクト(Node
やDocument
などのインターフェイスを実装)が
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
,
double
、
unrestricted double
です。
プリミティブ型は
bigint
,
boolean
と
数値型全てです。
文字列型は
DOMString
,
全ての列挙型,
ByteString
,
USVString
です。
バッファ型は
ArrayBuffer
と SharedArrayBuffer
です。
型付き配列型は
Int8Array
,
Int16Array
,
Int32Array
,
Uint8Array
,
Uint16Array
,
Uint32Array
,
Uint8ClampedArray
,
BigInt64Array
,
BigUint64Array
,
Float16Array
,
Float32Array
、
Float64Array
です。
バッファビュー型は
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
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
型の値に
unsigned long
の150や、
long
の150があり、
これは異なる値です。
any
値の型は
具体型と呼ばれます。
(ユニオン型の値も
具体型を持ちます。)
2.13.2. undefined
undefined
型は
一意な値を持ちます。
undefined
の
定数値はIDLで
undefined
は
いかなる場合も引数型(操作、
コールバック関数、
コンストラクタ操作等)や
辞書メンバー型
(直接でもユニオンでも)として使ってはなりません。
代わりにoptional引数や
非必須
辞書メンバーを使ってください。
注: この値は以前void
と綴られ、使用制限もより厳格でした。
2.13.3. boolean
boolean
の
定数値はIDLで
2.13.4. byte
byte
型は
8ビット符号付き整数に対応します。
byte
の
定数値はIDLで
2.13.5. octet
octet
型は
8ビット符号なし整数に対応します。
octet
の
定数値はIDLで
2.13.6. short
short
型は
16ビット符号付き整数に対応します。
short
の
定数値はIDLで
2.13.7. unsigned short
unsigned short
型は
16ビット符号なし整数に対応します。
unsigned short
の
定数値はIDLで
2.13.8. long
long
型は
32ビット符号付き整数に対応します。
long
の
定数値はIDLで
2.13.9. unsigned long
unsigned long
型は
32ビット符号なし整数に対応します。
unsigned long
の
定数値はIDLで
2.13.10. long long
long long
型は
64ビット符号付き整数に対応します。
long long
の
定数値はIDLで
2.13.11. unsigned long long
unsigned long long
型は
64ビット符号なし整数に対応します。
unsigned long long
の
定数値はIDLで
2.13.12. float
float
型は
浮動小数点数型で、有限な単精度32ビットIEEE 754浮動小数点数値の集合に対応します。
[IEEE-754]
float
の
定数値はIDLで
特別な理由がなければ32ビット浮動小数点型より
double
型を
仕様では使うべきです。
double
型の値集合の方が
JavaScriptのNumber型により近いからです。
2.13.13. unrestricted float
unrestricted float
型は
浮動小数点数型で、全ての単精度32ビットIEEE 754浮動小数点数値(有限値、非有限値、NaNなど特殊値含む)の集合に対応します。
[IEEE-754]
unrestricted float
の
定数値はIDLで
2.13.14. double
double
型は
浮動小数点数型で、有限な倍精度64ビットIEEE 754浮動小数点数値の集合に対応します。
[IEEE-754]
double
の
定数値はIDLで
2.13.15. unrestricted double
unrestricted double
型は
浮動小数点数型で、全ての倍精度64ビットIEEE 754浮動小数点数値(有限値、非有限値、NaNなど特殊値含む)の集合に対応します。
[IEEE-754]
unrestricted double
の
定数値はIDLで
2.13.16. bigint
bigint
型は
範囲制限のない任意精度整数型です。
bigint
の
定数値はIDLで
2.13.17. DOMString
注: DOMString
型の値ではありません。
DOMString
(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型(要素型はoctet
かbyte
)、
Uint8Array
、
Int8Array
を使うべきです。
ByteString
は避けてください。
2.13.19. USVString
USVString
型は
スカラー値文字列に対応します。
文脈によって、これらはコード単位の列や
スカラー値の列として扱われます。
USVString
型定数値はIDLで表現できませんが、
USVString
型
辞書メンバー
デフォルト値や
操作のoptional引数
デフォルト値には
文字列リテラルトークンの値を設定できます。
USVString
型は
テキスト処理APIなど、スカラー値列として
文字列処理が必要な場合のみ使うべきです。ほとんどのAPIは
DOMString
型を使うべきで、
コード単位の解釈をしません。
迷う場合はDOMString
を使ってください。
2.13.20. object
object
型は
全ての非nullオブジェクト参照の集合に対応します。
object
型定数値はIDLで表現できません。
全てのオブジェクト参照とobject?
を使ってください。
2.13.21. symbol
symbol
型は
全ての可能なsymbol値の集合に対応します。symbol値は不透明で
object
値ではありませんが、
識別性(自分自身のみ等価)を持ちます。
symbol
型定数値はIDLで表現できません。
2.13.22. インターフェイス型
識別子が インターフェイスを指す場合、 その型はそのインターフェイスを実装した全ての非nullオブジェクト参照の集合に対応します。
IDL値はオブジェクト参照のみで表現されます。
特定インターフェイス型のオブジェクト参照定数値はIDLで表現できません。
そのインターフェイスを実装する全てのオブジェクト参照と
2.13.23. コールバックインターフェイス型
識別子が コールバックインターフェイスを指す場合、 その型は全ての非nullオブジェクト参照の集合に対応します。
IDL値はオブジェクト参照と コールバックコンテキストのタプルで表現されます。 コールバックコンテキストは 言語バインディング固有値であり、言語バインディング固有オブジェクト参照をIDL値に変換する時点の実行コンテキスト情報を保持します。
注: JavaScriptオブジェクトの場合 コールバックコンテキストは そのObject値がIDLコールバックインターフェイス型値に変換される時点の インカンベント設定オブジェクトへの参照を保持します。 § 3.2.16 コールバックインターフェイス型参照。
特定コールバックインターフェイス型のオブジェクト参照定数値はIDLで表現できません。
全てのオブジェクト参照と
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)を基に、
追加で
-
他のnullable型
-
自体がnullable型を含むユニオン型、 またはflattened member型に辞書型を含むユニオン型
注: 辞書型は通常nullableですが、 操作引数型や辞書メンバー型として使う場合はnullable不可です。
nullable型定数値はIDLで、inner typeの定数値または
例えば、値がboolean?
と記述します:
[Exposed =Window ]interface NetworkFetcher {undefined get (optional boolean ?areWeThereYet =false ); };
次のインターフェイスは
2つの属性を持ちます。
1つはDOMString
またはNode
オブジェクト参照または
[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型のインスタンスです。
Kは
DOMString
、
USVString
、
ByteString
のいずれかでなければなりません。
順序付きマップのリテラル構文は 文脈からrecord型として扱われることが暗黙的に理解できればrecordの表現にも使えます。 ただし、IDLフラグメント内で定数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. ユニオン型
ユニオン型は
複数の型の値集合の合併となる型です。ユニオン型(
例えば(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
型と同様に、
ユニオン型の値には特定の型があり、
それは値に一致するメンバー型である。
注: 例えば
(Node or (sequence<long> or Event) or (XMLHttpRequest or DOMString)? or sequence<(sequence<double> or NodeList)>)
のflattened member型は
Node
、sequence<long>
、Event
、XMLHttpRequest
、DOMString
、
sequence<(sequence<double> or NodeList)>
の6型です。
nullableメンバー型数とは ユニオン型Tについて次の手順で決まる整数値です:
-
Tをユニオン型とする。
-
nを0で初期化。
-
ユニオン型Tの各Uについて:
-
Uがnullable型なら:
-
n=n+1。
-
Uをそのinner typeに置き換える。
-
-
Uがユニオン型なら:
-
mをUのnullableメンバー型数とする。
-
n=n+m。
-
-
-
nを返す。
any
型はユニオン型のメンバー型として使ってはなりません。
ユニオン型のnullableメンバー型数は0または1でなければならず、1の場合flattened member型に辞書型を含んではなりません。
型がnullable型を含むとは:
ユニオン型のflattened member型の各ペアT, Uは 区別可能でなければなりません。
bigint
型と数値型のユニオン型は作成可能ですが、
これは基本的にNumberFormat
など値を計算せず書式化するインターフェイス用です。
ユニオン型で受け取った値をbigint
に変換して計算に使うのは精度エラーの危険があるため推奨されません。
この機能の利用意向がある場合は
issue
を提出してください。
型がundefinedを含むとは:
-
その型が
undefined
型である -
その型がnullable型でinner typeがundefinedを含む
-
その型が注釈付き型でinner typeがundefinedを含む
-
その型がユニオン型でメンバー型のうち一つがundefinedを含む
ユニオン型の定数値はメンバー型の定数値と同じ方法でIDLで表現します。
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と呼びます。
以下の拡張属性は型に適用可能です:
[AllowResizable
],
[AllowShared
],
[Clamp
],
[EnforceRange
],
[LegacyNullToEmptyString
]
-
extended attributesを空の集合で初期化。
-
typeが
TypeWithExtendedAttributes 生成式の一部で現れる場合、 そのExtendedAttributeList に記載された 拡張属性をすべて extended attributesに追加します。 -
typeがユニオン型メンバーとして ユニオン型Uに含まれる場合、 Uに関連付けられる拡張属性を全てextended attributesに追加します。
-
typeが
Type 生成式内でArgument 生成式直下で現れる場合、 そのExtendedAttributeList に記載された 型に適用可能な拡張属性を全てextended attributesに追加します。 -
typeが
Type 生成式内でDictionaryMember 生成式直下で現れる場合、 そのExtendedAttributeList に記載された 型に適用可能な拡張属性を全てextended attributesに追加します。 -
typeがtypedefの場合、 新しい名前が与えられる型に関連付けられる拡張属性を追加します。
-
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属性の型としてのみ使うべきです。
[Exposed =Window ]interface PersonalPreferences {readonly attribute FrozenArray <DOMString >favoriteColors ;attribute FrozenArray <DOMString >favoriteFoods ;undefined randomizeFavoriteColors (); };
これらの属性の挙動は以下のように定義できます:
各PersonalPreferences
はfavorite colors(FrozenArray
<DOMString
>)を持ち、初期値は« "purple
", "aquamarine
" »からフローズン配列の生成を行った結果です。各
PersonalPreferences
はfavorite foods(FrozenArray
<DOMString
>)を持ち、初期値は空リストからフローズン配列の生成を行った結果です。
favoriteColors
のgetter手順はthis
のfavorite colorsを返す。
favoriteFoods
のgetter手順はthis
のfavorite foodsを返す。
favoriteFoods
のsetter手順はthis
のfavorite foodsをthe given value
に設定する。
randomizeFavoriteColors()
のメソッド手順は:
newFavoriteColorsを、ランダムに選んだ2つの色文字列のリストとする。
this
のfavorite colorsをnewFavoriteColorsからフローズン配列の生成を行った結果で設定する。
FrozenArray<T>値は参照であり、 sequence型が値渡しであるのとは異なります。
フローズン配列値をIDLで定数値として表現する方法はありません。
2.13.36. オブザーバブル配列型 — ObservableArray<T>
オブザーバブル配列型は 型パラメータ化されており、値はT型のオブジェクトからなる可変リストと、著者コードによるリスト内容変更時に実行される挙動を組み合わせたオブジェクト参照値です。
型パラメータTは辞書型、 sequence型、 record型、 オブザーバブル配列型のいずれも不可ですが、nullableは可です。
sequence型や フローズン配列型と同様、オブザーバブル配列型はJavaScript配列型のラッパーであり、使用時に追加意味論が課されます。
オブザーバブル配列型は、インターフェイス上で定義される 通常属性の型としてのみ使うべきです。
オブザーバブル配列型属性について、仕様策定者は以下のアルゴリズム群を指定できます:
-
インデックス付き値の設定(observable array に設定されようとしている IDL 値と、その値が設定されるインデックスを受け取る);
-
インデックス付き値の削除(observable array から削除されようとしている IDL 値と、その値が削除されるインデックスを受け取る)。
これらのアルゴリズムはどちらも任意であり、提供されていない場合、デフォルトの動作は何もしないことである。いずれのアルゴリズムも、例えば不正な値を拒否するために例外をスローしてもよい。
JavaScript コードが既存のインデックスに新しい値を設定するときは、まず インデックス付き値の削除アルゴリズムが呼び出され既存の値が削除され、 次に新しい値でインデックス付き値の設定アルゴリズムが呼び出される。
型がobservable array 型である通常の属性には、 バッキングリスト(リスト、初期状態は空)が存在する。 仕様策定者はバッキングリストの内容を修正することができ、その内容は JavaScript コードから観測される observable array の内容にも自動的に反映される。 同様に、JavaScript コードによる observable array の内容の変更は、 インデックス付き値の設定および インデックス付き値の削除アルゴリズムを通過した後、バッキングリストにも反映される。
IDL で定数の observable array 値を表現する方法は存在しない。
[Exposed =Window ]interface Building {attribute ObservableArray <Employee >employees ; };
属性の挙動は以下のように定義できます:
Building
のemployees
属性について、インデックス値設定アルゴリズムはemployeeとindexを受け取り:
employeeが今日建物に入る許可がなければ、"
NotAllowedError
"DOMException
をthrow。indexが200以上なら、
QuotaExceededError
(quota=200, requested=index)をthrow。employeeを勤務開始させる。
Building
のemployees
属性について、インデックス値削除アルゴリズムはemployeeとindexを受け取り:
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. employeesinstanceof Array); console. assert( Array. isArray( building. employees)); console. assert( building. employees. constructor === Array); // JSON.stringifyでも配列扱い(外側の[]に注意) console. assert( JSON. stringify( building. employees) === `[{}]` );
2.14. 拡張属性
拡張属性は、注釈であり
定義や
型(注釈付き型)、
インターフェイスメンバー、
インターフェイスミックスインメンバー、
コールバックインターフェイスメンバー、
名前空間メンバー、
辞書メンバー、
操作引数などに付与でき、
言語バインディングでの扱い方を制御します。
拡張属性は
文法記号 | 形式 | 例 |
---|---|---|
|
引数なし |
[Replaceable]
|
|
引数リストあり |
現行標準では未使用。過去には[Constructor(double x, double y)] で使用。
|
|
名前付き引数リストあり |
[LegacyFactoryFunction=Image(DOMString src)]
|
|
識別子あり |
[PutForwards=name]
|
|
文字列あり |
[Reflect="popover"]
|
|
整数あり |
[ReflectDefault=2]
|
|
小数あり |
[ReflectDefault=2.0]
|
|
整数リストあり |
[ReflectRange=(2, 600)]
|
|
識別子リストあり |
[Exposed=(Window,Worker)]
|
|
ワイルドカードあり |
[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オブジェクトの内部メソッドをオーバーライドすることは低レベルな操作であり、
通常オブジェクトと異なる挙動となる場合があるため、
セキュリティや互換性のために必要な場合以外は利用すべきではありません。
現状では
HTMLAllCollection
やLocation
インターフェイスの定義に使われています。[HTML]
特に指定がない限り、この節や他の仕様で定義されるエキゾチックオブジェクトは、 通常オブジェクトと同じ内部スロットを持ち、 代替定義がない内部メソッドは 通常オブジェクトと同じです。
特に指定がない限り、この節で定義されるオブジェクトの[[Extensible]]内部スロット値は
特に指定がない限り、この節で定義されるオブジェクトの[[Prototype]]内部スロットは
%Object.prototype%
です。
このセクションで説明される一部のオブジェクトには、クラス文字列が定義されている。
クラス文字列は、Object.prototype.toString
が返す文字列に含めるための文字列である。
オブジェクトがクラス文字列classStringを持つ場合、そのオブジェクトは作成時に、
名前が%Symbol.toStringTag%
であるプロパティを持たなければならない。
PropertyDescriptor{[[Writable]]:
この節のアルゴリズムはECMAScript § 5.2 アルゴリズム規約で説明される手順やサブ手順、数学演算などの記法慣例を用います。 また、他のECMA-262部分で定義された抽象演算や記法も参照する場合があります。
アルゴリズムで
throw SomethingError
と記述されている場合、
現在のrealmで
JavaScriptのSomethingError
オブジェクトを新たに構築し、
ECMA-262のアルゴリズムと同様にthrowすることを意味します。
アルゴリズムの手順は他のアルゴリズムや抽象演算を呼び出し、そこからthrowされる例外を明示的に処理しない場合があります。 例外がアルゴリズムや抽象演算からthrowされ、呼び出し元で明示的に処理されない場合、 そのアルゴリズムは終了し、例外は呼び出し元へ伝播し続けます。
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 iframeinstanceof w. Node; // false iframeinstanceof w. Object; // false iframe. appendChildinstanceof Function; // true iframe. appendChildinstanceof 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値型に対応できます。
IDL any
値は
JavaScript値へ変換
されますが、その際はIDL any
値の
具体型の変換規則に従います(以降の節参照)。
3.2.2. undefined
JavaScript値VをIDL undefined
値に
変換する場合、
Vを無視して一意なundefined
値を返します。
一意なIDL undefined
値は
JavaScript値へ変換する際、
JavaScriptの
3.2.3. boolean
IDL boolean
値
true
はJavaScript値へ変換した時、
JavaScriptのfalse
はJavaScriptの
3.2.4. 整数型
この節で使われる数学演算は、 ECMAScript § 5.2 アルゴリズム規約で定義されたものも含め、 数学的実数上の厳密な演算として理解してください。
つまり、xがNumber値である場合、 「xに対する演算」とは 「xと同じ数値を表す数学的実数に対する演算」を意味します。
3.2.4.1. byte
JavaScript値VをIDL byte
値に
変換するアルゴリズム:
-
xを? ConvertToInt(V, 8, "
signed
")の結果とする。 -
xと同じ数値を表すIDL
byte
値を返す。
IDL byte
値を
JavaScript値へ変換した結果は、
IDL byte
値と同じ数値を表す
Number値となります。
Number値は範囲[−128, 127]の整数です。
3.2.4.2. octet
JavaScript値VをIDL octet
値に
変換するアルゴリズム:
-
xを? ConvertToInt(V, 8, "
unsigned
")の結果とする。 -
xと同じ数値を表すIDL
octet
値を返す。
IDL octet
値を
JavaScript値へ変換した結果は、
IDL octet
値と同じ数値を表す
Number値となります。
Number値は範囲[0, 255]の整数です。
3.2.4.3. short
JavaScript値VをIDL short
値に
変換するアルゴリズム:
-
xを? ConvertToInt(V, 16, "
signed
")の結果とする。 -
xと同じ数値を表すIDL
short
値を返す。
IDL short
値を
JavaScript値へ変換した結果は、
IDL short
値と同じ数値を表す
Number値となります。
Number値は範囲[−32768, 32767]の整数です。
3.2.4.4. unsigned short
JavaScript値VをIDL unsigned short
値に
変換するアルゴリズム:
-
xを? ConvertToInt(V, 16, "
unsigned
")の結果とする。 -
xと同じ数値を表すIDL
unsigned short
値を返す。
IDL unsigned short
値を
JavaScript値へ変換した結果は、
IDL unsigned short
値と同じ数値を表す
Number値となります。
Number値は範囲[0, 65535]の整数です。
3.2.4.5. long
JavaScript値VをIDL long
値に
変換するアルゴリズム:
-
xを? ConvertToInt(V, 32, "
signed
")の結果とする。 -
xと同じ数値を表すIDL
long
値を返す。
IDL long
値を
JavaScript値へ変換した結果は、
IDL long
値と同じ数値を表す
Number値となります。
Number値は範囲[−2147483648, 2147483647]の整数です。
3.2.4.6. unsigned long
JavaScript値VをIDL unsigned long
値に
変換するアルゴリズム:
-
xを? ConvertToInt(V, 32, "
unsigned
")の結果とする。 -
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
値に
変換するアルゴリズム:
-
xを? ConvertToInt(V, 64, "
signed
")の結果とする。 -
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
値に
変換するアルゴリズム:
-
xを? ConvertToInt(V, 64, "
unsigned
")の結果とする。 -
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. 抽象演算
ConvertToInt(V, bitLength, signedness):
-
bitLengthが64なら:
-
upperBoundを253−1とする。
-
signednessが"
unsigned
"ならlowerBoundを0とする。 -
それ以外ならlowerBoundを−253+1とする。
注: これにより
long long
型に [EnforceRange
]や [Clamp
] 拡張属性が関連付けられている場合でも JavaScriptのNumber型で 明確な整数として表現可能です。
-
-
それ以外でsignednessが"
unsigned
"なら:-
lowerBoundを0とする。
-
upperBoundを2bitLength−1とする。
-
-
それ以外の場合:
-
lowerBoundを−2bitLength−1とする。
-
upperBoundを2bitLength−1−1とする。
-
-
xが−0ならxを+0にする。
-
変換先IDL型が[
EnforceRange
] 拡張属性に関連付けられていたら:-
xをIntegerPart(x)にする。
-
xを返す。
-
xが
NaN でなく、変換先IDL型が[Clamp
]拡張属性に関連付けられていたら: -
xが
NaN 、+0、+∞、−∞なら+0を返す。 -
xをIntegerPart(x)にする。
-
xをx modulo 2bitLengthにする。
-
signednessが"
signed
"かつx≥2bitLength−1なら x−2bitLengthを返す。 -
それ以外ならxを返す。
3.2.5. float
IDL float
値を
JavaScript値へ変換した結果は、
IDL float
値と同じ数値を表す
Number値です。
3.2.6. unrestricted float
JavaScript値VをIDL unrestricted float
値に
変換するアルゴリズム:
-
xが
NaN なら、 IEEE 754 NaN値(ビットパターン0x7fc00000)を表すIDLunrestricted float
値を返す。 [IEEE-754] -
Sを有限なIEEE 754単精度浮動小数点値集合(−0を除く)とし、2つの特殊値2128と−2128を加える。
-
yをxに最も近いS内の値とし、2つの値が同じだけ近い場合は有効数字が偶数の方を選択する。 (この目的で2128と−2128は有効数字が偶数と見なす。)
-
yが2128なら+∞を返す。
-
yが−2128なら−∞を返す。
-
yが+0かつxが負なら−0を返す。
-
yを返す。
注: JavaScriptの
IDL unrestricted float
値を
JavaScript値へ変換した結果はNumber値です:
-
IDL
unrestricted float
値がNaNなら、 Number値はNaN です。 -
それ以外は、IDL
unrestricted float
値と同じ数値を表すNumber値です。
3.2.7. double
IDL double
値を
JavaScript値へ変換した結果は、
IDL double
値と同じ数値を表す
Number値です。
3.2.8. unrestricted double
JavaScript値VをIDL unrestricted double
値に
変換するアルゴリズム:
-
xが
NaN なら、 IEEE 754 NaN値(ビットパターン0x7ff8000000000000)を表すIDLunrestricted double
値を返す。 [IEEE-754] -
xと同じ数値を表すIDL
unrestricted double
値を返す。
注: JavaScriptの
IDL unrestricted double
値を
JavaScript値へ変換した結果はNumber値です:
-
IDL
unrestricted double
値がNaNなら、 Number値はNaN です。 -
それ以外は、IDL
unrestricted double
値と同じ数値を表すNumber値です。
3.2.9. bigint
IDL bigint
値を
JavaScript値へ変換した結果はBigInt値です:
3.2.10. DOMString
JavaScript値VをIDL DOMString
値に
変換するアルゴリズム:
-
変換先IDL型が[
LegacyNullToEmptyString
]拡張属性に関連付けられていて Vがnull なら、空文字列を表すDOMString
値を返す。 -
JavaScript String値xが表すコード単位列と同じ列を表すIDL
DOMString
値を返す。
IDL DOMString
値を
JavaScript値へ変換した結果は、
IDL DOMString
が表す
コード単位列と同じ列を表す
String値です。
3.2.11. ByteString
JavaScript値VをIDL ByteString
値に
変換するアルゴリズム:
IDL ByteString
値を
JavaScript値へ変換した結果は、
ByteString
の長さと同じ長さで、
各要素値が対応する
ByteString
の要素値と同じ
String値です。
3.2.12. USVString
IDL USVString
値Sを
JavaScript値へ変換した結果はSです。
3.2.13. object
IDL object
値は
JavaScriptのObject値で表現されます。
JavaScript値VをIDL object
値に
変換するアルゴリズム:
-
VがObject型でない場合、 throw
TypeError
。 -
Vと同じオブジェクトを参照するIDL
object
値を返す。
IDL object
値を
JavaScript値へ変換した結果は、
IDL object
が
参照する同一オブジェクトを参照するObject値です。
3.2.14. symbol
IDL symbol
値は
JavaScriptのSymbol値で表現されます。
symbol
値に
変換するアルゴリズム:
-
VがSymbol型でない場合、 throw
TypeError
。 -
Vと同じSymbolを参照するIDL
symbol
値を返す。
IDL symbol
値を
JavaScript値へ変換した結果は、
IDL symbol
が
参照する同一Symbolを参照するSymbol値です。
3.2.15. インターフェイス型
IDL インターフェイス型値は JavaScriptのObject値(関数オブジェクトも含む)で表現されます。
IDL インターフェイス型値を JavaScript値へ変換した結果は、 IDL インターフェイス型値が参照する同一オブジェクトを参照する Object値です。
3.2.16. コールバックインターフェイス型
IDL コールバックインターフェイス型値は JavaScriptのObject値(関数オブジェクトも含む)で表現されます。
JavaScript値VをIDL コールバックインターフェイス型値に 変換するアルゴリズム:
-
VがObject型でない場合、 throw
TypeError
。 -
Vへの参照を持つIDL コールバックインターフェイス型値を返す。 この時現任設定オブジェクトをコールバックコンテキストとする。
IDL コールバックインターフェイス型値を JavaScript値へ変換した結果は、 IDL コールバックインターフェイス型値が参照する同一オブジェクトを参照する Object値です。
3.2.17. 辞書型
IDL 辞書型値は JavaScriptのObject値で表現されます。オブジェクト(またはプロトタイプチェーン上)のプロパティが 辞書メンバーに対応します。
JavaScript値jsDictをIDL 辞書型値に 変換するアルゴリズム(Dは辞書型):
-
jsDictがObject型でなく
undefined でもnull でもない場合、 throwTypeError
。 -
idlDictを空の順序付きマップ(型Dの辞書)で初期化。
-
dictionariesを、Dとその全継承辞書のリスト(派生度が低い順→高い順)とする。
-
dictionaries内の各dictionaryについて順に:
-
dictionaryに宣言された各memberについて辞書順:
-
-
idlDictを返す。
注: JavaScriptオブジェクト上で辞書メンバーを検索する順序は オブジェクトのプロパティ列挙順とは限りません。
IDL辞書値VをJavaScript値へ変換するアルゴリズム(Dは辞書):
-
dictionariesを、Dとその全継承辞書のリスト(派生度が低い順→高い順)とする。
-
dictionaries内の各dictionaryについて順に:
-
dictionaryに宣言された各memberについて辞書順:
-
keyをmemberの識別子とする。
-
V[key]が存在すれば:
-
idlValueをV[key]とする。
-
valueをidlValueをJavaScript値へ変換した結果とする。
-
! CreateDataPropertyOrThrow(O, key, value)を実行。
-
-
-
-
Oを返す。
3.2.18. 列挙型
IDL 列挙型は JavaScriptのString値で表現されます。
IDL 列挙型値を JavaScript値へ変換した結果は、 コード単位列が 列挙値と同じであるString値です。
3.2.19. コールバック関数型
IDL コールバック関数型は
JavaScriptの関数オブジェクトで表現されます。
ただし[LegacyTreatNonObjectAsNull
]の場合は任意のオブジェクトも可です。
JavaScript値VをIDL コールバック関数型値に 変換する手順:
-
IsCallable(V)の結果が
false で、 変換先IDL値が属性の値となる場合であり、 その属性型が[LegacyTreatNonObjectAsNull
]注釈付きnullableな コールバック関数型でない場合、 throwTypeError
。 -
Vが参照するオブジェクトへの参照を持ち、現任設定オブジェクトをコールバックコンテキストとするIDL コールバック関数型値を返す。
IDL コールバック関数型値を JavaScript値へ変換した結果は、 IDL コールバック関数型値が参照する同一オブジェクトを参照する値です。
3.2.20. nullable型 — T?
IDL nullable型値は
inner
IDL型に対応するJavaScript型の値、またはJavaScriptの
JavaScript値VをIDL nullable型 T?
値に
変換する手順(Tはinner型):
-
VがObject型でない場合で、 Vが属性の値として割り当てられる場合、 その属性型が[
LegacyTreatNonObjectAsNull
]注釈付きnullableな コールバック関数型であるなら、IDL nullable型T?
値null を返す。 -
それ以外でVが
undefined かつTがundefinedを含むなら、一意なundefined
値を返す。 -
それ以外でVが
null またはundefined なら、 IDL nullable型T?
値null を返す。 -
それ以外は変換規則に従い、 T型としてVを変換した結果を返す。
IDL nullable型値を JavaScript値へ変換する手順:
-
IDL nullable型
T?
値がnull なら、 JavaScript値はnull 。 -
それ以外は、inner型
T
としてIDL値をJavaScript値へ変換した結果。
3.2.21. sequence型 — sequence<T>
IDL sequence<T>値は JavaScriptのArray値で表現されます。
JavaScript値VをIDL sequence<T>値に 変換する手順:
-
VがObject型でない場合、 throw
TypeError
。 -
methodを? GetMethod(V,
%Symbol.iterator%
)の結果とする。 -
Vとmethodからsequenceの生成を行った結果を返す。
型sequence<T>の IDL sequence値Sを JavaScriptのArrayオブジェクトに変換する手順:
-
nをSの長さとする。
-
Aを
[]
式で生成した新しいArrayオブジェクトとする。 -
iを0で初期化。
-
i<nの間:
-
VをSのインデックスiの値とする。
-
EをVをJavaScript値へ変換した結果とする。
-
! CreateDataPropertyOrThrow(A, P, E)を実行。
-
iをi+1にする。
-
-
Aを返す。
3.2.21.1. イテラブルからsequenceの生成
イテラブルiterableとイテレータ取得メソッドmethodが与えられたとき、型sequence<T>のIDL値を生成するには、以下の手順を行う:
-
iteratorRecordを? GetIteratorFromMethod(iterable, method)の結果とする。
-
iを0で初期化。
-
繰り返し:
-
nextを? IteratorStepValue(iteratorRecord)の結果とする。
-
nextが
done なら、 長さiの型sequence<T>のIDL値を返す。 インデックスjの要素の値はSjとする。 -
Siをnextを型TのIDL値に変換した結果で初期化。
-
iをi+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値は 以下の構造体として表現される:
-
object:JavaScript値
-
method:JavaScript値
-
type:"sync"もしくは"async"
-
VがObject型でない場合、 throw
TypeError
。 -
methodを? GetMethod(obj,
%Symbol.asyncIterator%
)の結果とする。 -
methodが
undefined の場合:-
syncMethodを? GetMethod(obj,
%Symbol.iterator%
)の結果とする。 -
IDL async sequence値を返す。objectにV、 methodにsyncMethod、 typeに"sync"を設定。
-
-
IDL async sequence値を返す。objectにV、 methodにmethod、 typeに"async"を設定。
3.2.22.1. 非同期sequenceのイテレーション
async sequenceは直接イテレートされません。まずオープンして非同期イテレータを作成し、その非同期イテレータを非同期的にイテレートして値を生成します。
-
underlying record:Iterator Record
-
type parameter:非同期イテレータが生成する値の型を表すIDL型
async sequenceのオープン手順:
async_sequence<T>
sequenceについて:
-
iteratorを? GetIteratorFromMethod(sequenceのobject, sequenceのmethod)とする。
-
sequenceのtypeが"
sync
"の場合は iteratorをCreateAsyncFromSyncIterator(iterator)の結果に置換する。 -
非同期イテレータ値を返す。 underlying recordにiterator、 type parameterにTを設定。
非同期イテレータの次の値取得手順: 非同期イテレータ iteratorについて:
-
nextResultを IteratorNext(iteratorのunderlying record)の結果とする。
-
nextResultがabrupt completionなら、その値でrejectされたpromiseを返す。
-
nextPromiseをnextResultの値でresolveされたpromiseとする。
-
nextPromiseに対して、以下のfulfilledステップで反応する(iterResultを与える):
-
iterResultがObject型でない場合は、throw
TypeError
。 -
doneを? IteratorComplete(iterResult)の結果とする。
-
もしdoneがtrueなら:
-
イテレーション終了を返す。
-
-
それ以外:
-
Vを? IteratorValue(iterResult)の結果とする。
-
valueをVをiteratorのtype parameter型のIDL値に変換した結果とする。
-
valueを返す。
-
-
非同期イテレータのクローズ手順:
async iterator<T>
iterator(ECMAScript値reason付き)について:
-
iteratorRecordをiteratorのunderlying recordとする。
-
iteratorObjをiteratorRecord.[[Iterator]]とする。
-
returnMethodをGetMethod(iteratorObj, "
return
")の結果とする。 -
returnMethodがabrupt completionなら、その値でrejectされたpromiseを返す。
-
returnMethodが
undefined なら、undefinedでresolveされたpromiseを返す。 -
returnResultをCall(returnMethod.[[Value]], iteratorObj, « reason »)の結果とする。
-
returnResultがabrupt completionなら、その値でrejectされたpromiseを返す。
-
returnPromiseをreturnResultの値でresolveされたpromiseとする。
-
returnPromiseに対して、以下のfulfilledステップで反応する(returnPromiseResultを与える):
-
returnPromiseResultがObject型でない場合は、throw
TypeError
。 -
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)
メソッドの手順:
-
promiseを新しいpromiseとする。
-
resultを空文字列で初期化。
-
nを0で初期化。
-
iteratorをsequenceをオープンした結果とする。
-
stepをasync sequenceを処理する手順列とする:
-
stepを呼び出す。
-
promiseを返す。
3.2.23. record型 — record<K, V>
IDL record<K, V>値は JavaScriptのObject値で表現されます。
IDL
record<…>
値Dを
JavaScript値へ変換する手順:
-
resultをOrdinaryObjectCreate(
%Object.prototype%
)で初期化。 -
-
jsKeyをkeyをJavaScript値に変換した結果とする。
-
jsValueをvalueをJavaScript値に変換した結果とする。
-
createdを! CreateDataProperty(result, jsKey, jsValue)の結果とする。
-
(アサーション)createdは
true である。
-
-
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>
値に
変換する手順:
-
promiseCapabilityを? NewPromiseCapability(
%Promise%
)で初期化。 -
promiseCapabilityを返す。
IDL promise型値を JavaScript値へ変換した結果は、 IDL promise型値が表すレコードの[[Promise]]フィールドの値です。
3.2.24.1. Promiseの生成・操作
新しいPromiseの生成手順:
Promise<T>
を
realm realmで生成するには:
-
constructorをrealm.[[Intrinsics]].[[
%Promise%
]]とする。 -
? NewPromiseCapability(constructor)を返す。
resolveされたpromiseの生成手順:
Promise<T>
型で値x(型T)をrealm realmに持つ場合:
-
valueをxをJavaScript値に変換した結果とする。
-
constructorをrealm.[[Intrinsics]].[[
%Promise%
]]とする。 -
promiseCapabilityを? NewPromiseCapability(constructor)で初期化。
-
! Call(promiseCapability.[[Resolve]],
undefined , « value »)を実行。 -
promiseCapabilityを返す。
rejectされたpromiseの生成手順:
Promise<T>
型で理由r(JavaScript値)をrealm realmに持つ場合:
-
constructorをrealm.[[Intrinsics]].[[
%Promise%
]]とする。 -
promiseCapabilityを? NewPromiseCapability(constructor)で初期化。
-
promiseCapabilityを返す。
resolve手順:
Promise<T>
pを値x(型T)でresolveするには:
-
xが与えられていない場合は、一意な
undefined
値とする。 -
valueをxをJavaScript値に変換した結果とする。
promiseへの反応手順:
Promise<T>
promiseに対して、fulfilled/rejectedまたは両方の場合の処理手順を与えて以下を実行:
-
引数Vで呼ばれるonFulfilledStepsを以下とする:
-
valueをVを型TのIDL値に変換した結果とする。
-
promiseがfulfilledの場合に実行する手順があれば、resultをその手順をvalue(Tが
undefined
以外の場合のみ)で実行した結果とし、 それ以外はresultをvalueとする。 -
resultをJavaScript値に変換して返す。
-
-
onFulfilledをCreateBuiltinFunction(onFulfilledSteps, « »)とする。
-
引数Rで呼ばれるonRejectedStepsを以下とする:
-
promiseがrejectedの場合に実行する手順があれば、resultをその手順をreasonで実行した結果とし、 それ以外はresultをreasonでrejectされたpromiseとする。
-
resultをJavaScript値に変換して返す。
-
onRejectedをCreateBuiltinFunction(onRejectedSteps, « »)とする。
-
constructorをpromise.[[Promise]].[[Realm]].[[Intrinsics]].[[
%Promise%
]]とする。 -
newCapabilityを? NewPromiseCapability(constructor)で初期化。
注: 返した
Promise
を 呼び出し側が必ず使うとは限りません。実装によってはnewCapabilityの生成を省略してよい場合があります。 -
PerformPromiseThen(promise.[[Promise]], onFulfilled, onRejected, newCapability)を実行。
-
newCapabilityを返す。
注: このアルゴリズムは
promise.then()
メソッドと非常に似た動作をします。
特に、手順が型UまたはPromise<U>
値を返す場合、
このアルゴリズムもPromise<U>
を返します。
fulfillment時の処理手順:
Promise<T>
promiseのfulfillment時に型Tの値を受け取る手順stepsを実行するには:
-
promiseへの反応手順の結果を返す:
-
promiseが値vでfulfilledされた場合:
-
stepsをvで実行。
-
-
rejection時の処理手順:
Promise<T>
promiseのrejection時にJavaScript値を受け取る手順stepsを実行するには:
-
promiseへの反応手順の結果を返す:
-
promiseが理由rでrejectedされた場合:
-
stepsをrで実行。
-
-
全てを待つ手順:
list型
Promise<T>
値promises、成功時手順successSteps(list型T値を受け取る)、失敗時手順failureSteps(理由any
値を受け取る)について:
-
fullfilledCountを0で初期化。
-
rejectedをfalseで初期化。
-
rejectionHandlerStepsを引数argで呼ばれる以下の手順とする:
-
rejectedがtrueならこの手順を中止。
-
rejectedをtrueにする。
-
failureStepsをargで実行。
-
-
rejectionHandlerをCreateBuiltinFunction(rejectionHandlerSteps, « »)とする。
-
totalをpromisesのsizeとする。
-
totalが0なら:
-
マイクロタスクをキューしてsuccessStepsに« »を与えて実行。
-
return。
-
-
indexを0で初期化。
-
resultをtotal個のnull値のlistで初期化。
-
-
promiseIndexをindexとする。
-
fulfillmentHandlerを引数argで呼ばれる以下の手順とする:
-
result[promiseIndex]にargをセット。
-
fullfilledCountをfullfilledCount+1に。
-
fullfilledCountがtotalと等しければsuccessStepsにresultを与えて実行。
-
-
fulfillmentHandlerをCreateBuiltinFunction(fulfillmentHandler, « »)とする。
-
PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler)を実行。
-
indexをindex+1に。
-
全てを待つpromiseの取得手順:
list型
Promise<T>
値promisesと
realm realmについて:
-
promiseを新しいPromise型
Promise<sequence<T>>
をrealmで生成した結果とする。 -
successStepsを引数resultsで呼ばれる以下の手順とする:
-
resolve promiseをresultsで実行。
-
-
failureStepsを引数reasonで呼ばれる以下の手順とする:
-
reject promiseをreasonで実行。
-
-
全てを待つ手順に promises、successSteps、failureStepsを与えて実行。
-
promiseを返す。
この定義は複数promiseの結果を集約して新たなpromiseを生成したい場合に有用です。
これはJavaScriptのPromise.all()
と同様です。
新たなpromiseが不要なら全てを待つ手順の方が適しています。
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 ); };
validatedDelay
は操作で、delay関数と似ていますが
引数のバリデーションを行います。
非同期処理開始前に即時rejectされたpromiseを使う例です。
interface I {Promise <undefined >validatedDelay (unrestricted double ms ); };
validatedDelay(ms)
メソッドの手順:
-
taskSourceを適切なタスクソースとする。
-
msがNaNならTypeErrorでrejectされたpromiseをrealmで返す。
-
msが0未満ならRangeErrorでrejectされたpromiseをrealmで返す。
-
pを新しいpromiseをrealmで生成したものとする。
-
以下の手順を並行して行う:
-
pを返す。
addDelay
は操作で、promiseのsettle後に追加で指定した遅延(ms)を加えて
新しいpromiseのsettleを遅らせます。
interface I {Promise <any >addDelay (Promise <any >promise ,unrestricted double ms ); };
addDelay(ms, promise)
メソッドの手順:
-
taskSourceを適切なタスクソースとする。
-
msがNaNならmsを+0とし、そうでなければmsと+0の大きい方にする。
-
pを新しいpromiseをrealmで生成したものとする。
-
promiseへの反応をpromiseに対して行う:
-
pを返す。
environment.ready
は属性で、環境(例: DOM documentなど)が「ready」状態になった時を通知します。
環境に依存した非同期状態のコーディング例です。
interface Environment {readonly attribute Promise <undefined >ready ; };
すべてのEnvironment
オブジェクトはready
promise(型Promise<undefined>
)を持ちます。
ready
属性getterの手順:
-
thisのready promiseを返す。
Environment
オブジェクトをrealm realmで生成する手順:
-
taskSourceを適切なタスクソースとする。
-
environmentをnew
Environment
オブジェクトとしてrealmで生成する。 -
environmentのready promiseを新しいpromiseで初期化。
-
以下の手順を並行して行う:
-
非同期処理を実行する。
-
environmentがreadyになったら、タスクをキューしてtaskSource上でresolve environmentのready promiseを行う。
-
environmentがreadyにならなかったら、タスクをキューしてtaskSource上でreject environmentのready promiseを "
NetworkError
"DOMException
で行う。
-
-
environmentを返す。
addBookmark
は操作で、ユーザーに現在のウェブページをブックマーク登録するようリクエストします。
設計検討の例からの実例で、
環境非同期性や即時rejectの現実的な使い方を示します。
interface I {Promise <undefined >addBookmark (); };
addBookmark()
メソッドの手順:
-
taskSourceを適切なタスクソースとする。
-
このメソッドが明示的なユーザー操作によって呼び出されていなければ、 SecurityErrorでrejectされたpromise
DOMException
を返す。 -
ドキュメントの動作モードがスタンドアロンなら NotSupportedErrorでrejectされたpromise
DOMException
を返す。 -
promiseを新しいpromiseで初期化。
-
infoをウェブアプリのメタデータ取得結果とする。
-
以下の手順を並行して行う:
-
infoを使って、ユーザーエージェント依存で ユーザーがブックマーク追加するか選択できるようにする。
-
ブックマーク追加リクエストをユーザーが中止したら(例: Escapeキーや「キャンセル」ボタンなど)、 タスクをキューしてtaskSource上でreject promiseを "
AbortError
"DOMException
で行う。
-
-
-
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)
メソッドの手順:
-
responsePromisesを空リスト« »で初期化。
-
-
pを
fetch()
にurlを渡して呼び出した結果とする。
-
-
pをget a promise to wait for allでresponsePromisesを渡して呼び出した結果とする。
-
pを返す。
3.2.25. ユニオン型
IDL ユニオン型値は JavaScriptの値で表現され、 それぞれユニオンのメンバー型に対応します。
JavaScript値VをIDL ユニオン型値に 変換する手順:
-
ユニオン型がundefinedを含む場合でVが
undefined なら、 一意なundefined
値を返す。 -
ユニオン型がnullable型を含む場合で Vが
null またはundefined なら、 IDL値null を返す。 -
typesをユニオン型のフラット化メンバー型とする。
-
Vが
null またはundefined の場合: -
Vがプラットフォームオブジェクトなら:
-
VがObject型で、Vが[[ArrayBufferData]] 内部スロットを持ち、 IsSharedArrayBuffer(V)がfalseなら:
-
typesに
ArrayBuffer
が含まれていれば、 VをArrayBuffer
に変換した結果を返す。 -
typesに
object
が含まれていれば、 Vへの参照を持つIDL値を返す。
-
-
VがObject型で、Vが[[ArrayBufferData]] 内部スロットを持ち、 IsSharedArrayBuffer(V)がtrueなら:
-
typesに
SharedArrayBuffer
が含まれていれば、 VをSharedArrayBuffer
に変換した結果を返す。 -
typesに
object
が含まれていれば、 Vへの参照を持つIDL値を返す。
-
-
IsCallable(V)がtrueなら:
-
VがObject型なら:
-
typesにasync sequence型が含まれていれば:
-
typesに文字列型が含まれていないか、 Vが[[StringData]] 内部スロットを持たない場合:
-
asyncMethodを? GetMethod(V,
%Symbol.asyncIterator%
)の結果とする。 -
asyncMethodが
undefined でなければ、 async sequence型のIDL値を返す。 objectにV、 methodにsyncMethod、 typeに"async"を設定。 -
syncMethodを? GetMethod(V,
%Symbol.iterator%
)の結果とする。 -
syncMethodが
undefined でなければ、 async sequence型のIDL値を返す。 objectにV、 methodにsyncMethod、 typeに"sync"を設定。
-
-
-
typesにsequence型が含まれていれば:
-
methodを? GetMethod(V,
%Symbol.iterator%
)の結果とする。 -
methodが
undefined でなければ、 sequenceを生成した結果を返す。
-
-
typesにfrozen array型が含まれていれば:
-
methodを? GetMethod(V,
%Symbol.iterator%
)の結果とする。 -
methodが
undefined でなければ、 frozen arrayを生成した結果を返す。
-
-
typesにコールバックインターフェイス型が含まれていれば、 Vをその型に変換した結果を返す。
-
typesに
object
が含まれていれば、 Vへの参照を持つIDL値を返す。
-
-
VがBoolean型なら:
-
VがNumber型なら:
-
VがBigInt型なら:
-
typesに数値型と
bigint
が含まれていれば、 Vを数値型またはbigint型へ変換した結果を返す。 -
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クラスのオブジェクトとして表現され、さらに以下の制約が適用されます。
-
型が[
AllowResizable
]または[AllowShared
]拡張属性(該当する場合)に 関連付けられていない場合、 JavaScriptArrayBuffer
オブジェクトVのうち、IsResizableArrayBuffer(V)がfalseであるもののみ裏付けできます。 -
型が[
AllowResizable
]拡張属性にのみ 関連付けられている場合、 JavaScriptArrayBuffer
オブジェクトのみ裏付けできます。 -
型が[
AllowShared
]拡張属性にのみ 関連付けられている場合、 JavaScriptArrayBuffer
およびSharedArrayBuffer
オブジェクトVのうち、 IsResizableArrayBuffer(V)がfalseであるもののみ裏付けできます。 -
型が[
AllowResizable
]と [AllowShared
]両方の 拡張属性に 関連付けられている場合、 すべてのJavaScriptArrayBuffer
およびSharedArrayBuffer
オブジェクトが裏付けできます。
JavaScript値VをIDL ArrayBuffer
値に
変換するアルゴリズム:
-
VがObject型でない、 またはVが[[ArrayBufferData]] 内部スロットを持たない場合、 throw
TypeError
。 -
IsSharedArrayBuffer(V)がtrueなら throw
TypeError
。 -
変換先IDL型が[
AllowResizable
]拡張属性に関連付けられていない場合で、 IsResizableArrayBuffer(V)がtrueなら throwTypeError
。 -
Vと同じオブジェクトへの参照を持つIDL
ArrayBuffer
値を返す。
JavaScript値VをIDL SharedArrayBuffer
値に
変換するアルゴリズム:
-
VがObject型でない、 またはVが[[ArrayBufferData]] 内部スロットを持たない場合、 throw
TypeError
。 -
IsSharedArrayBuffer(V)がfalseなら throw
TypeError
。 -
変換先IDL型が[
AllowResizable
]拡張属性に関連付けられていない場合で、 IsResizableArrayBuffer(V)がtrueなら throwTypeError
。 -
Vと同じオブジェクトへの参照を持つIDL
SharedArrayBuffer
値を返す。
JavaScript値VをIDL DataView
値に
変換するアルゴリズム:
-
VがObject型でない、 またはVが[[DataView]] 内部スロットを持たない場合、 throw
TypeError
。 -
変換先IDL型が[
AllowShared
]拡張属性に関連付けられていない場合で、 IsSharedArrayBuffer(V.[[ViewedArrayBuffer]])がtrueなら throwTypeError
。 -
変換先IDL型が[
AllowResizable
]拡張属性に関連付けられていない場合で、 IsResizableArrayBuffer(V.[[ViewedArrayBuffer]])がtrueなら throwTypeError
。 -
Vと同じオブジェクトへの参照を持つIDL
DataView
値を返す。
JavaScript値 V は、
変換
されて、IDLの Int8Array
、
Int16Array
、
Int32Array
、
Uint8Array
、
Uint16Array
、
Uint32Array
、
Uint8ClampedArray
、
BigInt64Array
、
BigUint64Array
、
Float16Array
、
Float32Array
、
または
Float64Array
値に
変換されるため、次のアルゴリズムを実行する:
-
T を、V が変換されようとしている IDL 型とする。
-
もし V がObject でない、 または V が [[TypedArrayName]] 内部スロットを持たず、その値が T の名前と等しくない場合、 throw で
TypeError
をスローする。 -
変換先が [
AllowShared
] 拡張属性に関連付けられていない IDL 型であり、IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) が true の場合、 throw でTypeError
をスローする。 -
変換先が [
AllowResizable
] 拡張属性に関連付けられていない IDL 型であり、IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) が true の場合、 throw でTypeError
をスローする。 -
T 型の IDL 値で、V と同じオブジェクトへの参照を返す。
ArrayBuffer
arrayBuffer を:
-
jsArrayBuffer を ? AllocateArrayBuffer(realm.[[Intrinsics]].[[
%ArrayBuffer%
]], bytes の 長さ) とする。 -
arrayBuffer を、jsArrayBuffer を
ArrayBuffer
型のIDL値に変換した結果とする。 -
bytes を arrayBuffer に 書き込む。
-
arrayBuffer を返す。
SharedArrayBuffer
バイト列 bytes を realm realm で:
-
jsSharedArrayBuffer を ? AllocateSharedArrayBuffer(realm.[[Intrinsics]].[[
%SharedArrayBuffer%
]], bytes の 長さ) とする。 -
sharedArrayBuffer を、jsSharedArrayBuffer を
SharedArrayBuffer
型のIDL値に変換した結果とする。 -
bytes を sharedArrayBuffer に 書き込む。
-
sharedArrayBuffer を返す。
ArrayBufferView
型のいずれかを
バイト列 bytes を realm realm で:
-
型が
DataView
でない場合、bytes の 長さ を、その型の 要素サイズ で割った余りが 0 であることを保証する。 -
arrayBuffer を ArrayBuffer を bytes から realm で作成した結果とする。
-
jsArrayBuffer を arrayBuffer を JavaScript値に変換した結果とする。
-
constructor を realm.[[Intrinsics]] から作成する
ArrayBufferView
型に対応するコンストラクタとする。 -
jsView を与えられた型に 変換した結果を返す。
-
jsBufferSource を bufferSource を JavaScript値に変換した結果とする。
-
jsArrayBuffer を jsBufferSource とする。
-
offset を 0 とする。
-
length を 0 とする。
-
jsBufferSource が [[ViewedArrayBuffer]] 内部スロット を持つ場合:
-
jsArrayBuffer を jsBufferSource.[[ViewedArrayBuffer]] に設定する。
-
offset を jsBufferSource.[[ByteOffset]] に設定する。
-
length を jsBufferSource.[[ByteLength]] に設定する。
-
-
それ以外の場合:
-
jsBufferSource は
ArrayBuffer
またはSharedArrayBuffer
オブジェクトであることを保証する。 -
length を jsBufferSource.[[ArrayBufferByteLength]] に設定する。
-
-
IsDetachedBuffer(jsArrayBuffer) が true なら、空の バイト列 を返す。
-
i を 範囲 offset から offset + length − 1 までの各値について、bytes[i − offset] に GetValueFromBuffer(jsArrayBuffer, i, Uint8, true, Unordered) の結果を設定する。
-
bytes を返す。
-
jsBufferSource を bufferSource を JavaScript値に変換した結果とする。
-
jsBufferSource が [[ViewedArrayBuffer]] 内部スロットを持つ場合は、 jsBufferSource.[[ByteLength]] を返す。
-
jsBufferSource.[[ArrayBufferByteLength]] を返す。
-
bufferSource が buffer型 のインスタンスであれば bufferSource を返す。
-
jsBufferView を bufferSource を JavaScript値に変換した結果とする。
-
jsBuffer を jsBufferView.[[ViewedArrayBuffer]] とする。
-
IsSharedArrayBuffer(jsBuffer) が false の場合、 jsBuffer を
ArrayBuffer
型のIDL値に変換した結果を返す。 -
jsBuffer を
SharedArrayBuffer
型のIDL値に変換した結果を返す。
-
jsArrayBuffer を arrayBuffer を JavaScript値に変換した結果とする。
-
bytes の 長さ ≤ jsArrayBuffer.[[ArrayBufferByteLength]] − startingOffset であることを保証する。
-
i を startingOffset から startingOffset + bytes の 長さ − 1 までの範囲で、SetValueInBuffer(jsArrayBuffer, i, Uint8, bytes[i - startingOffset], true, Unordered) を実行する。
ArrayBufferView
view に、オプションで startingOffset(デフォルト0)を指定して、以下の手順を実行する:
-
jsView を view を JavaScript値に変換した結果とする。
-
bytes の 長さ ≤ jsView.[[ByteLength]] − startingOffset であることを保証する。
-
もし view が
DataView
でなければ、 bytes の 長さ を 要素サイズで割った余りが0であることを保証する。 -
arrayBuffer を、jsView.[[ViewedArrayBuffer]] を
ArrayBuffer
型のIDL値に変換した結果とする。 -
bytes を arrayBuffer に startingOffset = jsView.[[ByteOffset]] + startingOffset で書き込む。
SharedArrayBuffer
オブジェクトが関与する場合は注意が必要である。
共有されていない場合は、より推奨されるパターンとして、まず ArrayBuffer を転送して、他の変更と重複して書き込みが発生しないことを保証し、
必要に応じて新しい ArrayBuffer
インスタンスを著者コードに渡すことができる。
または、バイト列のコピーを取得し、そのバイト列を変更し、
それを使って新しい ArrayBuffer
または ArrayBufferView
を作成して著者コードに渡すこともできる。
ArrayBuffer
バイト列
bytes を realm realm で:
-
jsArrayBuffer を arrayBuffer を JavaScript値に変換した結果とする。
-
? DetachArrayBuffer(jsArrayBuffer) を実行する。
この操作は、
jsArrayBuffer が [[ArrayBufferDetachKey]] を持ち、その値が undefined でない場合(例えば WebAssembly.Memory
の
buffer
属性の場合)には例外を投げる。
[WASM-JS-API-1]
すでに 切り離されたバッファを切り離す操作は何も起こらない(no-op)である。
-
jsArrayBuffer を bufferSource を JavaScript値に変換した結果とする。
-
jsArrayBuffer が [[ViewedArrayBuffer]] 内部スロットを持つ場合は、 jsArrayBuffer を jsArrayBuffer.[[ViewedArrayBuffer]] に設定する。
-
IsDetachedBuffer(jsArrayBuffer) の結果を返す。
-
jsArrayBuffer を bufferSource を JavaScript値に変換した結果とする。
-
jsArrayBuffer が [[ViewedArrayBuffer]] 内部スロットを持つ場合は、 jsArrayBuffer を jsArrayBuffer.[[ViewedArrayBuffer]] に設定する。
-
IsSharedArrayBuffer(jsArrayBuffer) が true なら、false を返す。
-
IsDetachedBuffer(jsArrayBuffer) が true なら、false を返す。
-
jsArrayBuffer.[[ArrayBufferDetachKey]] が
undefined でないなら、false を返す。 -
true を返す。
ArrayBuffer
arrayBuffer に対して、オプションで レルム targetRealm を指定して以下の手順を行う:
-
jsArrayBuffer を arrayBuffer を JavaScript値に変換した結果とする。
-
IsDetachedBuffer(jsArrayBuffer) が false なら、TypeError を投げる。
-
arrayBufferData を jsArrayBuffer.[[ArrayBufferData]] とする。
-
arrayBufferByteLength を jsArrayBuffer.[[ArrayBufferByteLength]] とする。
-
? DetachArrayBuffer(jsArrayBuffer) を実行する。
-
targetRealm が指定されていない場合は、targetRealm を 現在のレルムとする。
-
jsTransferred を ? AllocateArrayBuffer(targetRealm.[[Intrinsics]].[[
%ArrayBuffer%
]], 0) とする。 -
jsTransferred.[[ArrayBufferData]] を arrayBufferData に設定する。
-
jsTransferred.[[ArrayBufferByteLength]] を arrayBufferByteLength に設定する。
-
jsTransferred を
ArrayBuffer
型のIDL値に変換した結果を返す。
-
arrayBuffer を 切り離せない場合(そのアルゴリズムの定義で説明されている理由による);
-
arrayBuffer がすでに 切り離されている場合;
-
realm で十分なメモリが確保できない場合。通常これは realm が arrayBuffer が割り当てられたものと異なる エージェントクラスタに属する場合のみである。同じ エージェントクラスタなら、実装はポインタの付け替えだけで可観測結果が同じになり、より高いパフォーマンスで割り当ても不要となる。
3.2.27. フローズン配列 — FrozenArray<T>
フローズン配列型の値は、フローズンされた JavaScript Array オブジェクトの参照として表現される。
JavaScript値 V は 変換 されて、IDL FrozenArray<T>値になる。以下のアルゴリズムを実行する:
-
values を、V を IDL 型 sequence<T> に変換した結果とする。
-
フローズン配列を作成して values から得られた結果を返す。
値の列 T から フローズン配列を作成するには、以下の手順を実行する:
-
array を 型 T の値の列を JavaScript 値に変換した結果とする。
-
! SetIntegrityLevel(array, "
frozen
") を実行する。 -
array を返す。
IDL の FrozenArray<T> 値をJavaScript 値に変換した結果は、 その IDL の FrozenArray<T> が表すオブジェクトと同じオブジェクトへの参照を表す Object 値である。
3.2.27.1. イテラブルからフローズン配列を作成する
イテラブル iterable とイテレーター取得関数 method を用いて、型 FrozenArray<T> のIDL値を作成するには、以下の手順を実行する:
-
values を、iterable と method から sequence を生成し、型は sequence<T> とすることで得られる結果とする。
-
values から frozen array を生成した結果を返す。
3.2.28. オブザーバブル配列 — ObservableArray<T>
オブザーバブル配列型の値は、オブザーバブル配列エキゾチックオブジェクトによって表現される。
通常の変換アルゴリズムの代わりに、オブザーバブル配列型は 属性ゲッターと属性セッターアルゴリズムの一部として特別な処理を持つ。
JavaScript バインディングでは、プラットフォームオブジェクトを表す JavaScript オブジェクトは、 observable array 型 の 通常属性ごとに 対応する observable array exotic object を持つ。 これらは 属性定義アルゴリズムの一部として生成・管理される。
-
Assert: obj が インターフェイスのinterfaceを実装し、その 通常属性 attribute を持つこと。
-
oa を obj の 裏で支えるオブザーバブル配列エキゾチックオブジェクト(attribute用)とする。
-
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
]
を使う場合の具体的な要件が記載されている。
3.3.3. [Clamp]
[Clamp
] 拡張属性が整数型に付与された場合、JavaScript
Number をそのIDL型に変換するとき、範囲外の値は有効な値の範囲にクランプされる新しいIDL型が作成される。これは、剰余演算子(ToInt32、ToUint32 など)を使う場合とは異なる動作となる。
[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 ); };
setColorClamped
を octet
の範囲外の
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
, Human
、Dog
(継承経由)オブジェクトに
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型に変換するとき、範囲外の値は剰余演算子(ToInt32、ToUint32 など)を使って有効値に変換せず、例外を投げる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実装では、setColorEnforcedRange
を octet
の範囲外の 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 を取る場合 - [
Exposed
] 拡張属性が識別子リスト I を取る場合 - [
Exposed
] 拡張属性がワイルドカードを取る場合 -
自身の公開セットは
*
である。
[Exposed=*]
の使用には注意が必要である。
APIが重要な新機能を公開しない場合のみ適している。
APIが環境によって制限・無効化される可能性がある場合は、グローバルを明示的に列挙する方が望ましい。
公開セットの共通部分は、構成要素 C と interface-or-null H に対し次のように定義される:
-
Assert: C は インターフェイスメンバー、インターフェイスミクシンメンバー、名前空間メンバー、 部分インターフェイス、部分インターフェイスミクシン、部分名前空間、インターフェイスミクシンであること。
-
Assert: H は インターフェイスまたはnullである。
-
H が null なら、C の 自身の公開セット を返す。
-
Assert: C は インターフェイス、コールバックインターフェイス、 名前空間、 インターフェイスメンバー、インターフェイスミクシンメンバー、または名前空間メンバーであること。
-
H を C が インターフェイスミクシンメンバーなら ホストインターフェイス、そうでなければ null とする。
-
C が インターフェイスメンバー、インターフェイスミクシンメンバー、名前空間メンバーなら:
-
[
Exposed
] 拡張属性が C に指定されていれば、公開セットの共通部分(C, H) を返す。 -
C を元の インターフェイス、部分インターフェイス、 インターフェイスミクシン、部分インターフェイスミクシン、 名前空間、部分名前空間の C に設定する。
-
-
C が 部分インターフェイス、部分インターフェイスミクシン、部分名前空間なら:
-
[
Exposed
] 拡張属性が C に指定されていれば、公開セットの共通部分(C, H) を返す。 -
C を元の インターフェイス、インターフェイスミクシン、名前空間の定義の C に設定する。
-
-
C が インターフェイスミクシンなら:
-
H は null ではないこと。
-
[
Exposed
] 拡張属性が C に指定されていれば、公開セットの共通部分(C, H) を返す。 -
C を H に設定する。
-
-
C は インターフェイス、コールバックインターフェイス、名前空間であること。
-
C の 自身の公開セットを返す。
[Exposed
] が オーバーロードされた 操作に指定されている場合、全てのオーバーロードに同一に指定されなければならない。
[Exposed
] 拡張属性は
インターフェイスメンバー、
インターフェイスミクシンメンバー、
名前空間メンバー
と 部分インターフェイス、
部分インターフェイスミクシン、
部分名前空間定義の両方に指定してはならない。
注: 部分インターフェイス、部分インターフェイスミクシン、部分名前空間に [Exposed
] 拡張属性を付与するのは、各メンバーに個別に付与する省略表現であるためである。
[Exposed
] が 部分インターフェイスまたは部分名前空間に指定されている場合、その 自身の公開セットは
元の インターフェイスまたは
名前空間の 公開セットの部分集合でなければならない。
[Exposed
] が インターフェイスメンバーまたは名前空間メンバーに指定されている場合、その メンバーの公開セットは
所属する インターフェイスまたは名前空間の 公開セットの部分集合でなければならない。
[Exposed
] が 部分インターフェイスミクシンと元の インターフェイスミクシンの両方に指定されている場合、部分インターフェイスミクシンの 自身の公開セットはインターフェイスミクシンの
自身の公開セットの部分集合でなければならない。
[Exposed
] が インターフェイスミクシンメンバーと インターフェイスミクシンの両方に指定されている場合、そのインターフェイスミクシンメンバーの
自身の公開セットは
インターフェイスミクシンの 自身の公開セットの部分集合でなければならない。
インターフェイス X が他のインターフェイス Y を 継承している場合、X の 公開セットは Y の 公開セットの部分集合でなければならない。
注: インターフェイスミクシンは複数の インターフェイスに include できるので、そのメンバーの 公開セットは
それを include した インターフェイスに依存する関数となる。
[Exposed
] 拡張属性が
インターフェイスミクシンメンバー、部分インターフェイスミクシン、インターフェイスミクシンに付与されていれば、そのメンバーの 公開セットは該当構成要素の 自身の公開セットと ホストインターフェイスの 公開セットの共通部分となる。そうでなければホストインターフェイスの 公開セットとなる。
-
construct の 公開セットが
*
でなく、 realm.[[GlobalObject]] が construct の 公開セット内の インターフェイスを実装していなければ false を返す。 -
realm の 設定オブジェクトがセキュアコンテキストでなく、かつ construct が [
SecureContext
] で条件付き公開されていれば false を返す。 -
realm の 設定オブジェクトのクロスオリジン分離機能が false で、construct が [
CrossOriginIsolated
] で条件付き公開されていれば false を返す。 -
true を返す。
-
Assert: construct は インターフェイス、コールバックインターフェイス、 名前空間、 インターフェイスメンバー、インターフェイスミクシンメンバー、名前空間メンバーであること。
-
H を construct が インターフェイスミクシンメンバーなら ホストインターフェイス、そうでなければ null とする。
-
construct が インターフェイスメンバー、インターフェイスミクシンメンバー、名前空間メンバーなら:
-
exposure condition 拡張属性が construct に指定されていれば true を返す。
-
そうでなければ construct を元の インターフェイス、部分インターフェイス、 インターフェイスミクシン、部分インターフェイスミクシン、 名前空間、部分名前空間の construct に設定する。
-
-
construct が 部分インターフェイス、部分インターフェイスミクシン、部分名前空間なら:
-
exposure condition 拡張属性が construct に指定されていれば true を返す。
-
そうでなければ construct を元の インターフェイス、インターフェイスミクシン、名前空間の定義の construct に設定する。
-
-
construct が インターフェイスミクシンなら:
-
exposure condition 拡張属性が construct に指定されていれば true を返す。
-
そうでなければ construct を H に設定する。
-
-
construct は インターフェイス、コールバックインターフェイス、名前空間であること。
-
exposure condition 拡張属性が construct に指定されていれば true を返す。
-
そうでなければ false を返す。
注: JavaScriptグローバルオブジェクトの関連設定オブジェクトがセキュアコンテキストやクロスオリジン分離機能の有無を後から変更できないため、インターフェイスやインターフェイスメンバーのプロパティ作成は初期オブジェクトが作成される時点で一度決定できる。
詳細は
§ 3.7 インターフェイス、
§ 3.7.5 定数、
§ 3.7.6 属性、
§ 3.7.7 操作
を参照。[Exposed
]
使用時の具体的な要件が記載されている。
[Exposed
]
は、インターフェイス、
コールバックインターフェイス、名前空間、または個々のインターフェイス、
ミクシン、
名前空間メンバーが
ワーカー、Worklet
、
Window
、
あるいはその組み合わせで利用可能かを制御するために使うことを意図している。
以下の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
」は複数種のスレッド関連グローバルインターフェイスを指すために使われている。
こうしたグローバルインターフェイスは、プロトタイプチェーンの構造や インターフェイスメンバーに対応するプロパティの反映方法が他のインターフェイスと異なる。具体的には:
-
名前付きプロパティは、オブジェクト自身ではなくプロトタイプチェーン上の 名前付きプロパティオブジェクト に公開される。
-
インターフェイスメンバーは インターフェイスから オブジェクト自身のプロパティとなり、 インターフェイスプロトタイプオブジェクトのプロパティにはならない。
全てのレルムは グローバルプロトタイプチェーンが可変かどうかというブール値を持つ。 これはレルム生成時に設定され、その後は変更できない。デフォルトは false。
これにより ShadowRealm
グローバルは可変プロトタイプを持てる。
名前付きプロパティをプロトタイプチェーン上のオブジェクトに置く理由は、変数宣言や裸の代入で グローバルオブジェクト自身のプロパティが名前付きプロパティを隠す(シャドウする)ためである。
インターフェイスメンバーに対応するプロパティをオブジェクト自身に置くことで、以下のような機能検出コードが機能する:
var indexedDB= window. indexedDB|| window. webkitIndexedDB|| window. mozIndexedDB|| window. msIndexedDB; var requestAnimationFrame= window. requestAnimationFrame|| window. mozRequestAnimationFrame|| ...;
JavaScriptの変数宣言の扱いにより、上記コードは window.indexedDB
や window.requestAnimationFrame
の評価結果が
[Global
] 拡張属性がインターフェイスに使われた場合:
-
インターフェイスは名前付きプロパティセッターを定義してはならない。
-
インターフェイスはインデックス付きプロパティゲッターやセッターを定義してはならない。
-
インターフェイスはコンストラクタ操作を定義してはならない。
-
インターフェイスは[
LegacyOverrideBuiltIns
]拡張属性と同時に宣言してはならない。 -
インターフェイスは [
LegacyOverrideBuiltIns
] 拡張属性を持つ他のインターフェイスから継承してはならない。 -
他のインターフェイスはこのインターフェイスから継承してはならない。
[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
]
拡張属性は
識別子を取らなければならない。
前提として:
-
A は [
PutForwards
] 拡張属性が付与された属性、 -
I は A が宣言されているインターフェイス、
-
J は A の型として宣言されているインターフェイス型、
-
N は拡張属性引数の識別子、
この場合、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
]
拡張属性は
名前付き引数リストを取らなければならない。
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 名前空間オブジェクト を参照。
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型が作成される。
[LegacyNullToEmptyString
]
拡張属性は
DOMString
またはUSVString
型以外には関連付けてはならない。
注: DOMString?
であっても[LegacyNullToEmptyString
]は使えない。
詳細要件については § 3.2.10 DOMString を参照。
[Exposed =Window ]interface Dog {attribute DOMString name ;attribute [LegacyNullToEmptyString ]DOMString owner ;boolean isMemberOfBreed ([LegacyNullToEmptyString ]DOMString breedName ); };
このインターフェイスを実装するJavaScriptでは、Dog
のownerプロパティやisMemberOfBreedの引数に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の継承インターフェイスの一つである場合、BはXと同じ識別子の通常属性や非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
]
拡張属性は
識別子または
識別子リストを取ることができる。
「=」の後に現れる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つの入力を取る:
-
操作呼び出しや属性アクセスが行われているプラットフォームオブジェクト
-
操作や属性の識別子
-
関数オブジェクトの種類 — 操作の場合は"
method
"、属性のgetter/setterの場合は"getter
"または"setter
"。
注: セキュリティチェックの実装方法はHTML標準で定義されている。[HTML]
3.6. オーバーロード解決アルゴリズム
関数呼び出しの解決方法を定義するため、オーバーロード解決アルゴリズムを定義する。入力は有効オーバーロード集合Sと、JavaScript値のリストargs。出力は、Sのいずれかのエントリの操作または拡張属性と、IDL値のリストまたは特別な値“missing”のペアである。アルゴリズムは以下のように動作する:
-
maxargをS内で最も長い型リストの長さとする。
-
nをargsのサイズとする。
-
argcountをmin(maxarg, n)で初期化する。
-
argcount長でない型リストを持つSのエントリを全て除去する。
-
もしSが空なら、TypeErrorをスローする。
-
dを−1で初期化する。
-
methodを
undefined で初期化する。 -
もしSに複数エントリがあれば、dをSのエントリに対する識別引数インデックスで設定する。
-
valuesを空リストで初期化する(各エントリはIDL値または“missing”になる)。
-
iを0で初期化する。
-
while i < d:
-
もしi = dなら:
-
Vをargs[i]とする。
注: この引数でどのオーバーロードを選ぶか決定される。
-
もしVが
undefined で、Sにオプション性値リストがインデックスiで“optional”なエントリがあれば、他のエントリをSから除去。 -
それ以外で、Vが
null またはundefined で、Sに以下の型がインデックスiにあるエントリがあれば:-
union型または注釈付きunion型でnullable型を含むかdictionary型をflattenedメンバーにもつ
他のエントリをSから除去。
-
それ以外でVがプラットフォームオブジェクトで、Sに以下型がインデックスiにあるエントリがあれば:
-
上記型のnullable版
-
上記型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
他のエントリをSから除去。
-
それ以外でVがObjectで[[ArrayBufferData]]内部スロットを持ち、Sに以下型がインデックスiにあるエントリがあれば:
-
上記型のnullable版
-
上記型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
他のエントリをSから除去。
-
それ以外でVがObjectで[[DataView]]内部スロットを持ち、Sに以下型がインデックスiにあるエントリがあれば:
他のエントリをSから除去。
-
それ以外でVがObjectで[[TypedArrayName]]内部スロットを持ち、Sに以下型がインデックスiにあるエントリがあれば:
-
TypedArray型で名前がVの[[TypedArrayName]]と一致するもの
-
上記型のnullable版
-
上記型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
他のエントリをSから除去。
-
-
それ以外でIsCallable(V)がtrueで、Sに以下型がインデックスiにあるエントリがあれば:
他のエントリをSから除去。
-
それ以外でVがObjectで、Sに以下型がインデックスiにあるエントリがあれば:
-
上記型のnullable版
-
上記型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
かつ下記条件が全てfalseの場合:
-
Vが[[StringData]]内部スロットを持つ
-
Sがインデックスiで以下型を持つ:
-
string型のnullable版
-
string型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
さらに以下を実行:
-
methodをVの
%Symbol.asyncIterator%
から取得。 -
もしmethodが
undefined なら、%Symbol.iterator%
から取得。
methodが
undefined でなければ他のエントリをSから除去。 -
それ以外でVがObjectで、Sに以下型がインデックスiにあるエントリがあれば:
-
上記型のnullable版
-
上記型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
以下を実行:
-
methodをVの
%Symbol.iterator%
から取得。
methodが
undefined でなければ他のエントリをSから除去。 -
それ以外でVがObjectで、Sに以下型がインデックスiにあるエントリがあれば:
-
上記型のnullable版
-
上記型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
他のエントリをSから除去。
-
それ以外でVがBooleanで、Sに以下型がインデックスiにあるエントリがあれば:
-
boolean型のnullable版
-
boolean型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
他のエントリをSから除去。
-
それ以外でVがNumberで、Sに以下型がインデックスiにあるエントリがあれば:
-
数値型のnullable版
-
数値型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
他のエントリをSから除去。
-
それ以外でVがBigIntで、Sに以下型がインデックスiにあるエントリがあれば:
-
bigint型のnullable版
-
bigint型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
他のエントリをSから除去。
-
それ以外でSにインデックスiで以下型があるエントリがあれば:
-
string型のnullable版
-
string型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
他のエントリをSから除去。
-
それ以外でSにインデックスiで以下型があるエントリがあれば:
-
数値型のnullable版
-
数値型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
他のエントリをSから除去。
-
それ以外でSにインデックスiで以下型があるエントリがあれば:
-
boolean型のnullable版
-
boolean型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
他のエントリをSから除去。
-
それ以外でSにインデックスiで以下型があるエントリがあれば:
-
bigint型のnullable版
-
bigint型を内包する注釈付き型
-
上記型をflattenedメンバーに持つunion型、nullable union型、注釈付きunion型
他のエントリをSから除去。
-
それ以外でSにインデックスiで
any
型があるエントリがあれば、他のエントリをSから除去。 -
それ以外はTypeErrorをスローする。
-
-
もしi = dかつmethodが
undefined でない場合: -
while i < argcount:
-
while iがcallableが宣言する引数の数より小さい間:
-
もしcallableのインデックスiの引数がデフォルト値付きなら、valuesにそのデフォルト値を追加。
-
それ以外でcallableのインデックスiの引数がvariadicでなければ、valuesに“missing”を追加。
-
iをi + 1にする。
-
-
ペア <callable, values> を返す。
オーバーロード解決アルゴリズムは、呼び出されるオーバーロードされた操作やコンストラクタ等の特定と、JavaScript引数値の対応するIDL値への変換の両方を行う。非公式には以下のように動作する。
まず、関数に渡されたJavaScript引数の数で有効なオーバーロードを選択する:
-
最も長いオーバーロード引数リストより多く引数が渡された場合、それらは無視される。
-
これらの末尾引数を無視した後、この正確な引数数を受け入れられるオーバーロードのみを考慮する。該当するものがなければ
TypeError
をスローする。
正しい引数数の可能なオーバーロード集合が得られたら、JavaScript値を左から右へ変換する。オーバーロード時の制約により、この時点で複数の候補がある場合、引数リストの中でどの位置を使って最終的なオーバーロードを選択するかが決まる。この位置が識別引数インデックスである。
まず識別引数より左の引数を変換する(左側の引数は他のオーバーロードでも同じインデックスで同じ型である必要がある)。次に識別引数インデックスで渡されたJavaScript値の型を調べ、それがどのIDL型に対応するかを判定する。これにより最終的に呼び出すオーバーロードが決定される。ここで渡された値がTypeError
をスローする。一般的に、識別引数インデックスでの値検査は副作用を持たず、オーバーロード解決アルゴリズムでの副作用はJavaScript値のIDL値への変換のみである(例外として、識別引数インデックスがasync sequence型、sequence型、frozen
array型のいずれかの場合、該当するオーバーロードを決めるために%Symbol.asyncIterator%
/ %Symbol.iterator%
プロパティの取得を試み、識別引数の変換を個別に行う)。
この時点で使用するオーバーロードが決定したので、残りの引数(識別引数以降)も変換し、最後の可能な引数以降に渡された余分な引数は引き続き無視する。
optional引数のJavaScript値をIDL値に変換する際、
ただし、最終の可変長(variadic)引数に対応するoptional引数の場合は、
3.7. インターフェイス
あるインターフェイスが特定の公開レルムで公開されていて、かつ[LegacyNoInterfaceObject
]や[LegacyNamespace
]拡張属性が宣言されていない場合、そのインターフェイスに対応するプロパティがそのレルムのグローバルオブジェクトに存在する。
プロパティ名はインターフェイスの識別子であり、その値はインターフェイスオブジェクトというオブジェクトである。
インターフェイスオブジェクトの特性については§ 3.7.1 インターフェイスオブジェクトを参照。
もし LegacyWindowAlias
拡張属性が 公開されたインターフェイスに指定されている場合、
LegacyWindowAlias の
識別子ごとに、Window
グローバルオブジェクト上に対応するプロパティが存在する。
プロパティ名は指定された 識別子 となり、
その値は インターフェイスオブジェクトへの参照である。
さらに、公開インターフェイス上の各[LegacyFactoryFunction
]拡張属性ごとに、JavaScriptグローバルオブジェクト上に対応するプロパティが存在する。
プロパティ名は[LegacyFactoryFunction
]の識別子であり、その値はレガシーファクトリ関数と呼ばれるオブジェクトで、インターフェイスを実装するオブジェクトの生成を可能にする。
レガシーファクトリ関数の特性については§ 3.7.2 レガシーファクトリ関数を参照。
オブジェクトの実装チェックを行うには、jsValueをインターフェイスinterface・識別子name・型typeに対して:
-
objectがプラットフォームオブジェクトなら、以下を渡してセキュリティチェックを実行:
-
プラットフォームオブジェクトobject
-
識別子name
-
型type
-
-
objectを返す。
このアルゴリズムは現時点で一貫して使われているわけではない。
3.7.1. インターフェイスオブジェクト
あるインターフェイスオブジェクトは、そのインターフェイスに対応する組み込み関数オブジェクトとなる。 インターフェイスオブジェクトには、そのインターフェイス上で定義された定数やstatic操作に対応するプロパティが存在する(詳細は§ 3.7.5 定数や§ 3.7.7 操作参照)。
インターフェイスがコンストラクタ操作で宣言されている場合、そのインターフェイスオブジェクトはコンストラクタとして呼び出すことができ、そのインターフェイスを実装するオブジェクトが生成される。 関数として呼び出すと例外が投げられる。
インターフェイスオブジェクトで、そのインターフェイスがコンストラクタ操作で宣言されていない場合、関数としてもコンストラクタとしても呼び出すと例外が投げられる。
インターフェイスIのインターフェイスオブジェクトは、インターフェイスプロトタイプオブジェクトを関連付けて持つ。 このプロトタイプオブジェクトには、インターフェイス上で定義された通常属性や通常操作に対応するプロパティが存在し、詳細は§ 3.7.3 インターフェイスプロトタイプオブジェクト参照。
注: インターフェイスオブジェクトは関数オブジェクトなので、typeof演算子を適用すると"function"が返る。
インターフェイスはオーバーライドされたコンストラクタ手順を持ちうる。これによりインターフェイスオブジェクトの呼び出しや構築時の挙動が変更される。デフォルトではこの手順は持たない。
通常、コンストラクタはコンストラクタ操作とその挙動を定義することで記述される。 オーバーライドされたコンストラクタ手順は、より複雑な状況でのみ使用すること。 この機能を使いたい編集者は事前にissueを提出して議論することを強く推奨する。
インターフェイスI(識別子id)のインターフェイスオブジェクトをrealm(レルム)で生成する手順:
-
steps を、I の オーバーライドされたコンストラクタ手順が存在すればそれとし、存在しない場合は以下の手順とする:
-
argsを渡された引数とする。
-
nをargsのサイズとする。
-
idをインターフェイスIの識別子とする。
-
コンストラクタの有効オーバーロード集合を、識別子id・インターフェイスI・引数数nで計算し、Sとする。
-
Sとargsをオーバーロード解決アルゴリズムに渡し、結果を<constructor, values>とする。
-
objectを内部的にインターフェイスIを実装する新しいオブジェクトを生成(realmと
NewTarget
を指定)し、得る。 -
OをobjectをJavaScript値に変換したものとする。
-
Assert: OはインターフェイスIを実装するオブジェクトである。
-
Assert: O.[[Realm]]はrealmである。
-
Oを返す。
-
constructorProtoをrealm.[[Intrinsics]].[[
%Function.prototype%
]]とする。 -
Iが他のインターフェイスPから継承していれば、constructorProtoをrealm内のPのインターフェイスオブジェクトとする。
-
FをCreateBuiltinFunction(steps, « [[Unforgeables]] » , realm, constructorProto)とする。
-
unforgeablesをOrdinaryObjectCreate(
null )で生成。 -
非偽造通常操作をIからunforgeablesへ定義(realm指定)。
-
非偽造通常属性をIからunforgeablesへ定義(realm指定)。
-
F.[[Unforgeables]]にunforgeablesをセットする。
注: このオブジェクトはユーザーコードに公開されない。インターフェイスの非偽造メンバーがすべてのインスタンスで同じJavaScript関数オブジェクト(属性getter・setter・操作関数)を使うためだけに存在する。
-
SetFunctionName(F, id)を実行。
-
lengthを0で初期化。
-
Iがコンストラクタ操作で宣言されていれば:
-
コンストラクタの有効オーバーロード集合を、識別子id・インターフェイスI・引数数0で計算し、Sとする。
-
lengthをS内で最も短い引数リストの長さにセット。
-
-
SetFunctionLength(F, length)を実行。
-
protoをインターフェイスプロトタイプオブジェクト生成(インターフェイスI・realm指定)の結果とする。
-
! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: proto, [[Writable]]:
false , [[Enumerable]]:false , [[Configurable]]:false })を実行。 -
定数をインターフェイスIからFへ定義(realm指定)。
-
static属性をインターフェイスIからFへ定義(realm指定)。
-
static操作をインターフェイスIからFへ定義(realm指定)。
-
Fを返す。
3.7.2. レガシーファクトリ関数
あるレガシーファクトリ関数は、1つ以上の[LegacyFactoryFunction
]拡張属性が同じ識別子で定義されていることで存在し、組み込み関数オブジェクトとなる。
これは、その[LegacyFactoryFunction
]拡張属性が現れるインターフェイスを実装するオブジェクトを生成できる。
インターフェイスI(識別子id)・realmでのレガシーファクトリ関数を生成する手順:
-
stepsを以下の手順とする:
-
argsを渡された引数とする。
-
nをargsのサイズとする。
-
レガシーファクトリ関数の有効オーバーロード集合を、識別子id・インターフェイスI・引数数nで計算し、Sとする。
-
Sとargsをオーバーロード解決アルゴリズムに渡し、結果を<constructor, values>とする。
-
objectを内部的にインターフェイスIを実装する新しいオブジェクトを生成(realmと
NewTarget
を指定)し、得る。 -
OをobjectをJavaScript値に変換したものとする。
-
Assert: OはインターフェイスIを実装するオブジェクトである。
-
Assert: O.[[Realm]]はrealmである。
-
Oを返す。
-
FをCreateBuiltinFunction(steps, « » , realm)とする。
-
SetFunctionName(F, id)を実行。
-
レガシーファクトリ関数の有効オーバーロード集合を、識別子id・インターフェイスI・引数数0で計算し、Sとする。
-
lengthをS内で最も短い引数リストの長さにセット。
-
SetFunctionLength(F, length)を実行。
-
protoをインターフェイスIのインターフェイスプロトタイプオブジェクト(realm指定)の結果とする。
-
! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: proto, [[Writable]]:
false , [[Enumerable]]:false , [[Configurable]]:false })を実行。 -
Fを返す。
3.7.3. インターフェイスプロトタイプオブジェクト
全てのインターフェイスに対して、[LegacyNoInterfaceObject
]拡張属性で宣言されているかどうかに関わらず、インターフェイスプロトタイプオブジェクトが存在する。
インターフェイスinterfaceとrealmに対するインターフェイスプロトタイプオブジェクトの生成手順:
-
protoをnullで初期化。
-
interfaceが[
Global
]拡張属性で宣言され、かつ名前付きプロパティをサポートする場合、protoをinterfaceとrealmで名前付きプロパティオブジェクト生成の結果でセット。 -
それ以外でinterfaceが他インターフェイスから継承していれば、protoをrealm内のその継承インターフェイスのインターフェイスプロトタイプオブジェクトでセット。
-
それ以外でinterfaceが
DOMException
インターフェイスなら、protoをrealm.[[Intrinsics]].[[%Error.prototype%
]]でセット。 -
それ以外はprotoをrealm.[[Intrinsics]].[[
%Object.prototype%
]]でセット。 -
Assert: protoはObjectである。
-
interfaceProtoObjをnullで初期化。
-
もしrealmのグローバルプロトタイプチェーンがmutableなら:
-
interfaceProtoObjをOrdinaryObjectCreate(proto)で生成。
-
-
それ以外でinterfaceが[
Global
]拡張属性で宣言されている、あるいはinterfaceが[Global
]拡張属性で宣言されているインターフェイスの継承インターフェイス集合に含まれている場合:-
interfaceProtoObjをMakeBasicObject(« [[Prototype]], [[Extensible]] »)で生成。
-
interfaceProtoObj.[[Prototype]]にprotoをセット。
-
interfaceProtoObjの内部メソッドをimmutable prototype exotic objectの定義に従ってセット。
-
-
それ以外はinterfaceProtoObjをOrdinaryObjectCreate(proto)で生成。
-
interfaceに[
Unscopable
]拡張属性で宣言されたメンバーがあれば:-
unscopableObjectをOrdinaryObjectCreate(null)で生成。
-
全ての公開メンバーmember([
Unscopable
]拡張属性付き)について:-
idにmemberの識別子をセット。
-
! CreateDataPropertyOrThrow(unscopableObject, id, true)を実行。
-
-
descにPropertyDescriptor{[[Value]]: unscopableObject, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}をセット。
-
! DefinePropertyOrThrow(interfaceProtoObj,
%Symbol.unscopables%
, desc)を実行。
-
-
interfaceが[
Global
]拡張属性で宣言されていなければ:-
通常属性定義をinterfaceからinterfaceProtoObjへ(realm指定)。
-
通常操作定義をinterfaceからinterfaceProtoObjへ(realm指定)。
-
反復メソッド定義をinterfaceからinterfaceProtoObjへ(realm指定)。
-
非同期反復メソッド定義をinterfaceからinterfaceProtoObjへ(realm指定)。
-
-
定数定義をinterfaceからinterfaceProtoObjへ(realm指定)。
-
[
LegacyNoInterfaceObject
]拡張属性がinterfaceに指定されていなければ:-
constructorをrealm内のinterfaceのインターフェイスオブジェクトでセット。
-
descにPropertyDescriptor{[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true, [[Value]]: constructor}をセット。
-
! DefinePropertyOrThrow(interfaceProtoObj, "constructor", desc)を実行。
-
-
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
]拡張属性で宣言され、かつ名前付きプロパティをサポートする全てのインターフェイスに対して、そのインターフェイスが名前付きプロパティを公開する名前付きプロパティオブジェクトが存在する。
-
protoをnullで初期化。
-
interfaceが他インターフェイスから継承していれば、protoをrealm内の継承インターフェイスのインターフェイスプロトタイプオブジェクトでセット。
-
それ以外はprotoをrealm.[[Intrinsics]].[[
%Object.prototype%
]]でセット。 -
objをMakeBasicObject(« [[Prototype]], [[Extensible]] »)で生成。
-
obj.[[GetOwnProperty]]を§ 3.7.4.1 [[GetOwnProperty]]の定義に従ってセット。
-
obj.[[DefineOwnProperty]]を§ 3.7.4.2 [[DefineOwnProperty]]の定義に従ってセット。
-
obj.[[Delete]]を§ 3.7.4.3 [[Delete]]の定義に従ってセット。
-
obj.[[SetPrototypeOf]]を§ 3.7.4.4 [[SetPrototypeOf]]の定義に従ってセット。
-
obj.[[PreventExtensions]]を§ 3.7.4.5 [[PreventExtensions]]の定義に従ってセット。
-
obj.[[Prototype]]にprotoをセット。
-
objを返す。
注: 名前付きプロパティオブジェクトの[[OwnPropertyKeys]]内部メソッドはOrdinaryOwnPropertyKeysを使い続ける。レガシープラットフォームオブジェクトの対応物とは異なる。名前付きプロパティは「本当の」独自プロパティではないため、この内部メソッドでは返されない。
名前付きプロパティオブジェクトのクラス文字列は、インターフェイスの識別子と文字列"Properties
"を連結したもの。
3.7.4.1. [[GetOwnProperty]]
名前付きプロパティオブジェクトOの[[GetOwnProperty]]内部メソッドがプロパティキーPで呼ばれたとき、以下の手順を行う:
-
AをOに対応するインターフェイスとする。
-
objectをO.[[Realm]]のグローバルオブジェクトとする。
-
Assert: objectはAを実装する。
-
名前付きプロパティ可視性アルゴリズムをプロパティ名P・オブジェクトobjectで実行した結果がtrueなら:
-
operationを名前付きプロパティゲッター宣言に使われた操作とする。
-
valueを未初期化変数とする。
-
もしoperationが識別子無しで定義されていれば、valueにインターフェイス記述の「名前付きプロパティの値決定」手順(Pをnameとして)を実行した結果をセット。
-
それ以外の場合、operationが識別子付きで定義されていれば、valueに操作の記述の手順(Pを唯一の引数値として)を実行した結果をセット。
-
descをフィールド無しの新しいProperty Descriptorとして生成。
-
desc.[[Value]]にvalueをJavaScript値へ変換した結果をセット。
-
もしAが[
LegacyUnenumerableNamedProperties
]拡張属性を持つインターフェイスを実装していれば、desc.[[Enumerable]]にfalseをセット、それ以外はtrueをセット。 -
desc.[[Writable]]にtrue、desc.[[Configurable]]にtrueをセット。
-
descを返す。
-
-
OrdinaryGetOwnProperty(O, P)を返す。
3.7.4.2. [[DefineOwnProperty]]
名前付きプロパティオブジェクトの[[DefineOwnProperty]]内部メソッドが呼び出されたとき、以下の手順を行う:
-
false を返す。
3.7.4.3. [[Delete]]
名前付きプロパティオブジェクトの[[Delete]]内部メソッドが呼び出されたとき、以下の手順を行う:
-
false を返す。
3.7.4.4. [[SetPrototypeOf]]
名前付きプロパティオブジェクトOの[[SetPrototypeOf]]内部メソッドがJavaScript値Vで呼び出されたとき、以下の手順を行う:
-
もしOの関連付けられたrealmのグローバルプロトタイプチェーンがmutableなら、 ? OrdinarySetPrototypeOf(O, V)を返す。
-
? SetImmutablePrototype(O, V)を返す。
3.7.4.5. [[PreventExtensions]]
名前付きプロパティオブジェクトの[[PreventExtensions]]内部メソッドが呼び出されたとき、以下の手順を行う:
-
false を返す。
注: これにより[[PreventExtensions]]が失敗することで、名前付きプロパティオブジェクトを拡張可能なままに保つ。
3.7.5. 定数
定数はインターフェイスオブジェクト、
レガシーコールバックインターフェイスオブジェクト、
インターフェイスプロトタイプオブジェクト、
そして[Global
]拡張属性で宣言されたインターフェイスの場合は、
そのインターフェイスを実装する単一のオブジェクト上で公開される。
-
全ての 定数const(definitionのメンバー)について:
-
valueにconstのIDL値をJavaScript値へ変換したものをセット。
-
descにPropertyDescriptor{[[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false, [[Value]]: value}をセット。
-
idにconstの識別子をセット。
-
! DefinePropertyOrThrow(target, id, desc)を実行。
3.7.6. 属性
静的属性
はインターフェースオブジェクト上に公開されます。
通常の属性はインターフェースプロトタイプオブジェクト上に公開されますが、
属性が偽造不可である場合や
インターフェースが [Global
]
拡張属性で宣言された場合には、
それらはそのインターフェースを実装するすべてのオブジェクト上に公開されます。
-
attributesから属性であり 偽造不可なものをすべて削除します。
-
attributesのattributesをdefinitionのtarget上にrealmを与えて定義します。
-
attributesのattributesをdefinitionのtarget上にrealmを与えて定義します。
-
attributesのattributesをdefinitionのtarget上にrealmを与えて定義します。
-
attributesの各属性attrについて:
-
getterを、属性ゲッターの生成結果として、attr、definition、realmを与えて取得します。
-
setterを、属性セッターの生成結果として、attr、definition、realmを与えて取得します。
-
もしattrが偽造不可ならconfigurableは
false とし、 そうでなければtrue とします。 -
descをPropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]:
true , [[Configurable]]: configurable}とします。 -
idをattrの識別子とします。
-
! DefinePropertyOrThrow(target, id, desc)を実行します。
-
もしattrの型が型引数Tをもつオブザーバブル配列型なら、 targetのバックエンドオブザーバブル配列エキゾチックオブジェクトを attrのために、オブザーバブル配列エキゾチックオブジェクトの作成アルゴリズムの結果(realm、T、attrのインデックス付き値の設定アルゴリズム、attrのインデックス付き値の削除アルゴリズム)で設定します。
属性ゲッターは、以下のようにして生成されます。与えられるのは 属性 attribute、名前空間またはインターフェースtarget、realmrealmです:
-
stepsを以下の一連のステップとします:
-
以下のステップを試行します:
-
idlObjectをnullとします。
-
もしtargetがインターフェースであり、attributeが 通常の属性なら:
-
jsValueを
this の値(null またはundefined でなければ)、そうでなければrealmの グローバルオブジェクトとします。 (この場合、グローバルオブジェクトがtargetを実装せず、かつ[LegacyLenientThis
]が指定されていない場合は、 後のステップでTypeError
が発生します。) -
もしjsValueがプラットフォームオブジェクトなら、 セキュリティチェックを実行します。 引数はjsValue、attributeの識別子、および"getter"です。
-
もしjsValueがtargetを実装しない場合:
-
もしattributeが[
LegacyLenientThis
] 拡張属性で指定されていれば、undefined を返します。
-
-
もしattributeの型がオブザーバブル配列型なら、 jsValueのattributeに対する バックエンドオブザーバブル配列エキゾチックオブジェクトを返します。
-
idlObjectに、jsValueへの参照を表すIDLインターフェース型値を設定します。
-
-
RをIDL値からJavaScript値への変換により attributeの宣言型としてJavaScript値に変換した結果を返します。
-
そして、例外Eがスローされた場合:
-
もしattributeの型がPromise型なら、 ! Call(
%Promise.reject%
,%Promise%
, «E»)を返します。 -
それ以外の場合は、これらのステップを終了し、例外を伝播させます。
-
-
FをCreateBuiltinFunction(steps, « », realm)とします。
-
nameを文字列"
get
"をattributeの識別子の前につけたものとします。 -
SetFunctionName(F, name)を実行します。
-
SetFunctionLength(F, 0)を実行します。
-
Fを返します。
属性セッターは、以下のようにして生成されます。与えられるのは 属性 attribute、名前空間またはインターフェースtarget、realmrealmです:
-
もしtargetが名前空間なら:
-
アサート: attributeは読み取り専用です。
-
undefined を返します。
-
-
もしattributeが読み取り専用であり、 [
LegacyLenientSetter
]、 [PutForwards
]、 または[Replaceable
] 拡張属性を持たなければ、undefined を返します。 属性セッター関数はありません。 -
アサート: attributeの型はPromise型ではありません。
-
stepsを以下の一連のステップとします:
-
Vを
undefined とします。 -
引数が渡されていれば、最初の引数の値をVに設定します。
-
idをattributeの識別子とします。
-
idlObjectをnullとします。
-
もしattributeが通常の属性なら:
-
jsValueを
this の値(nullやundefinedでなければ)、そうでなければrealmの グローバルオブジェクトとします。 (この場合、グローバルオブジェクトがtargetを実装せず、かつ[LegacyLenientThis
]が指定されていない場合は、 後のステップでTypeError
が発生します。) -
もしjsValueがプラットフォームオブジェクトなら、 セキュリティチェックを jsValue、id、"setter"で実行します。
-
validThisを、jsValueがtargetを実装していればtrue、そうでなければfalseとします。
-
もしvalidThisがfalseで、かつattributeが [
LegacyLenientThis
] 拡張属性で指定されていなければ、 throwし、TypeError
を投げます。 -
もしattributeが[
Replaceable
] 拡張属性で宣言されていれば:-
? CreateDataPropertyOrThrow(jsValue, id, V)を実行します。
-
undefined を返します。
-
-
もしvalidThisがfalseなら、
undefined を返します。 -
もしattributeが[
LegacyLenientSetter
] 拡張属性で宣言されていれば、undefined を返します。 -
もしattributeが[
PutForwards
] 拡張属性で宣言されていれば:-
もしQがオブジェクトでなければ、 throwし、
TypeError
を投げます。 -
forwardIdを[
PutForwards
] 拡張属性の識別子引数とします。 -
undefined を返します。
-
idlObjectに、jsValueへの参照を表すIDLインターフェース型値を設定します。
-
もしattributeの型が型引数Tをもつオブザーバブル配列型なら:
-
newValuesをECMAScript値からIDL値への変換で Vを型sequence<T>として変換した結果とします。
-
oaをidlObjectのattributeに対するバックエンドオブザーバブル配列エキゾチックオブジェクトとします。
-
長さを設定し、 oa.[[ProxyHandler]]の長さを0にします。
-
iを0とします。
-
i < newValuesのサイズの間、繰り返します:
-
oa.[[ProxyHandler]].[[SetAlgorithm]]のアルゴリズムステップを newValues[i]とiを与えて実行します。
-
Append newValues[i]を oa.[[ProxyHandler]].[[BackingList]]に追加します。
-
-
undefined を返します。
-
-
-
idlValueを以下のように決定します:
- attributeの型が列挙型の場合
- その他の場合
- idlValueをECMAScript値からIDL値への変換で Vをattributeの型として変換した結果とします。
-
setter手順をattributeに対して、 idlObjectをthisとして、 idlValueを与えられた値として実行します。
-
undefined を返します。
-
-
FをCreateBuiltinFunction(steps, « », realm)とします。
-
nameを文字列"
set
"をidの前につけたものとします。 -
SetFunctionName(F, name)を実行します。
-
SetFunctionLength(F, 1)を実行します。
-
Fを返します。
注: IDL属性にはプロパティは一つしかありませんが、 アクセサプロパティのgetter/setterは、プロパティに対応するIDL属性がアクセスされるオブジェクトのthis値を渡されるため、インスタンス固有のデータを公開できます。
注: 読み取り専用の属性に対応するプロパティに代入しようとすると、
そのスクリプトがstrict modeかどうかで挙動が異なります。
strict modeの場合はTypeError
がスローされ、
そうでない場合は代入は無視されます。
3.7.7. 操作
各 identifier が一意となる
exposed な operation が interface 上に定義されている場合、
対応するプロパティが存在する。
Static
operation
は interface
object 上に公開される。
Regular
operation は
interface prototype object 上に公開されるが、
operation が unforgeable
である場合や interface が [Global
] extended
attribute で宣言されている場合には、
その interface を implements
する各オブジェクト上に公開される。
-
operations を、list のうち、 regular operation で members であるものとして definition から取得する。
-
Remove を用いて、operations から operation のうち unforgeable なものを除去する。
-
Define the operations operations を、definition および target に対し、realm を用いて定義する。
-
operations を、list のうち、 static operation で members であるものとして definition から取得する。
-
Define the operations operations を、definition および target に対し、realm を用いて定義する。
-
operations を、list のうち、 unforgeable な regular operation で members であるものとして definition から取得する。
-
Define the operations operations を、definition および target に対し、realm を用いて定義する。
-
For each operation op を operations の要素として:
-
method を create an operation function を op、definition、realm に対して実行した結果とする。
-
もし op が unforgeable であれば modifiable を
false 、 それ以外ならtrue とする。 -
desc を PropertyDescriptor{[[Value]]: method, [[Writable]]: modifiable, [[Enumerable]]:
true , [[Configurable]]: modifiable} とする。 -
id を op の identifier とする。
-
! DefinePropertyOrThrow(target, id, desc) を実行する。
-
id を op の identifier とする。
-
steps を、関数引数値 args を与えたときに実行する以下の手順とする:
-
以下を試みる:
-
idlObject を null とする。
-
もし target が interface であり、かつ op が static operation でなければ:
-
jsValue を
this の値(null または undefined でなければ)、 そうでなければ realm の global object とする。 (この場合、global object が target を implements せず、 [LegacyLenientThis
] が指定されていなければ、後続のステップでTypeError
が発生する。) -
もし jsValue が platform object であれば、 perform a security check を jsValue、id、"method" を渡して実行する。
-
もし jsValue が interface target を implements していなければ、 throw により
TypeError
を投げる。 -
idlObject を interface type の IDL 値で jsValue を参照するものに設定する。
-
-
n を size of args とする。
-
Compute the effective overload set を regular operation(op が regular の場合)または static operation(op が static の場合)に対して、 identifier id、target、引数数 n を渡して計算し、 結果を S とする。
-
<operation, values> を、S と args を overload resolution algorithm に渡した結果とする。
-
R を
null とする。 -
もし operation が [
Default
] extended attribute で宣言されているなら:-
Assert: operation が has default method steps を持つことを保証する。
-
R を default method steps を operation、idlObject(this)、values(引数値)を渡して実行した結果に設定する。
-
-
それ以外の場合は、R を method steps を operation、idlObject(this)、values(引数値)で実行した結果に設定する。
-
R を IDL から JavaScript 値への変換 を行った値として返す。
R は op が宣言する型の IDL 値であることが想定されている。[whatwg/webidl Issue #674]
-
そして、例外 E が投げられた場合:
-
もし op の return type が promise type であれば、 ! Call(
%Promise.reject%
,%Promise%
, «E») を返す。 -
それ以外の場合は、これらの手順を終了し、例外を伝播させる。
-
-
F を CreateBuiltinFunction(steps, « », realm) の結果とする。
-
SetFunctionName(F, id) を実行する。
-
Compute the effective overload set を regular operation(op が regular の場合)または static operation(op が static の場合)に対して、 identifier id、target、引数数 0 を渡して計算し、結果を S とする。
-
length を S の各エントリの中で最も短い引数リストの長さとする。
-
SetFunctionLength(F, length) を実行する。
-
F を返す。
3.7.7.1. デフォルト操作
通常の操作 デフォルトメソッド手順を持つ とは、その 識別子 が下記の表の第一列に現れる場合を指す。 この場合、その デフォルトメソッド手順 は表の第二列に示されたアルゴリズムによって与えられ、操作は表の第三列で示された返却型を持たなければならない。
識別子 | デフォルトメソッド手順 | 返却型 |
---|---|---|
"toJSON "
|
デフォルト toJSON 手順 | object
|
通常の操作 が デフォルトメソッド手順を持たない 場合、[Default
] 拡張属性
で宣言してはならない。
3.7.7.1.1. デフォルト toJSON 操作
デフォルト toJSON 手順は、インターフェース I に対して次の通り実行する:
-
map を新しい 順序付きマップ とする。
-
stack を 継承スタックを作成する で インターフェース I を渡して得る。
-
継承スタックの属性値を収集するを、 this, stack, map を渡して呼び出す。
-
result を OrdinaryObjectCreate(
%Object.prototype%
) の結果とする。 -
map の各 key → value について、
-
k を key IDL から JavaScript への値変換の結果とする。
-
v を value IDL から JavaScript への値変換の結果とする。
-
! CreateDataPropertyOrThrow(result, k, v) を実行する。
-
-
result を返す。
継承スタックの属性値を収集するは プラットフォームオブジェクト object, スタック stack, 順序付きマップ map を与えて実行する:
-
I を stack から pop する結果とする。
-
属性値を収集する を object, I, map で呼び出す。
-
もし stack が 空でなければ、 継承スタックの属性値を収集するを object, stack, map で呼び出す。
属性値を収集するは プラットフォームオブジェクト object, インターフェース I, 順序付きマップ map を与えて実行する:
継承スタックを作成するは インターフェース I に対して以下を実行する:
-
stack を新しい スタックとする。
-
stack に push するで I を stack に追加する。
-
-
I をその インターフェースとする。
-
stack に push するで I を stack に追加する。
-
-
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 を持つ場合、 以下の特性を持つプロパティが存在しなければならない:
-
プロパティ名は "
toString
" である。 -
もし stringifier が unforgeable であるか インターフェースが [
Global
] 拡張属性 で宣言されている場合は、 そのインターフェースを implements する各オブジェクト上にプロパティが存在する。 それ以外の場合は、インターフェースプロトタイプオブジェクト上に存在する。 -
プロパティの属性は { [[Writable]]: B, [[Enumerable]]:
true , [[Configurable]]: B } であり、B は stringifier がインターフェース上で unforgeable ならfalse 、 それ以外ならtrue である。 -
プロパティ値は 組み込み関数オブジェクトであり、次のように動作する:
-
thisValue を
this の値とする。 -
もし O が プラットフォームオブジェクトであれば、 セキュリティチェックを実施する(以下を渡す):
-
プラットフォームオブジェクト O
-
型 "
method
"
-
-
もし O が stringifier を宣言した インターフェース を implements していなければ、TypeError を投げる。
-
V を未初期化変数として用意する。
-
stringifier
の指定方法に応じて: -
V を IDL から JavaScript への値変換で String 型に変換した結果を返す。
-
-
関数オブジェクトの
length
プロパティ値は Number 値0 である。 -
関数オブジェクトの
name
プロパティ値は String 値 "toString
" である。
3.7.9. イテラブル宣言
-
もし definition が インデックス付きプロパティgetter を持つ場合:
-
DefineMethodProperty(target,
%Symbol.iterator%
,%Array.prototype.values%
, false) を実行する。 -
もし definition が 値イテレーター を持つ場合:
-
! CreateDataPropertyOrThrow(target, "
entries
",%Array.prototype.entries%
) を実行する。 -
! CreateDataPropertyOrThrow(target, "
keys
",%Array.prototype.keys%
) を実行する。 -
! CreateDataPropertyOrThrow(target, "
values
",%Array.prototype.values%
) を実行する。 -
! CreateDataPropertyOrThrow(target, "
forEach
",%Array.prototype.forEach%
) を実行する。
-
-
-
それ以外の場合、definition が ペアイテレーター を持つ場合:
-
%Symbol.iterator%
とentries
メソッドを定義する:-
steps を次の手順列とする:
-
もし jsValue が プラットフォームオブジェクト であれば、 セキュリティチェックを実施する(jsValue, "
%Symbol.iterator%
", "method
" を渡す) -
もし jsValue が definition を implements していなければ、TypeError を投げる。
-
新しい デフォルトイテレーターオブジェクト を definition 用、jsValue を target、 "
key+value
" を kind、 index は 0 で返す。
-
F を CreateBuiltinFunction(steps, « », realm) の結果とする。
-
SetFunctionName(F, "
entries
") を実行する。 -
SetFunctionLength(F, 0) を実行する。
-
DefineMethodProperty(target,
%Symbol.iterator%
, F, false) を実行する。 -
! CreateDataPropertyOrThrow(target, "
entries
", F) を実行する。
-
-
keys
メソッドを定義する:-
steps を次の手順列とする:
-
もし jsValue が プラットフォームオブジェクト であれば、 セキュリティチェックを実施する(jsValue, "
keys
", "method
" を渡す) -
もし jsValue が definition を implements していなければ、TypeError を投げる。
-
新しい デフォルトイテレーターオブジェクト を definition 用、jsValue を target、 "
key
" を kind、 index は 0 で返す。
-
F を CreateBuiltinFunction(steps, « », realm) の結果とする。
-
SetFunctionName(F, "
keys
") を実行する。 -
SetFunctionLength(F, 0) を実行する。
-
! CreateDataPropertyOrThrow(target, "
keys
", F) を実行する。
-
-
values
メソッドを定義する:-
steps を次の手順列とする:
-
もし jsValue が プラットフォームオブジェクト であれば、 セキュリティチェックを実施する(jsValue, "
values
", "method
" を渡す) -
もし jsValue が definition を implements していなければ、TypeError を投げる。
-
新しい デフォルトイテレーターオブジェクト を definition 用、jsValue を target、 "
value
" を kind、 index は 0 で返す。
-
F を CreateBuiltinFunction(steps, « », realm) の結果とする。
-
SetFunctionName(F, "
values
") を実行する。 -
SetFunctionLength(F, 0) を実行する。
-
! CreateDataPropertyOrThrow(target, "
values
", F) を実行する。
-
-
forEach
メソッドを定義する:-
steps を関数引数値 callback および thisArg を与えて次の手順列とする:
-
もし jsValue が プラットフォームオブジェクト であれば、 セキュリティチェックを実施する(jsValue, "
forEach
", "method
" を渡す) -
もし jsValue が definition を implements していなければ、TypeError を投げる。
-
idlObject を インターフェース型 の IDL 値で jsValue を参照するものに設定する。
-
pairs を idlObject の イテレート対象の値ペアのリストとする。
-
i を 0 とする。
-
While i < pairs の サイズ の間:
-
pair を pairs[i] とする。
-
コールバック関数呼び出し idlCallback に « pair の value, pair の key, idlObject » を渡し、 thisArg を コールバックthis値とする。
-
pairs を idlObject の現在の イテレート対象の値ペアのリストに更新する(変更されている可能性がある)。
-
i を i + 1 にする。
-
-
F を CreateBuiltinFunction(steps, « », realm) の結果とする。
-
SetFunctionName(F, "
forEach
") を実行する。 -
SetFunctionLength(F, 1) を実行する。
-
! CreateDataPropertyOrThrow(target, "
forEach
", F) を実行する。
-
-
3.7.9.1. デフォルトイテレーターオブジェクト
ある インターフェース、target、イテレーションkindに対する デフォルトイテレーターオブジェクト は、 [[Prototype]] 内部スロット が その インターフェース用の イテレータープロトタイプオブジェクト となるオブジェクトである。
デフォルトイテレーターオブジェクト には、以下の3つの内部値がある:
-
target:イテレートする値を持つオブジェクト
-
kind:イテレーションの種類
-
index:イテレートする値の現在のインデックス
注: デフォルトイテレーターオブジェクトは ペアイテレーター のみで使用される。 値イテレーターは、現状オブジェクトの サポートされるインデックス付きプロパティのみをイテレートするため、 標準のJavaScript Arrayイテレーターオブジェクトを利用する。
注: デフォルトイテレーターオブジェクト
は class string を持たない。
インターフェースの
デフォルトイテレーターオブジェクトに対して
Object.prototype.toString()
が呼び出された場合、その イテレータープロトタイプオブジェクト
の
class string が使われる。
3.7.9.2. イテレータープロトタイプオブジェクト
イテレータープロトタイプオブジェクト とは、ある インターフェース に対して ペアイテレーター を持つ全てのインターフェースごとに存在するオブジェクトである。これは、そのインターフェース用の デフォルトイテレーターオブジェクト のプロトタイプとなる。
[[Prototype]] 内部スロット は イテレータープロトタイプオブジェクトについて、
%Iterator.prototype%
でなければならない。
-
result を kind の値に応じて決定する:
- "
key
" -
-
idlKey を pair の key とする。
-
key を IDL から JavaScript 値への変換 で idlKey を変換した結果とする。
-
result は key である。
-
- "
value
" -
-
idlValue を pair の value とする。
-
value を IDL から JavaScript 値への変換 で idlValue を変換した結果とする。
-
result は value である。
-
- "
key+value
" -
-
idlKey を pair の key とする。
-
idlValue を pair の value とする。
-
key を IDL から JavaScript 値への変換 で idlKey を変換した結果とする。
-
value を IDL から JavaScript 値への変換 で idlValue を変換した結果とする。
-
array を ! ArrayCreate(2) の結果とする。
-
! CreateDataPropertyOrThrow(array, "
0
", key) を実行する。 -
! CreateDataPropertyOrThrow(array, "
1
", value) を実行する。 -
result は array である。
-
- "
-
CreateIteratorResultObject(result,
false ) を返す。
イテレータープロトタイプオブジェクトは、属性
{ [[Writable]]: next
データプロパティを持たなければならず、その値は以下のように動作する 組み込み関数オブジェクト である:
-
interface を、イテレータプロトタイプオブジェクトが存在する インターフェイスとする。
-
thisValue を
this の値とする。 -
もし object が プラットフォームオブジェクト であれば、 セキュリティチェックを実施する(以下を渡す):
-
プラットフォームオブジェクト object
-
識別子 "
next
" -
型 "
method
"
-
-
もし object が interface の デフォルトイテレーターオブジェクトでなければ、 TypeError を投げる。
-
index を object の index とする。
-
kind を object の kind とする。
-
values を object の target の イテレート対象の値ペアとする。
-
len を values の長さとする。
-
もし index が len 以上なら、 CreateIteratorResultObject(
undefined ,true ) を返す。 -
pair を values の index 番目のエントリとする。
-
object の index を index + 1 に設定する。
-
イテレーター結果 を pair と kind で返す。
ある インターフェース 用の イテレータープロトタイプオブジェクト の class string は、
その インターフェース の 識別子 と文字列
" Iterator
" を連結したものである。
3.7.10. 非同期イテラブル宣言
-
もし definition がいずれの 非同期イテラブル宣言(どちらの種類でも)も持たなければ、return する。
-
Assert: definition は インデックス付きプロパティgetter や イテラブル宣言 を持たないこと。
-
もし definition が ペア非同期イテラブル宣言 を持つ場合、以下の
%Symbol.asyncIterator%
およびentries
メソッドを定義する:-
steps を次の手順列とし、関数引数値 args を与える:
-
もし jsValue が プラットフォームオブジェクト であれば、セキュリティチェックを実施して jsValue, "
%Symbol.asyncIterator%
", "method
" を渡す。 -
もし jsValue が definition を implements していなければ、TypeError を投げる。
-
idlObject を IDL インターフェース型値で jsValue を参照するものとする。
-
idlArgs を 非同期イテレーターメソッドの引数変換で args を与えた結果とする。
-
iterator を新しく作成した デフォルト非同期イテレーターオブジェクト( definition 用、idlObject を target、 "
key+value
" を kind、 is finished は false)とする。 -
もし存在すれば、非同期イテレーター初期化手順を definition、idlObject、iterator、idlArgs で実行する。
-
iterator を返す。
-
F を CreateBuiltinFunction(steps, « », realm) の結果とする。
-
SetFunctionName(F, "
entries
") を実行する。 -
SetFunctionLength(F, 0) を実行する。
-
DefineMethodProperty(target,
%Symbol.asyncIterator%
, F, false) を実行する。 -
! CreateDataPropertyOrThrow(target, "
entries
", F) を実行する。
-
-
もし definition が ペア非同期イテラブル宣言を持つ場合、
keys
メソッドを定義する:-
steps を次の手順列とし、関数引数値 args を与える:
-
もし jsValue が プラットフォームオブジェクト であれば、セキュリティチェックを実施して jsValue, "
keys
", "method
" を渡す。 -
もし jsValue が definition を implements していなければ、TypeError を投げる。
-
idlObject を IDL インターフェース型値で jsValue を参照するものとする。
-
idlArgs を 非同期イテレーターメソッドの引数変換で args を与えた結果とする。
-
iterator を新しく作成した デフォルト非同期イテレーターオブジェクト( definition 用、idlObject を target、 "
key
" を kind、 is finished は false)とする。 -
もし存在すれば、非同期イテレーター初期化手順を definition、idlObject、iterator、idlArgs で実行する。
-
iterator を返す。
-
F を CreateBuiltinFunction(steps, « », realm) の結果とする。
-
SetFunctionName(F, "
keys
") を実行する。 -
SetFunctionLength(F, 0) を実行する。
-
! CreateDataPropertyOrThrow(target, "
keys
", F) を実行する。
-
-
values
、および必要に応じて%Symbol.asyncIterator%
メソッドを定義する:-
steps を次の手順列とし、関数引数値 args を与える:
-
もし jsValue が プラットフォームオブジェクト であれば、セキュリティチェックを実施して jsValue, "
values
", "method
" を渡す。 -
もし jsValue が definition を implements していなければ、TypeError を投げる。
-
idlObject を IDL インターフェース型値で jsValue を参照するものとする。
-
idlArgs を 非同期イテレーターメソッドの引数変換で args を与えた結果とする。
-
iterator を新しく作成した デフォルト非同期イテレーターオブジェクト( definition 用、idlObject を target、 "
value
" を kind、 is finished は false)とする。 -
もし存在すれば、非同期イテレーター初期化手順を definition、idlObject、iterator、idlArgs で実行する。
-
iterator を返す。
-
F を CreateBuiltinFunction(steps, « », realm) の結果とする。
-
SetFunctionName(F, "
values
") を実行する。 -
SetFunctionLength(F, 0) を実行する。
-
! CreateDataPropertyOrThrow(target, "
values
", F) を実行する。 -
もし definition が 値非同期イテラブル宣言 を持つ場合、! DefineMethodProperty(target,
%Symbol.asyncIterator%
, F, false) を実行する。
-
-
idlArgs を空のリストとする。
-
argCount を definition の 非同期イテラブル宣言 の引数数(もしくは引数リストがなければ0)とする。
-
i を 0 とする。
-
While i < argCount の間:
-
もし i ≥ args の サイズ もしくは args[i] が
undefined なら:-
もし 非同期イテラブル宣言 のその引数(インデックス i)が デフォルト値で宣言されていれば、 そのデフォルト値を idlArgs に追加する。
-
それ以外の場合、idlArgs に特殊値 "missing" を追加する。
-
-
それ以外の場合、idlArgs に追加する値は ECMAScript値からIDL型変換で args[i] を 非同期イテラブル宣言の引数リスト(インデックスi)の型に変換した値とする。
-
i を i + 1 にする。
-
-
idlArgs を返す。
これは、全ての引数がオプションでありオーバーロードが許可されない場合の オーバーロード解決アルゴリズム の特殊ケースである。
3.7.10.1. デフォルト非同期イテレーターオブジェクト
ある インターフェース、target、イテレーションkindに対する デフォルト非同期イテレーターオブジェクト は、 [[Prototype]] 内部スロット が その インターフェース用の 非同期イテレータープロトタイプオブジェクト となるオブジェクトである。
デフォルト非同期イテレーターオブジェクト には、以下の内部値がある:
-
target:イテレートする値を持つオブジェクト
-
kind:イテレーションの種類
-
ongoing promise:
Promise
または null -
is finished:真偽値(boolean)
注: デフォルト非同期イテレーターオブジェクト は
class string を持たない。
インターフェースの
デフォルト非同期イテレーターオブジェクトに対して
Object.prototype.toString()
が呼び出された場合、その 非同期イテレータープロトタイプオブジェクト の
class string が使われる。
3.7.10.2. 非同期イテレータープロトタイプオブジェクト
非同期イテレータープロトタイプオブジェクト とは、ある インターフェース に対して 非同期イテラブル宣言 を持つ全てのインターフェースごとに存在するオブジェクトである。 これは、そのインターフェース用の デフォルト非同期イテレーターオブジェクト のプロトタイプとなる。
[[Prototype]] 内部スロット は 非同期イテレータープロトタイプオブジェクトについて、
%AsyncIteratorPrototype%
でなければならない。
非同期イテレータープロトタイプオブジェクト は、
属性 { [[Writable]]: next
データプロパティを持たなければならず、その値は以下のように動作する 組み込み関数オブジェクト である:
-
interface を、非同期イテレータプロトタイプオブジェクトが存在する インターフェイスとする。
-
thisValidationPromiseCapability を ! NewPromiseCapability(
%Promise%
) とする。 -
thisValue を
this の値とする。 -
object を Completion(ToObject(thisValue)) とする。
-
IfAbruptRejectPromise(object, thisValidationPromiseCapability) を実行する。
-
もし object が プラットフォームオブジェクト であれば、セキュリティチェックを実施(以下を渡す):
-
プラットフォームオブジェクト object
-
識別子 "
next
" -
型 "
method
"
このとき例外 e が投げられた場合:
-
-
もし object が interface の デフォルト非同期イテレーターオブジェクトでなければ:
-
nextSteps を次の手順列とする:
-
nextPromiseCapability を ! NewPromiseCapability(
%Promise%
) とする。 -
もし object の is finished が true なら:
-
result を CreateIteratorResultObject(
undefined ,true ) とする。 -
! Call(nextPromiseCapability.[[Resolve]],
undefined , « result ») を実行する。 -
nextPromiseCapability.[[Promise]] を返す。
-
-
kind を object の kind とする。
-
nextPromise を 次のイテレーション結果を取得で object の target および object を与えた結果とする。
-
fulfillSteps を次の手順列(nextを与える)とする:
-
object の ongoing promise を null に設定する。
-
もし next が イテレーション終了 なら:
-
object の is finished を true に設定する。
-
CreateIteratorResultObject(
undefined ,true ) を返す。
-
-
それ以外の場合、もし interface が ペア非同期イテラブル宣言 を持つ場合:
-
それ以外の場合:
-
Assert: interface は 値非同期イテラブル宣言 を持つ。
-
Assert: next は宣言で示された型の値である。
-
value を next を IDL から JavaScript値変換した結果とする。
-
CreateIteratorResultObject(value,
false ) を返す。
-
-
-
onFulfilled を CreateBuiltinFunction(fulfillSteps, « ») の結果とする。
-
rejectSteps を次の手順列(reasonを与える)とする:
-
object の ongoing promise を null に設定する。
-
object の is finished を true に設定する。
-
例外を投げる reason を投げる。
-
-
onRejected を CreateBuiltinFunction(rejectSteps, « ») の結果とする。
-
PerformPromiseThen(nextPromise, onFulfilled, onRejected, nextPromiseCapability) を実行する。
-
nextPromiseCapability.[[Promise]] を返す。
-
-
ongoingPromise を object の ongoing promiseとする。
-
もし ongoingPromise が null でなければ:
-
afterOngoingPromiseCapability を ! NewPromiseCapability(
%Promise%
) とする。 -
onSettled を CreateBuiltinFunction(nextSteps, « ») の結果とする。
-
PerformPromiseThen(ongoingPromise, onSettled, onSettled, afterOngoingPromiseCapability) を実行する。
-
object の ongoing promise を afterOngoingPromiseCapability.[[Promise]] に設定する。
-
-
それ以外の場合:
-
object の ongoing promise を nextSteps の実行結果に設定する。
-
-
object の ongoing promise を返す。
もし 非同期イテレーター return アルゴリズムが インターフェース に定義されていれば、
非同期イテレータープロトタイプオブジェクト は
属性 { [[Writable]]: return
データプロパティを持ち、その値は引数valueを受け取り以下のように動作する 組み込み関数オブジェクト である:
-
interface を、非同期イテレータプロトタイプオブジェクトが存在する インターフェイスとする。
-
returnPromiseCapability を NewPromiseCapability(
%Promise%
) の ! により得る。 -
thisValue を
this の値とする。 -
object を ToObject(thisValue) の Completion により得る。
-
IfAbruptRejectPromise(object, returnPromiseCapability) を行う。
-
もし object が プラットフォームオブジェクトであれば、 以下を引数として セキュリティチェックを実行する:
-
プラットフォームオブジェクト object
-
識別子 "
return
" -
型 "
method
"
これにより例外 e が投げられた場合:
-
-
もし object が interface 用の default asynchronous iterator object でなければ、次を行う:
-
returnSteps を以下の手順とする:
-
returnPromiseCapability を NewPromiseCapability(
%Promise%
) の ! により得る。 -
もし object の is finished が true なら、次を行う:
-
result を CreateIteratorResultObject(value,
true ) により得る。 -
Call(returnPromiseCapability.[[Resolve]],
undefined , « result ») を ! で実行する。 -
returnPromiseCapability.[[Promise]] を返す。
-
-
object の is finished を true に設定する。
-
interface 用の 非同期イテレータ return アルゴリズム を、 object の target、object、 そして value を与えて実行した結果を返す。
-
-
ongoingPromise を object の ongoing promise とする。
-
もし ongoingPromise が null でなければ、次を行う:
-
afterOngoingPromiseCapability を NewPromiseCapability(
%Promise%
) の ! により得る。 -
onSettled を CreateBuiltinFunction(returnSteps, « ») により得る。
-
PerformPromiseThen(ongoingPromise, onSettled, onSettled, afterOngoingPromiseCapability) を実行する。
-
object の ongoing promise を afterOngoingPromiseCapability.[[Promise]] に設定する。
-
-
それ以外の場合:
-
object の ongoing promise を returnSteps の実行結果に設定する。
-
-
fulfillSteps を以下の手順とする:
-
CreateIteratorResultObject(value,
true ) を返す。
-
-
onFulfilled を CreateBuiltinFunction(fulfillSteps, « ») により得る。
-
PerformPromiseThen(object の ongoing promise, onFulfilled,
undefined , returnPromiseCapability) を実行する。 -
returnPromiseCapability.[[Promise]] を返す。
ある インターフェース 用の 非同期イテレータープロトタイプオブジェクト の class string は、
その インターフェース の 識別子 と文字列
" AsyncIterator
" を連結したものである。
3.7.11. マップライク宣言
ある インターフェース A が maplike宣言 で宣言されている場合、 A の インターフェースプロトタイプオブジェクト にいくつかの追加プロパティが存在する。 これらの追加プロパティについては、以下のサブセクションで説明する。
3.7.11.1. size
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ size
プロパティが存在しなければならない:
-
このプロパティは { [[Get]]: G, [[Enumerable]]:
true , [[Configurable]]:true } という属性を持ち、G はインターフェースの map size getter(定義は下記)である。 -
map size getter は 以下のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "size
"、型 "getter
" で 実装チェック を行う。 -
map を、O を参照するIDL値の map entries とする。
-
map の サイズ を JavaScript値へ変換して返す。
関数オブジェクトの
length
プロパティ値は Number値0 である。関数オブジェクトの
name
プロパティ値は 文字列 "get size
" である。 -
3.7.11.2. %Symbol.iterator%
A の インターフェースプロトタイプオブジェクト 上に
%Symbol.iterator%
という名前のデータプロパティが属性 { [[Writable]]: entries
プロパティの値である 関数オブジェクト である。
key+value
"、"key
"、"value
"のいずれか)を与えて:
-
closure を、 map と kind をキャプチャして、呼び出された際に以下の手順を実行する パラメータ無しの Abstract Closureとして新規作成する:
-
map の全て key → value について:
-
key、value をそれぞれ JavaScript値へ変換する。
-
もし kind が "
key
" なら、result を key とする。 -
それ以外で kind が "
value
" なら、result を value とする。 -
それ以外の場合、result を CreateArrayFromList(« key, value ») とする。
-
? GeneratorYield(CreateIteratorResultObject(result,
false )) を実行する。
注: map の サイズやエントリの順序は、 Yield によりこの抽象操作の実行が一時停止された間に変更されている可能性がある。
-
-
undefined を返す。
-
-
CreateIteratorFromClosure(closure, "
%MapIteratorPrototype%
",%MapIteratorPrototype%
) を返す。
3.7.11.3. entries
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ entries
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "entries
"、型 "method
" で 実装チェック を行う。 -
map を O を参照するIDL値の map entries とする。
-
map から マップイテレーターの生成 を kind "
key+value
" で行い、その結果を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "entries
" である。
3.7.11.4. keys
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ keys
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "keys
"、型 "method
" で 実装チェック を行う。 -
map を O を参照するIDL値の map entries とする。
-
map から マップイテレーターの生成 を kind "
key
" で行い、その結果を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "keys
" である。
3.7.11.5. values
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ values
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "values
"、型 "method
" で 実装チェック を行う。 -
map を O を参照するIDL値の map entries とする。
-
map から マップイテレーターの生成 を kind "
value
" で行い、その結果を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "values
" である。
3.7.11.6. forEach
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ forEach
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "forEach
"、型 "method
" で 実装チェック を行う。 -
map を O を参照するIDL値の map entries とする。
-
callbackFn を関数に渡された第1引数(未指定なら
undefined )とする。 -
もし IsCallable(callbackFn) が
false なら、TypeError を投げる。 -
thisArg を関数に渡された第2引数(未指定なら
undefined )とする。 -
map の全て key → value について:
-
jsKey、jsValue を key、value を JavaScript値へ変換したものとする。
-
-
undefined を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "forEach
" である。
3.7.11.7. get
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ get
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "get
"、型 "method
" で 実装チェック を行う。 -
map を O を参照するIDL値の map entries とする。
-
keyType を maplike宣言 で指定されたキー型とする。
-
keyArg をこの関数に渡された第1引数(未指定なら
undefined )とする。 -
key を keyArg を keyType 型の IDL値に変換したものとする。
-
もし key が -0 なら、key を +0 に設定する。
-
もし map[key] が 存在する場合、 map[key] を JavaScript値へ変換して返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "get
" である。
3.7.11.8. has
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ has
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "has
"、型 "method
" で 実装チェック を行う。 -
map を O を参照するIDL値の map entries とする。
-
keyType を maplike宣言 で指定されたキー型とする。
-
keyArg をこの関数に渡された第1引数(未指定なら
undefined )とする。 -
key を keyArg を keyType 型の IDL値に変換したものとする。
-
もし key が -0 なら、key を +0 に設定する。
-
もし map[key] が 存在する場合は
true を返し、 そうでなければfalse を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "has
" である。
3.7.11.9. set
もし A が識別子 "set
" を持つ member を宣言していない場合で、
A がread–writeのmaplike宣言で宣言されている場合は、
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ set
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "set
"、型 "method
" で 実装チェック を行う。 -
map を O を参照するIDL値の map entries とする。
-
keyType を maplike宣言 で指定されたキー型、 valueType を値型とする。
-
keyArg をこの関数に渡された第1引数(未指定なら
undefined )とする。 -
key を keyArg を keyType 型の IDL値に変換したものとする。
-
もし key が -0 なら、key を +0 に設定する。
-
valueArg をこの関数に渡された第2引数(未指定なら
undefined )とする。 -
value を valueArg を valueType 型の IDL値に変換したものとする。
-
map に key をキー、value を値として設定する。
-
O を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "set
" である。
もしインターフェースが set
メソッドを宣言している場合も、同様に -0 キーを +0 にマッピングし、
this を返さなければならない。
3.7.11.10. delete
もし A が識別子 "delete
" を持つ member を宣言していない場合で、
A がread–writeのmaplike宣言で宣言されている場合は、
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ delete
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "delete
"、型 "method
" で 実装チェック を行う。 -
map を O を参照するIDL値の map entries とする。
-
keyType を maplike宣言 で指定されたキー型とする。
-
keyArg をこの関数に渡された第1引数(未指定なら
undefined )とする。 -
key を keyArg を keyType 型の IDL値に変換したものとする。
-
もし key が -0 なら、key を +0 に設定する。
-
retVal を map[key] が存在すれば
true 、そうでなければfalse とする。 -
map から key を削除する。
-
retVal を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "delete
" である。
もしインターフェースが delete
メソッドを宣言している場合も、同様に -0 キーを +0 にマッピングし、
キーが存在したかどうかを示す boolean
を返さなければならない。
3.7.11.11. clear
もし A が識別子 "clear
" を持つ member を宣言していない場合で、
A がread–writeのmaplike宣言で宣言されている場合は、
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ clear
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "clear
"、型 "method
" で 実装チェック を行う。 -
map を O を参照するIDL値の map entries とする。
-
map をクリアする。
注: map オブジェクト自体は保持される。なぜなら、現在一時停止中のイテレーターなどがそれを参照している可能性があるため。
-
undefined を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "clear
" である。
もしインターフェースが clear
メソッドを宣言している場合も、map entries オブジェクトは(新しく生成せず)保持し、
undefined
を返さなければならない。
3.7.12. setlike宣言
ある インターフェース A が setlike宣言 で宣言されている場合、 A の インターフェースプロトタイプオブジェクト にいくつかの追加プロパティが存在する。 これらの追加プロパティについては、以下のサブセクションで説明する。
3.7.12.1. size
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ size
プロパティが存在しなければならない:
-
このプロパティは属性 { [[Get]]: G, [[Enumerable]]:
true , [[Configurable]]:true } を持ち、G はインターフェースの set size getter(定義は下記)である。 -
set size getter は 以下のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "size
"、型 "getter
" で 実装チェック を行う。 -
set を、O を参照するIDL値の set entries とする。
-
set の サイズ を JavaScript値へ変換して返す。
関数オブジェクトの
length
プロパティ値は Number値0 である。関数オブジェクトの
name
プロパティ値は 文字列 "get size
" である。 -
3.7.12.2. %Symbol.iterator%
A の インターフェースプロトタイプオブジェクト 上に
%Symbol.iterator%
という名前のデータプロパティが属性 { [[Writable]]: values
プロパティの値である 関数オブジェクト である。
key+value
"、"value
"のいずれか)を与えて:
-
closure を、 set と kind をキャプチャして、呼び出された際に以下の手順を実行する パラメータ無しの Abstract Closureとして新規作成する:
-
set の全て entry について:
-
entry を JavaScript値へ変換する。
-
もし kind が "
value
" なら、result を entry とする。 -
それ以外の場合、result を CreateArrayFromList(« entry, entry ») とする。
-
? GeneratorYield(CreateIteratorResultObject(result,
false )) を実行する。
注: set の サイズやエントリの順序は、 Yield によりこの抽象操作の実行が一時停止された間に変更されている可能性がある。
-
-
undefined を返す。
-
-
CreateIteratorFromClosure(closure, "
%SetIteratorPrototype%
",%SetIteratorPrototype%
) を返す。
3.7.12.3. entries
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ entries
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "entries
"、型 "method
" で 実装チェック を行う。 -
set を O を参照するIDL値の set entries とする。
-
set から セットイテレーターの生成 を kind "
key+value
" で行い、その結果を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "entries
" である。
3.7.12.4. keys
A の インターフェースプロトタイプオブジェクト 上に
属性 { [[Writable]]: keys
データプロパティが存在しなければならず、その値は values
プロパティの値である 関数オブジェクト である。
3.7.12.5. values
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ values
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "values
"、型 "method
" で 実装チェック を行う。 -
set を O を参照するIDL値の set entries とする。
-
set から セットイテレーターの生成 を kind "
value
" で行い、その結果を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "values
" である。
3.7.12.6. forEach
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ forEach
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "forEach
"、型 "method
" で 実装チェック を行う。 -
set を O を参照するIDL値の set entries とする。
-
callbackFn を関数に渡された第1引数(未指定なら
undefined )とする。 -
もし IsCallable(callbackFn) が
false なら、TypeError を投げる。 -
thisArg を関数に渡された第2引数(未指定なら
undefined )とする。 -
set の全て value について:
-
jsValue を value を JavaScript値へ変換したものとする。
-
-
undefined を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "forEach
" である。
3.7.12.7. has
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ has
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "has
"、型 "method
" で 実装チェック を行う。 -
set を O を参照するIDL値の set entries とする。
-
valueType を setlike宣言 で指定された値型とする。
-
valueArg をこの関数に渡された第1引数(未指定なら
undefined )とする。 -
value を valueArg を valueType 型の IDL値に変換したものとする。
-
もし value が -0 なら、value を +0 に設定する。
-
もし set が value を含む場合は
true を返し、 そうでなければfalse を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "has
" である。
3.7.12.8. add
もし A が識別子 "add
" を持つ member を宣言していない場合で、
A がread–writeのsetlike宣言で宣言されている場合は、
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ add
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "add
"、型 "method
" で 実装チェック を行う。 -
set を O を参照するIDL値の set entries とする。
-
valueType を setlike宣言 で指定された値型とする。
-
valueArg をこの関数に渡された第1引数(未指定なら
undefined )とする。 -
value を valueArg を valueType 型の IDL値に変換したものとする。
-
もし value が -0 なら、value を +0 に設定する。
-
set に value を追加する。
-
O を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "add
" である。
もしインターフェースが add
メソッドを宣言している場合も、同様に -0 値を +0 にマッピングし、
設定された値を返さなければならない。
3.7.12.9. delete
もし A が識別子 "delete
" を持つ member を宣言していない場合で、
A がread–writeのsetlike宣言で宣言されている場合は、
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ delete
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "delete
"、型 "method
" で 実装チェック を行う。 -
set を O を参照するIDL値の set entries とする。
-
valueType を setlike宣言 で指定された値型とする。
-
valueArg をこの関数に渡された第1引数(未指定なら
undefined )とする。 -
value を valueArg を valueType 型の IDL値に変換したものとする。
-
もし value が -0 なら、value を +0 に設定する。
-
retVal を set が value を含む場合は
true 、そうでなければfalse とする。 -
set から value を削除する。
-
retVal を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "delete
" である。
もしインターフェースが delete
メソッドを宣言している場合も、同様に -0 値を +0 にマッピングし、
値が存在したかどうかを示す boolean
を返さなければならない。
3.7.12.10. clear
もし A が識別子 "clear
" を持つ member を宣言していない場合で、
A がread–writeのsetlike宣言で宣言されている場合は、
A の インターフェースプロトタイプオブジェクト 上に
以下の特徴を持つ clear
データプロパティが存在しなければならない:
-
このプロパティは属性 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true } を持つ。 -
このプロパティの値は、呼び出されたときに次のように動作する 組み込み関数オブジェクト である:
-
O を
this の値とし、 A に対して識別子 "clear
"、型 "method
" で 実装チェック を行う。 -
set を O を参照するIDL値の set entries とする。
-
set を空にする。
注: set オブジェクト自体は保持される。なぜなら、現在一時停止中のイテレーターなどがそれを参照している可能性があるため。
-
undefined を返す。
-
関数オブジェクトの length
プロパティ値は
Number値
関数オブジェクトの name
プロパティ値は
文字列 "clear
" である。
もしインターフェースが clear
メソッドを宣言している場合も、set entries オブジェクトは(新しく生成せず)保持し、
undefined
を返さなければならない。
3.8. インターフェースを実装するプラットフォームオブジェクト
仕様書では、「object implements interface」という概念を、「object が interfaceオブジェクトである」など様々な形で参照されることがある。
全ての プラットフォームオブジェクトは、 realm と関連付けられている。これは 初期オブジェクトと同様である。 このrealmは プラットフォームオブジェクトの [[Realm]] スロットに格納される。 Web IDLを利用する仕様は、各プラットフォームオブジェクトがどのrealm(または間接的にどのグローバルオブジェクト)と関連付けられるのかを明示する責任がある。 特に、以下のアルゴリズムは新しい プラットフォームオブジェクト を引数で与えられたrealmと関連付ける。
-
インターフェースを内部的に実装する新しいオブジェクトを作成し、 interface、realm、
undefined を与えた結果を返す。
-
Assert: interface は realm で 公開されている。
-
もし newTarget が
undefined なら:-
prototype を realm の interface 用 インターフェースプロトタイプオブジェクトとする。
-
-
それ以外の場合:
-
Assert: IsCallable(newTarget) は true。
-
もし prototype が Objectでない場合:
-
targetRealm を ? GetFunctionRealm(newTarget) とする。
-
prototype を targetRealm の interface 用 インターフェースプロトタイプオブジェクトに設定する。
-
-
-
slots を « [[Prototype]], [[Extensible]], [[Realm]], [[PrimaryInterface]] » とする。
-
もし interface が
DOMException
なら、 [[ErrorData]] を slots に追加する。 -
instance を MakeBasicObject(slots) とする。
-
instance.[[Realm]] を realm に設定する。
-
instance.[[PrimaryInterface]] を interface に設定する。
-
instance.[[Prototype]] を prototype に設定する。
-
interfaces を interface の 包括的な継承インターフェースとする。
-
全ての インターフェース ancestor interface in interfaces について:
-
unforgeables を realm の ancestor interface の インターフェースオブジェクトの [[Unforgeables]] スロット値とする。
-
keys を ! unforgeables.[[OwnPropertyKeys]]() の結果とする。
-
各 key in keys について:
-
descriptor を ! unforgeables.[[GetOwnProperty]](key) の結果とする。
-
! DefinePropertyOrThrow(instance, key, descriptor) を実行する。
-
-
-
もし interface が [
Global
] 拡張属性で宣言されている場合:-
通常の操作を定義するを interface、instance、realm で実行する。
-
通常の属性を定義するを interface、instance、realm で実行する。
-
イテレーションメソッドを定義するを interface、instance、realm で実行する。
-
非同期イテレーションメソッドを定義するを interface、instance、realm で実行する。
-
グローバルプロパティ参照を定義するを instance、realm で実行する。
-
instance.[[SetPrototypeOf]] を § 3.8.1 [[SetPrototypeOf]] の定義に従って設定する。
-
-
それ以外で、interfaces が インターフェースで インデックス付きプロパティや 名前付きプロパティをサポートするものを含む場合:
-
instance.[[GetOwnProperty]] を § 3.9.1 [[GetOwnProperty]] の定義に従って設定する。
-
instance.[[Set]] を § 3.9.2 [[Set]] の定義に従って設定する。
-
instance.[[DefineOwnProperty]] を § 3.9.3 [[DefineOwnProperty]] の定義に従って設定する。
-
instance.[[Delete]] を § 3.9.4 [[Delete]] の定義に従って設定する。
-
instance.[[PreventExtensions]] を § 3.9.5 [[PreventExtensions]] の定義に従って設定する。
-
instance.[[OwnPropertyKeys]] を § 3.9.6 [[OwnPropertyKeys]] の定義に従って設定する。
-
-
instance を返す。
-
もし A と B が interfaces の 要素であり、 A が B を 継承していたら、 A のインデックスは B よりも高くなるよう interfaces をソートする。
-
全ての interfaces の interface について:
-
interface が [
LegacyNoInterfaceObject
] または [LegacyNamespace
] 拡張属性で宣言されていなければ:-
id を interface の 識別子とする。
-
interfaceObject を インターフェースオブジェクトの作成し、interface、id、realmを与えた結果とする。
-
DefineMethodProperty(target, id, interfaceObject, false) を実行する。
-
もし interface が [
LegacyWindowAlias
] 拡張属性 で宣言されていて、 target がWindow
インターフェースを実装している場合:-
全ての [
LegacyWindowAlias
] の 識別子 id について:-
DefineMethodProperty(target, id, interfaceObject, false) を実行する。
-
-
-
-
もし interface が [
LegacyFactoryFunction
] 拡張属性で宣言されている場合:-
全ての [
LegacyFactoryFunction
] の 識別子 id について:-
legacyFactoryFunction を レガシーファクトリ関数の作成で id、interface、realm を与えた結果とする。
-
DefineMethodProperty(target, id, legacyFactoryFunction, false) を実行する。
-
-
-
-
全ての コールバックインターフェース interface で realm で 公開され、かつ 定数が定義されているものについて:
-
id を interface の 識別子とする。
-
interfaceObject を レガシーコールバックインターフェースオブジェクトの作成で interface、id、realm を与えた結果とする。
-
DefineMethodProperty(target, id, interfaceObject, false) を実行する。
-
-
全ての 名前空間 namespace で realm で 公開されているものについて:
-
id を namespace の 識別子とする。
-
namespaceObject を 名前空間オブジェクトの作成で namespace、realm を与えた結果とする。
-
DefineMethodProperty(target, id, namespaceObject, false) を実行する。
-
異なる プラットフォームオブジェクト が 異なる グローバルオブジェクト を持っていても、 [[PrimaryInterface]] 内部スロットには同じ インターフェースへの参照を共有する。例えば、同一オリジンのiframeを含むページで、iframeのメソッドが メインページの同種の要素で呼ばれても例外は投げられない。
インターフェースミクスインは implementsアルゴリズムの評価に直接関与しない。 代わりに、インターフェースミクスインが includeされている各 インターフェースはミクスインの各 member の「コピー」を持ち、 対応する operation functionはレシーバがその インターフェースを includeしていることをチェックする。
ある realm に関連付けられた プラットフォームオブジェクトは、作成後に グローバル環境を変更できる。 プラットフォームオブジェクトに関連付けられている realm が変更された場合、 その [[Prototype]] 内部スロットは 直ちに新しい関連realmの プライマリインターフェースの インターフェースプロトタイプオブジェクトに更新されなければならない。
また、[Global
] 拡張属性を持つ
インターフェースを実装する プラットフォームオブジェクトは、
以下から宣言的にプロパティを取得する:
これらのプロパティは命令的に定義すること。
3.8.1. [[SetPrototypeOf]]
インターフェースが [Global
] 拡張属性を持つ
プラットフォームオブジェクト O の [[SetPrototypeOf]] 内部メソッドが
JavaScript言語値 V で呼び出された場合、以下の手順を実行する:
-
もし O の 関連realm の グローバルプロトタイプチェーンがmutableか が true なら、 ? OrdinarySetPrototypeOf(O, V) を返す。
-
? 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 で呼び出された場合、以下のように動作しなければならない:
-
? LegacyPlatformObjectGetOwnProperty(O, P,
false ) を返す。
3.9.2. [[Set]]
全ての レガシープラットフォームオブジェクト O の [[Set]] 内部メソッドは、 プロパティ名 P、値 V、JavaScript言語値 Receiver で呼び出された場合、以下のように動作しなければならない:
-
もし O と Receiver が同一オブジェクトなら:
-
もし O が インターフェースを実装していて、インデックス付きプロパティsetterを持ち、 P が 配列インデックスなら:
-
インデックス付きプロパティsetterを呼び出す(O, P, V)。
-
true を返す。
-
-
もし O が インターフェースを実装していて、名前付きプロパティsetterを持ち、 P が String型なら:
-
名前付きプロパティsetterを呼び出す(O, P, V)。
-
true を返す。
-
-
-
ownDesc を ? LegacyPlatformObjectGetOwnProperty(O, P,
true ) とする。 -
? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc) を実行する。
3.9.3. [[DefineOwnProperty]]
全ての レガシープラットフォームオブジェクト O の [[DefineOwnProperty]] 内部メソッドがプロパティキー P と プロパティディスクリプタ Desc で呼び出された場合、以下の手順を実行する:
-
もし O が インデックス付きプロパティをサポートしていて、 P が 配列インデックスなら:
-
IsDataDescriptor(Desc) の結果が
false なら、false を返す。 -
もし O が インデックス付きプロパティsetterを持つインターフェースを実装していなければ
false を返す。 -
インデックス付きプロパティsetterを呼び出す(O, P, Desc.[[Value]])。
-
true を返す。
-
-
もし O が 名前付きプロパティをサポートしていて、 O が [
Global
] 拡張属性を持つインターフェースを実装しておらず、 P が String型で、 P が O の 偽造不可プロパティ名でない場合:-
creating を P が サポートされるプロパティ名でなければ true、そうであれば false とする。
-
もし O が [
LegacyOverrideBuiltIns
] 拡張属性を持つインターフェースを実装している場合、または O が P というownプロパティを持たない場合:-
もし creating が false かつ O が 名前付きプロパティsetterを持つインターフェースを実装していなければ
false を返す。 -
もし O が 名前付きプロパティsetterを持つインターフェースを実装していれば:
-
IsDataDescriptor(Desc) の結果が
false ならfalse を返す。 -
名前付きプロパティsetterを呼び出す(O, P, Desc.[[Value]])。
-
true を返す。
-
-
-
-
! OrdinaryDefineOwnProperty(O, P, Desc) を返す。
3.9.4. [[Delete]]
全ての レガシープラットフォームオブジェクト O の [[Delete]] 内部メソッドは、 プロパティ名 P で呼び出された場合、以下のように動作しなければならない。
-
もし O が インデックス付きプロパティをサポートしていて、 P が 配列インデックスなら:
-
もし index が サポートされるプロパティインデックスでなければ
true を返す。 -
false を返す。
-
もし O が 名前付きプロパティをサポートしていて、 O が [
Global
] 拡張属性を持つインターフェースを実装しておらず、 named property visibility algorithm を プロパティ名 P とオブジェクト O で呼び出した結果が true なら:-
もし O が 名前付きプロパティdeleterを持つインターフェースを実装していなければ
false を返す。 -
operation を名前付きプロパティdeleterを宣言した際に使用したoperationとする。
-
もし operation が識別子無しで定義されていれば:
-
インターフェース記述の指示に従い 既存の名前付きプロパティを削除する手順を実行し、 P を名前とする。
-
もし削除失敗であると指示された場合、
false を返す。
-
-
それ以外の場合、operation が識別子付きで定義されていれば:
-
true を返す。
-
-
もし O が P というownプロパティを持っていれば:
-
そのプロパティがconfigurableでなければ
false を返す。 -
それ以外なら O からそのプロパティを削除する。
-
-
true を返す。
3.9.5. [[PreventExtensions]]
レガシープラットフォームオブジェクトの [[PreventExtensions]] 内部メソッドが呼び出された場合、以下の手順を実行する:
-
false を返す。
注: これは レガシープラットフォームオブジェクト を 拡張可能(extensible)なままにし、[[PreventExtensions]] が失敗することを保証する。
3.9.6. [[OwnPropertyKeys]]
この文書では、インターフェースを実装するプラットフォームオブジェクト (または 例外を表すプラットフォームオブジェクト)の 完全なプロパティ列挙順を定義していない。 ただし、レガシープラットフォームオブジェクトについては [[OwnPropertyKeys]] 内部メソッドを以下の通り定義する。
レガシープラットフォームオブジェクト O の [[OwnPropertyKeys]] 内部メソッドが呼び出された場合、以下の手順を実行する:
-
keys を JavaScriptのString値およびSymbol値の空リストとして新規作成する。
-
もし O が インデックス付きプロパティをサポートしている場合は、 各 O の サポートされるプロパティインデックス index について、 昇順で append し、 ! ToString(index) を keys に追加する。
-
もし O が 名前付きプロパティをサポートしている場合は、 各 O の サポートされるプロパティ名 P について、 named property visibility algorithm で 可視なら append し、P を keys に追加する。
-
各 O の ownプロパティキー(String型) P について、プロパティ作成の昇順で append し、P を keys に追加する。
-
各 O の ownプロパティキー(Symbol型) P について、プロパティ作成の昇順で append し、P を keys に追加する。
-
Assert: keys に重複はない。
-
keys を返す。
3.9.7. 抽象操作
プロパティ名 P が 配列インデックスか判定するには、次のアルゴリズムを適用する:
-
もし P が String型でなければ、
false を返す。 -
index を CanonicalNumericIndexString(P) の結果とする。
-
もし index が
undefined ならfalse を返す。 -
もし IsInteger(index) が
false ならfalse を返す。 -
もし index が −0 なら
false を返す。 -
もし index < 0 なら
false を返す。 -
もし index ≥ 232 − 1 なら
false を返す。注: 232 − 1 は JavaScript の最大配列長である。
-
true を返す。
名前付きプロパティ可視性アルゴリズム
は、与えられた名前付きプロパティがオブジェクト上で公開されているかどうかを判定するために使用される。
一部の名前付きプロパティは、[LegacyOverrideBuiltIns
]
拡張属性の有無により公開されない場合がある。
このアルゴリズムは、プロパティ名 P とオブジェクト O について次のように動作する:
-
もし P が O の サポートされるプロパティ名でなければ false を返す。
-
もし O が P というownプロパティを持っていれば false を返す。
注: これには O が偽造不可プロパティを持つ場合も含まれる。実際、それらは常にサポートされるプロパティ名が設定される前にセットアップされるため、セットアップ後は対応する名前付きプロパティは不可視となる。
-
もし O が [
LegacyOverrideBuiltIns
] 拡張属性を持つインターフェースを実装していれば true を返す。 -
prototype を O.[[GetPrototypeOf]]() の値とする。
-
prototype が null でない間:
-
もし prototype が 名前付きプロパティオブジェクトでなく、 かつ prototype が P というownプロパティを持っていれば false を返す。
-
prototype を prototype.[[GetPrototypeOf]]() に設定する。
-
-
true を返す。
これにより、名前付きプロパティを持つオブジェクトに対してプロパティ解決が以下の順序で行われることが保証される:
-
インデックス付きプロパティ。
-
ownプロパティ(偽造不可属性や操作も含む)。
-
[
LegacyOverrideBuiltIns
] の場合:-
名前付きプロパティ。
-
プロトタイプチェーンからのプロパティ。
-
-
それ以外([
LegacyOverrideBuiltIns
] でない場合):-
プロトタイプチェーンからのプロパティ。
-
名前付きプロパティ。
-
インデックス付きプロパティsetterを呼び出す には、プラットフォームオブジェクト O、プロパティ名 P、JavaScript値 V を与え、以下の手順を実施する:
-
creating を index が サポートされるプロパティインデックスでなければ true、そうであれば false とする。
-
operation をインデックス付きプロパティsetterを宣言した際に使用したoperationとする。
-
T を operation の第2引数の型とする。
-
value を、V を型 T の IDL 値に変換した結果とする。
-
もし operation が識別子無しで定義されていれば:
-
もし creating が true なら、インターフェース記述の指示に従い 新しいインデックス付きプロパティの値を設定する手順を、 indexをインデックス、valueを値として実行する。
-
それ以外の場合(creating が false)、インターフェース記述の指示に従い 既存のインデックス付きプロパティの値を設定する手順を、 indexをインデックス、valueを値として実行する。
-
-
それ以外の場合、operation が識別子付きで定義されていれば、 メソッド手順(operation)を O を this、« index, value » を引数値として実行する。
名前付きプロパティsetterを呼び出す には、プラットフォームオブジェクト O、プロパティ名 P、JavaScript値 V を与え、以下の手順を実施する:
-
creating を P が サポートされるプロパティ名でなければ true、そうであれば false とする。
-
operation を名前付きプロパティsetterを宣言した際に使用したoperationとする。
-
T を operation の第2引数の型とする。
-
value を、V を型 T の IDL 値に変換した結果とする。
-
もし operation が識別子無しで定義されていれば:
-
もし creating が true なら、インターフェース記述の指示に従い 新しい名前付きプロパティの値を設定する手順を、 Pを名前、valueを値として実行する。
-
それ以外の場合(creating が false)、インターフェース記述の指示に従い 既存の名前付きプロパティの値を設定する手順を、 Pを名前、valueを値として実行する。
-
-
それ以外の場合、operation が識別子付きで定義されていれば、 メソッド手順(operation)を O を this、« P, value » を引数値として実行する。
LegacyPlatformObjectGetOwnProperty 抽象操作は、 オブジェクト O、プロパティ名 P、boolean値 ignoreNamedProps を受けて次の手順を実行する:
-
もし O が インデックス付きプロパティをサポートしていて、 P が 配列インデックスなら:
-
もし index が サポートされるプロパティインデックスなら:
-
operation をインデックス付きプロパティgetterを宣言した際に使用したoperationとする。
-
value を未初期化変数とする。
-
もし operation が識別子無しで定義されていれば、 value をインターフェース記述の指示に従い インデックス付きプロパティの値を取得する手順を indexをインデックスとして実行した結果に設定する。
-
それ以外の場合、operation が識別子付きで定義されていれば value を メソッド手順(operation)を O を this、« index » を引数値として実行した結果に設定する。
-
desc をフィールド無しの新規 プロパティディスクリプタとして生成する。
-
desc.[[Value]] を valueをJavaScript値へ変換した結果に設定する。
-
もし O が インデックス付きプロパティsetterを持つインターフェースを実装していれば desc.[[Writable]] を
true に、そうでなければfalse に設定する。 -
desc.[[Enumerable]] および desc.[[Configurable]] を
true に設定する。 -
desc を返す。
-
-
ignoreNamedProps を true に設定する。
-
もし O が 名前付きプロパティをサポートしていて、 ignoreNamedProps が false なら:
-
もし 名前付きプロパティ可視性アルゴリズム(プロパティ名 P、オブジェクト O)の結果が true なら:
-
operation を名前付きプロパティgetterを宣言した際に使用したoperationとする。
-
value を未初期化変数とする。
-
もし operation が識別子無しで定義されていれば、 value をインターフェース記述の指示に従い 名前付きプロパティの値を取得する手順を Pを名前として実行した結果に設定する。
-
それ以外の場合、operation が識別子付きで定義されていれば value を メソッド手順(operation)を O を this、« P » を引数値として実行した結果に設定する。
-
desc をフィールド無しの新規 プロパティディスクリプタとして生成する。
-
desc.[[Value]] を valueをJavaScript値へ変換した結果に設定する。
-
もし O が 名前付きプロパティsetterを持つインターフェースを実装していれば desc.[[Writable]] を
true に、そうでなければfalse に設定する。 -
もし O が [
LegacyUnenumerableNamedProperties
] 拡張属性を持つインターフェースを実装していれば desc.[[Enumerable]] をfalse に、そうでなければtrue に設定する。 -
desc.[[Configurable]] を
true に設定する。 -
desc を返す。
-
-
-
OrdinaryGetOwnProperty(O, P) を返す。
3.10. オブザーバブル配列エキゾチックオブジェクト
オブザーバブル配列エキゾチックオブジェクトは、JavaScriptの Proxyエキゾチックオブジェクトの特定の型であり、本節で定義されたプロキシトラップを用いて作成される。 これは、JavaScript仕様が ArrayインスタンスをプロキシターゲットとするProxyエキゾチックオブジェクトに対し特別な扱いを行っているためであり、 オブザーバブル配列型がこの特別扱いを保ったままJavaScriptコードに公開されることを保証したいからである。
オブザーバブル配列エキゾチックオブジェクトで使われるプロキシトラップは、通常のArray
インスタンスの不変条件よりも多くの不変条件を保証する:
-
配列には穴がなく、0 から
observableArray.length
− 1 までの各プロパティは指定されたWeb IDL型に適合する値で埋められており、その範囲外の 配列インデックスプロパティは存在しない。 -
重要なプロパティのプロパティディスクリプタはデフォルト構成から変更できない。インデックス付きプロパティは常にconfigurable, enumerable, writableなデータプロパティのままであり、
length
プロパティは非configurable, 非enumerable, writableなデータプロパティのままである。 -
Object.preventExtensions()
などを使って配列に追加プロパティを追加不可にすることはできない。
-
innerArray を ! ArrayCreate(0) とする。
-
handler を OrdinaryObjectCreate(
null , « [[Type]], [[SetAlgorithm]], [[DeleteAlgorithm]], [[BackingList]] ») とする。 -
handler.[[Type]] に T を設定する。
-
handler.[[SetAlgorithm]] に setAlgorithm を設定する。
-
handler.[[DeleteAlgorithm]] に deleteAlgorithm を設定する。
-
defineProperty を CreateBuiltinFunction(§ 3.10.1 defineProperty の手順, « », realm) とする。
-
! CreateDataPropertyOrThrow(handler, "
defineProperty
", defineProperty) を実行する。 -
deleteProperty を CreateBuiltinFunction(§ 3.10.2 deleteProperty の手順, « », realm) とする。
-
! CreateDataPropertyOrThrow(handler, "
deleteProperty
", deleteProperty) を実行する。 -
get を CreateBuiltinFunction(§ 3.10.3 get の手順, « », realm) とする。
-
! CreateDataPropertyOrThrow(handler, "
get
", get) を実行する。 -
getOwnPropertyDescriptor を CreateBuiltinFunction(§ 3.10.4 getOwnPropertyDescriptor の手順, « », realm) とする。
-
! CreateDataPropertyOrThrow(handler, "
getOwnPropertyDescriptor
", getOwnPropertyDescriptor) を実行する。 -
has を CreateBuiltinFunction(§ 3.10.5 has の手順, « », realm) とする。
-
! CreateDataPropertyOrThrow(handler, "
has
", has) を実行する。 -
ownKeys を CreateBuiltinFunction(§ 3.10.6 ownKeys の手順, « », realm) とする。
-
! CreateDataPropertyOrThrow(handler, "
ownKeys
", ownKeys) を実行する。 -
preventExtensions を CreateBuiltinFunction(§ 3.10.7 preventExtensions の手順, « », realm) とする。
-
! CreateDataPropertyOrThrow(handler, "
preventExtensions
", preventExtensions) を実行する。 -
set を CreateBuiltinFunction(§ 3.10.8 set の手順, « », realm) とする。
-
! CreateDataPropertyOrThrow(handler, "
set
", set) を実行する。 -
! ProxyCreate(innerArray, handler) を返す。
3.10.1. defineProperty
defineProperty
プロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O, P,
descriptorObjを与える)は以下の通り:
-
handler を
this の値とする。 -
descriptor を ! ToPropertyDescriptor(descriptorObj) の結果とする。
-
P が "length" なら:
-
IsAccessorDescriptor(descriptor) が
true ならfalse を返す。 -
descriptor.[[Configurable]] が present かつ値が
true ならfalse を返す。 -
descriptor.[[Enumerable]] が present かつ値が
true ならfalse を返す。 -
descriptor.[[Writable]] が present かつ値が
false ならfalse を返す。 -
descriptor.[[Value]] が present なら、 lengthの設定(handler, descriptor.[[Value]])の結果を返す。
-
true を返す。
-
-
P が 配列インデックスなら:
-
IsAccessorDescriptor(descriptor) が
true ならfalse を返す。 -
descriptor.[[Configurable]] が present かつ値が
false ならfalse を返す。 -
descriptor.[[Enumerable]] が present かつ値が
false ならfalse を返す。 -
descriptor.[[Writable]] が present かつ値が
false ならfalse を返す。 -
descriptor.[[Value]] が present なら、 インデックス値の設定(handler, P, descriptor.[[Value]])の結果を返す。
-
true を返す。
-
-
? O.[[DefineOwnProperty]](P, descriptor) を返す。
3.10.2. deleteProperty
deleteProperty
プロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O,
Pを与える)は以下の通り:
3.10.3.
get
get
プロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O, P,
Receiverを与える)は以下の通り:
3.10.4. getOwnPropertyDescriptor
getOwnPropertyDescriptor
プロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O,
Pを与える)は以下の通り:
-
handler を
this の値とする。 -
length を handler.[[BackingList]] の サイズとする。
-
P が "length" なら ! FromPropertyDescriptor(PropertyDescriptor{[[Configurable]]:
false , [[Enumerable]]:false , [[Writable]]:true , [[Value]]: length }) を返す。 -
P が 配列インデックスなら
-
index ≥ length なら
undefined を返す。 -
jsValue を handler.[[BackingList]][index] をJavaScript値へ変換した結果とする。
-
上記のステップで例外が投げられることはない。
-
FromPropertyDescriptor(PropertyDescriptor{[[Configurable]]:
true , [[Enumerable]]:true , [[Writable]]:true , [[Value]]: jsValue }) を返す。
-
FromPropertyDescriptor(? O.[[GetOwnProperty]](P)) を返す。
3.10.5.
has
has
プロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O,
Pを与える)は以下の通り:
3.10.6.
ownKeys
ownKeys
プロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、Oを与える)は以下の通り:
3.10.7. preventExtensions
3.10.8.
set
set
プロキシトラップの手順(オブザーバブル配列エキゾチックオブジェクト用、O, P,
V, Receiverを与える)は以下の通り:
-
handler を
this の値とする。 -
P が "length" なら lengthの設定(handler, V)の結果を返す。
-
P が 配列インデックスなら インデックス値の設定(handler, P, V)の結果を返す。
-
? O.[[Set]](P, V, Receiver) を返す。
3.10.9. 抽象操作
-
uint32Len ≠ numberLen なら
RangeError
例外を投げる。 -
oldLen を handler.[[BackingList]] の サイズとする。
-
uint32Len > oldLen なら
false を返す。 -
indexToDelete を oldLen − 1 とする。
-
While indexToDelete ≥ uint32Len の間:
-
handler.[[DeleteAlgorithm]] の手順を、handler.[[BackingList]][indexToDelete]、indexToDelete を与えて実行する。
-
handler.[[BackingList]] から最後の要素を削除する。
-
indexToDelete を indexToDelete − 1 にする。
-
-
true を返す。
-
oldLen を handler.[[BackingList]] の サイズとする。
-
index > oldLen なら
false を返す。 -
idlValue を Vを handler.[[Type]] 型のIDL値に変換した結果とする。
-
index < oldLen なら:
-
handler.[[DeleteAlgorithm]] の手順を、handler.[[BackingList]][index]、index を与えて実行する。
-
-
handler.[[SetAlgorithm]] の手順を、idlValue、index を与えて実行する。
-
index = oldLen なら idlValueを handler.[[BackingList]] に追加する。
-
それ以外の場合、handler.[[BackingList]][index] を idlValue に設定する。
-
true を返す。
3.11. コールバックインターフェース
§ 2.12 インターフェースを実装するオブジェクトで説明されている通り、 コールバックインターフェースは 任意のJavaScriptオブジェクトによってスクリプトで実装できる。 以下は、あるオブジェクトに対して コールバックインターフェースの operation を呼び出す場合のケースである:
-
オブジェクトが callable(呼び出し可能)であれば、operationの実装はその呼び出し可能オブジェクト自身となる。
-
それ以外の場合、operationの実装は、そのオブジェクトに対して operation の 識別子をプロパティ名として 内部 [[Get]] メソッドを呼び出した結果となる。
JavaScriptオブジェクトは、定数に対応する プロパティを持っていなくても、 その定数を宣言している コールバックインターフェースを実装したとみなされることに注意。
Web IDL 引数リストは、 各値がIDL値または特殊値“missing”(省略されたオプション引数を表す)のいずれかである値の リストである。
-
jsArgs を空の リストとする。
-
i を 0 とする。
-
count を 0 とする。
-
i < args の サイズ の間:
-
args[i] が特殊値“missing”なら、undefined を jsArgs に追加する。
-
それ以外の場合、args[i] はIDL値:
-
convertResult を args[i] をJavaScript値に変換した結果とする(例外は再スロー)。
-
convertResult を jsArgs に追加する。
-
count を i + 1 に設定する。
-
-
i を i + 1 にする。
-
-
jsArgs を count個の要素になるよう切り捨てる。
-
jsArgs を返す。
ユーザーオブジェクトの operation を呼び出すには、 コールバックインターフェース型値 value、 operation名 opName、Web IDL 引数リスト args、オプションの コールバックthis値 thisArg を与え、以下の手順を実行する。 これらの手順はIDL値を返すか例外を投げる。
-
completion を未初期化変数とする。
-
thisArg が与えられていなければ thisArg を
undefined にする。 -
O を value に対応するJavaScriptオブジェクトとする。
-
realm を O の 関連realmとする。
-
relevant settings を realm の 設定オブジェクトとする。
-
stored settings を value の コールバックコンテキストとする。
-
スクリプトの実行準備を relevant settings で行う。
-
コールバックの実行準備を stored settings で行う。
-
X を O とする。
-
IsCallable(O) が false なら:
-
getResult を Completion(Get(O, opName)) とする。
-
getResult が abrupt completion なら completion に getResult を設定し return のステップへジャンプする。
-
X を getResult.[[Value]] に設定する。
-
IsCallable(X) が
false なら completion に Completion Record { [[Type]]: throw, [[Value]]: 新規TypeError
オブジェクト, [[Target]]: 空 } を設定し return のステップへジャンプする。 -
thisArg を O に設定(与えられた値を上書き)。
-
-
jsArgs を argsをJavaScript引数リストに変換した結果とする。例外が投げられた場合、 completion に投げられた例外のcompletion値を設定し return のステップへジャンプする。
-
callResult を Completion(Call(X, thisArg, jsArgs)) とする。
-
callResult が abrupt completion なら completion に callResult を設定し return のステップへジャンプする。
-
completion を callResult.[[Value]] をoperationの戻り値型のIDL値に変換した結果に設定する。例外が投げられた場合はcompletionに例外のcompletion値を設定する。
-
Return: この時点で completion はIDL値か abrupt completion となる。
-
コールバック実行後のクリーンアップを stored settings で行う。
-
スクリプト実行後のクリーンアップを relevant settings で行う。
-
completionがIDL値ならcompletionを返す。
-
completionが abrupt completion で、operationの戻り値型が promise型でない場合、completion.[[Value]] をthrowする。
-
rejectedPromise を ! Call(
%Promise.reject%
,%Promise%
, «completion.[[Value]]») とする。 -
rejectedPromise をoperationの戻り値型へ変換した結果を返す。
-
3.11.1. レガシーコールバックインターフェースオブジェクト
ある コールバックインターフェース が ある realmで公開されていて、 そのインターフェース上に 定数が定義されている場合、 対応するプロパティが realm の グローバルオブジェクト 上に存在する。 このプロパティ名は コールバックインターフェースの識別子であり、 その値は レガシーコールバックインターフェースオブジェクトである。
特定の コールバックインターフェースの レガシーコールバックインターフェースオブジェクトは 組み込み関数オブジェクトである。 そのプロパティには、そのインターフェースで定義されている 定数が対応しており、詳細は § 3.7.5 定数 に記載されている。
注:
レガシーコールバックインターフェースオブジェクトは
関数オブジェクトであるため、
typeof
演算子を適用すると "function" を返す。
特定の コールバックインターフェース interface (識別子 id、realm realm)の レガシーコールバックインターフェースオブジェクトは、以下の手順で 生成される:
-
steps を以下のステップとする:
-
TypeError例外を投げる。
-
-
F を CreateBuiltinFunction(steps, « », realm) とする。
-
SetFunctionName(F, id) を実行する。
-
SetFunctionLength(F, 0) を実行する。
-
定数の定義(interface, F, realm)を実行する。
-
F を返す。
3.12. コールバック関数の呼び出し
JavaScriptの 呼び出し可能オブジェクトが コールバック関数値として利用される場合は、 operationが コールバックインターフェース値上で呼び出される場合(前節参照)と 似た方法で呼び出される。
呼び出す
には
コールバック関数型値
callable、
Web IDL
引数リスト args、
例外動作 exceptionBehavior("report
"または"rethrow
")、
オプションの コールバックthis値 thisArg を与え、以下の手順を実行する。
これらの手順はIDL値を返すか例外を投げる。
exceptionBehavior 引数は、callable の 戻り値型が
promise型でない場合に限り必須となる。
callable の戻り値型が
undefined
または any
以外なら
必ず "rethrow
" でなければならない。
rethrow
" を指定したものと見なすべきである。
-
completion を未初期化変数とする。
-
thisArg が与えられていなければ thisArg を
undefined にする。 -
F を callable に対応するJavaScriptオブジェクトとする。
-
IsCallable(F) が
false なら:-
注: これはコールバック関数が [
LegacyTreatNonObjectAsNull
] 属性付きの属性から来た場合のみ起こり得る。 -
undefined をコールバック関数の戻り値型に変換した結果を返す。
-
-
realm を F の 関連realmとする。
-
relevant settings を realm の 設定オブジェクトとする。
-
stored settings を callable の コールバックコンテキストとする。
-
スクリプトの実行準備を relevant settings で行う。
-
コールバックの実行準備を stored settings で行う。
-
jsArgs を argsをJavaScript引数リストに変換した結果とする。例外が投げられた場合、 completion に投げられた例外のcompletion値を設定し return のステップへジャンプする。
-
callResult を Completion(Call(F, thisArg, jsArgs)) とする。
-
callResult が abrupt completion なら completion に callResult を設定し return のステップへジャンプする。
-
completion を callResult.[[Value]] をコールバック関数の戻り値型のIDL値に変換した結果に設定する。例外が投げられた場合はcompletionに例外のcompletion値を設定する。
-
Return: この時点で completion はIDL値か abrupt completion となる。
-
コールバック実行後のクリーンアップを stored settings で行う。
-
スクリプト実行後のクリーンアップを relevant settings で行う。
-
completionがIDL値ならcompletionを返す。
-
Assert: completionは abrupt completion であること。
-
exceptionBehaviorが"
rethrow
"なら completion.[[Value]] をthrowする。 -
それ以外で exceptionBehaviorが"
report
"なら: -
rejectedPromise を ! Call(
%Promise.reject%
,%Promise%
, «completion.[[Value]]») とする。 -
rejectedPromise をコールバック関数の戻り値型へ変換した結果を返す。
-
一部のコールバック関数は コンストラクタとして使われる場合がある。その場合、戻り値型が promise型であってはならない。
コールバック関数を構築するには コールバック関数型値 callable、 Web IDL 引数リスト args を与え、以下の手順を実行する。 これらの手順はIDL値を返すか例外を投げる。
-
completion を未初期化変数とする。
-
F を callable に対応するJavaScriptオブジェクトとする。
-
IsConstructor(F) が
false ならTypeError
例外を投げる。 -
realm を F の 関連realmとする。
-
relevant settings を realm の 設定オブジェクトとする。
-
stored settings を callable の コールバックコンテキストとする。
-
スクリプトの実行準備を relevant settings で行う。
-
コールバックの実行準備を stored settings で行う。
-
jsArgs を argsをJavaScript引数リストに変換した結果とする。例外が投げられた場合、 completion に投げられた例外のcompletion値を設定し return のステップへジャンプする。
-
callResult を Completion(Construct(F, jsArgs)) とする。
-
callResult が abrupt completion なら completion に callResult を設定し return のステップへジャンプする。
-
completion を callResult.[[Value]] をコールバック関数の戻り値型のIDL値に変換した結果に設定する。例外が投げられた場合はcompletionに例外のcompletion値を設定する。
-
Return: この時点で completion はIDL値か abrupt completion となる。
-
コールバック実行後のクリーンアップを stored settings で行う。
-
スクリプト実行後のクリーンアップを relevant settings で行う。
-
completionが abrupt completion なら completion.[[Value]] をthrowする。
-
completionを返す。
-
3.13. 名前空間
ある 名前空間 が特定の realmで公開されている場合、 対応するプロパティがその realm の グローバルオブジェクト上に存在する。 プロパティ名はその名前空間の 識別子であり、値は 名前空間オブジェクトと呼ばれるオブジェクトである。
名前空間オブジェクトの特徴は § 3.13.1 名前空間オブジェクト に記載されている。
3.13.1. 名前空間オブジェクト
特定の 名前空間 namespace と realm realm の 名前空間オブジェクトは、以下の手順で 生成される:
-
namespaceObject を OrdinaryObjectCreate(realm.[[Intrinsics]].[[
%Object.prototype%
]]) とする。 -
通常の属性を定義する(namespace, namespaceObject, realm)を実行する。
-
通常の操作を定義する(namespace, namespaceObject, realm)を実行する。
-
定数の定義(namespace, namespaceObject, realm)を実行する。
-
各 公開された インターフェース interface で、 [
LegacyNamespace
] 拡張属性の引数として namespace の識別子が指定されているものについて:-
id を interface の 識別子とする。
-
interfaceObject を インターフェースオブジェクトの生成(interface, id, realm)の結果とする。
-
DefineMethodProperty(namespaceObject, id, interfaceObject, false) を実行する。
-
-
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
-
Assert: name は
DOMException
名テーブルに含まれている。 -
ex を 現行realmで新規作成した
DOMException
とする。 -
ex の name を name に設定する。
-
ex の message を例外状況に適した 実装依存メッセージに設定する。呼び出し元仕様は、実装がこのメッセージを構築する際の参考情報を持つ場合がある。
実装はこのメッセージを構築する際、クロスオリジンフレームのURLやユーザーを特定できる情報など、機密性やセキュリティに関する情報を漏らさないよう注意すること。
-
ex を返す。
-
ex を 現行realmで新規作成した type識別子の インターフェース インスタンスとする。
-
ex の name を type に設定する。
-
ex の message を例外状況に適した 実装依存メッセージに設定する。呼び出し元仕様は、実装がこのメッセージを構築する際の参考情報を持つ場合がある。
実装はこのメッセージを構築する際、クロスオリジンフレームのURLやユーザーを特定できる情報など、機密性やセキュリティに関する情報を漏らさないよう注意すること。
-
呼び出し元による追加の初期化処理を ex に対して実施する。
-
ex を返す。
上記アルゴリズムにより、例外を表すオブジェクトが 関数オブジェクトの外に伝播する際は、その realm(関数オブジェクトのrealm、すなわち関数実行時の 現行realm)に紐づくものに限定される。 例えば以下のIDL定義を考える:
[Exposed =Window ]interface MathUtils { // xが負の場合は "NotSupportedError" DOMException をthrowする。double computeSquareRoot (double x ); };
もし異なる realm の MathUtils
オブジェクトに対して computeSquareRoot
を適用した場合、
throwされる例外はメソッドのrealm(呼び出されたメソッドのrealm)に属するものであり、
適用されたオブジェクトのrealmではない:
const myMU= window. getMathUtils(); // このrealmのMathUtilsオブジェクト const otherMU= otherWindow. getMathUtils(); // 異なるrealmのMathUtilsオブジェクト myMUinstanceof Object; // trueになる otherMUinstanceof Object; // falseになる otherMUinstanceof otherWindow. Object; // trueになる try { otherMU. doComputation. call( myMU, - 1 ); } catch ( e) { console. assert( ! ( einstanceof DOMException)); console. assert( einstanceof otherWindow. DOMException); }
3.14.4. 例外の扱い
特に指定がない限り、 本書の要件によりJavaScriptランタイムセマンティクスが呼び出され、 例外がthrowされて終了した場合は、その例外は呼び出し元へ伝播し、そこでcatchされなければさらにその呼び出し元へ、以降も同様に伝播しなければならない。
文書の慣例に従い、本書で定義されるアルゴリズムはthrowされた例外を捕捉する場合があり、その際には 例外がthrowされた場合に取るべき具体的な手順を記述するか、 abrupt completionを明示的に扱う。
次のIDLフラグメントは2つのインターフェースと1つの例外を定義する。
ExceptionThrower
のvalueOf
属性は、値の取得を試みるたびに例外を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 = "Error");
name readonly attribute DOMString name ;readonly attribute DOMString message ;readonly attribute unsigned short code ;const unsigned short INDEX_SIZE_ERR = 1;const unsigned short = 2;
DOMSTRING_SIZE_ERR const unsigned short HIERARCHY_REQUEST_ERR = 3;const unsigned short WRONG_DOCUMENT_ERR = 4;const unsigned short INVALID_CHARACTER_ERR = 5;const unsigned short = 6;
NO_DATA_ALLOWED_ERR 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 = 16;
VALIDATION_ERR 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)
のコンストラクタ手順は以下の通り:
name
のgetter手順は this の name を返す。
message
のgetter手順は this の message を返す。
code
のgetter手順は、DOMException
名テーブルで this の name に対応するレガシーコード、該当エントリがなければ0を返す。
DOMException
オブジェクトはシリアライズ可能オブジェクトである。
そのシリアライズ手順は、valueとserializedを与え、次の通り:
- value の name に serialized.[[Name]] を設定する。
- value の message に serialized.[[Message]] を設定する。
- もし 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文法
この節では、開始記号
文法の各生成規則の右辺は、ゼロでない個数の終端記号と非終端記号の並び、または ε(何もないことを表す)である。 大文字で始まる記号は非終端記号である。 等幅フォントで記載された記号は終端記号である。 小文字で始まるサンセリフ体の記号は、Perl 5正規表現構文 [PERLRE] を用いた正規表現でマッチする終端記号である:
=
|
/-?([1-9][0-9]*|0[Xx][0-9A-Fa-f]+|0[0-7]*)/
|
|
=
|
/-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)/
|
|
=
|
/[_-]?[A-Za-z][0-9A-Z_a-z-]*/
|
|
=
|
/"[^"]*"/
|
|
=
|
/[\t\n\r ]+/
|
|
=
|
/\/\/.*|\/\*(.|\n)*?\*\//
|
|
=
|
/[^\t\n\r 0-9A-Za-z]/
|
トークナイザは スカラー値の列で動作する。
トークナイズ時は、可能な限り最長一致でマッチを行う必要がある。例えば、入力テキストが「a1」の場合は、long
"という
IDL構文は大文字・小文字を区別する。文法で使われる等幅フォント終端記号や A
"なら"a
"とは区別される。
また 拡張属性
[legacyfactoryfunction
]は
[LegacyFactoryFunction
]
拡張属性として認識されない。
暗黙的に、入力テキストの各終端記号の間には任意個数の
以下のLL(1)文法は、開始記号
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 )
注:
一方、
文書の規約
本書では、以下の書式規約が使用されています。
-
用語の定義箇所:例示用語
-
本書または他文書で定義された用語へのリンク:例示用語
-
文法の終端記号:
sometoken -
文法の非終端記号:
ExampleGrammarNonTerminal -
文法記号:
identifier -
IDL型:
unsigned long
-
JavaScriptクラス:
Map
-
JavaScript言語型:Object
-
コードスニペット:
a = b + obj.f()
-
スカラー値:U+0030 (0)
-
拡張属性:[
ExampleExtendedAttribute
] -
文章やアルゴリズム中の変数名:exampleVariableName。
-
IDL非公式構文例:
[
extended_attributes ]interface identifier { /* interface_members... */ };(周辺の文章で説明されている構文の特定部分が ハイライトされています。)
-
IDL文法スニペット:
ExampleGrammarNonTerminal ::OtherNonTerminal sometoken other AnotherNonTerminal ε //nothing -
非規範的な注記:
注: これは注記です。
-
非規範的な例:
-
規範的な警告:
これは警告です。
-
コードブロック:
// これはIDLのコードブロックです。 [
Exposed =Window ]interface Example {attribute long something ; };// これはJavaScriptのコードブロックです。 window. onload= function () { window. alert( "loaded" ); };
本書のアルゴリズムでは、以下の規約が使用されています。
-
アルゴリズムは JavaScript仕様の規約を用いており、 ! と ? の記法で Completion Records のアンラップを表します。
-
アルゴリズムは、値の返却や例外のthrow、Completion Records の返却を同等に扱う場合があります。すなわち、return/throw用語を使うアルゴリズムは Completion Record を返すものとみなされる一方、Completion Record を返すものは値を返す・例外をthrowするものとして扱われることがあります。同様に、例外を捕捉する際、例外がスローされた場合の動作を定義し、Completion Record の [[Type]] フィールドが "throw" かどうかを確認することは等価です。
-
Completion Records は、 JavaScript値以外の値(Web IDL値など)を含むことができるよう拡張されています。
適合性
図、例、注記、および参考情報として明記されたセクションを除き、本仕様書のすべてが規範的です。
本仕様書は Infra Standard(基盤標準)に依存します。[INFRA]
本仕様書では、以下の適合クラスを定義します。
- IDLフラグメントの適合セット
-
複数の IDLフラグメント の集合は、 この仕様書でIDLフラグメントに適用されるmust、required、およびshallレベルの基準をすべて満たす場合、 IDLフラグメントの適合セットとみなされます。
- 適合実装
-
ユーザーエージェントは、 適合実装 として、 IDLフラグメントの適合セットに対して、 ユーザーエージェントがサポートするすべての言語バインディングに関して、この仕様書のmust、required、およびshallレベルの基準をすべて満たす場合に該当します。
- 適合JavaScript実装
-
ユーザーエージェントは、 適合JavaScript実装 として、 IDLフラグメントの適合セットに対して、 JavaScript言語バインディングに関して、この仕様書のmust、required、およびshallレベルの基準をすべて満たす場合に該当します。
知的財産権
Copyright © WHATWG (Apple, Google, Mozilla, Microsoft)。この文書は クリエイティブ・コモンズ表示 4.0 国際ライセンス の下でライセンスされています。一部がソースコードに組み込まれる場合、その部分は BSD 3-Clause License の下でライセンスされます。
これは現行標準です。特許審査版については 現行標準審査ドラフトを参照してください。