웹 IDL

현행 표준 — 최종 업데이트

참여하기:
GitHub whatwg/webidl (새 이슈 등록, 오픈된 이슈)
Matrix에서 채팅하기
커밋:
GitHub whatwg/webidl/커밋 내역
이 커밋 기준의 스냅샷
@webidl
테스트:
web-platform-tests webidl/ (진행 중인 작업)
번역 (비규범):
일본어
중국어(간체)

요약

이 표준은 웹 브라우저에서 구현될 인터페이스를 기술하기 위해 사용할 수 있는 인터페이스 정의 언어인 웹 IDL을 정의합니다.

1. 소개

이 섹션은 참고용입니다.

이 표준은 웹 브라우저에 구현될 인터페이스를 기술하는 데 사용할 수 있는 인터페이스 정의 언어, 웹 IDL을 정의합니다. 웹 IDL은 웹 플랫폼의 일반적인 스크립트 객체의 동작을 보다 쉽게 명세할 수 있도록 하는 다양한 기능을 가진 IDL 변형입니다. 웹 IDL로 기술된 인터페이스가 자바스크립트 실행 환경 내의 구조와 어떻게 대응되는지도 이곳에서 자세히 설명합니다.

구체적으로, 웹 IDL은 웹 플랫폼 객체의 표면 API를 명세하는 구문과, 그 API가 자바스크립트 구조로 어떻게 나타나는지 상세히 기술하는 자바스크립트 바인딩을 제공합니다. 이로 인해 글로벌 속성 설치, 숫자 입력 처리, 반복 동작 노출과 같은 일반적인 작업들이 웹 플랫폼 명세서 전체에서 일관성을 유지할 수 있습니다. 이러한 명세서들은 웹 IDL로 인터페이스를 기술하고, 프로즈로 API 고유의 세부사항을 명세합니다.

"자바스크립트"라는 용어는 공식 용어 ECMAScript가 아닌 ECMA-262를 의미하며, 자바스크립트라는 명칭이 더 널리 알려져 있기 때문에 사용합니다.

2. 인터페이스 정의 언어

이 섹션에서는 웹 IDL이라는 언어를 설명합니다. 이는 웹 플랫폼의 API를 정의하는 인터페이스를 명세하는 데 사용할 수 있습니다. 웹 API를 정의하는 명세서는 하나 이상의 IDL 프래그먼트를 포함하여, 해당 명세서에서 정의된 API의 인터페이스(객체가 가질 수 있는 상태와 동작)를 기술합니다. IDL 프래그먼트Definitions 문법 기호에 일치하는 일련의 정의입니다. 구현체가 지원하는 IDL 프래그먼트 집합은 순서가 없습니다. 전체 문법과 표기법 설명은 IDL 문법을 참고하세요.

IDL 프래그먼트에 등장할 수 있는 다양한 정의의 종류는 다음과 같습니다: 인터페이스, 부분 인터페이스 정의, 인터페이스 믹스인, 부분 믹스인 정의, 콜백 함수, 콜백 인터페이스, 네임스페이스, 부분 네임스페이스 정의, 딕셔너리, 부분 딕셔너리 정의, 타입 정의(typedef)includes 문입니다. 모든 종류는 아래 섹션에서 정의됩니다.

정의 (Definition에 일치) 앞에는 확장 속성 목록(ExtendedAttributeList에 일치)이 올 수 있으며, 이는 해당 정의가 언어 바인딩에서 어떻게 처리될지 제어합니다. 이 명세서에서 정의된 언어 바인딩에 독립적인 확장 속성은 § 2.14 확장 속성에서, 자바스크립트 언어 바인딩에 특화된 것은 § 3.3 확장 속성에서 설명합니다.

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

아래는 IDL 프래그먼트의 예시입니다.

[Exposed=Window]
interface Paint { };

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

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

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

  attribute Paint currentPaint;

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

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

여기서는 네 개의 인터페이스가 정의되고 있습니다. GraphicalWindow 인터페이스에는 두 개의 읽기 전용 속성, 하나의 쓰기 가능한 속성, 그리고 두 개의 연산이 정의되어 있습니다. GraphicalWindow 인터페이스를 구현하는 객체들은 해당 언어에 맞는 방식으로 이 속성과 연산을 노출합니다.

자바스크립트에서는, IDL 인터페이스의 속성들이 접근자 속성으로, 연산들은 모든 GraphicalWindow 객체의 프로토타입 객체에 내장 함수 객체(built-in function object)로서 데이터 속성으로 노출됩니다. 각 자바스크립트 객체는 GraphicalWindow를 구현하면 해당 프로토타입 객체를 프로토타입 체인에 갖게 됩니다.

GraphicalWindow에 등장하는 생성자 연산은 자바스크립트 구현체에서 생성자가 존재하도록 하여, new GraphicalWindow()를 호출하면 해당 인터페이스를 구현하는 새로운 객체를 반환합니다.

모든 인터페이스에는 [Exposed] 확장 속성이 붙어 있으며, 이로 인해 인터페이스가 realm글로벌 객체Window 객체인 경우에만 사용할 수 있도록 보장합니다.

2.1. 이름

모든 인터페이스, 부분 인터페이스 정의, 네임스페이스, 부분 네임스페이스 정의, 딕셔너리, 부분 딕셔너리 정의, 열거형, 콜백 함수, 콜백 인터페이스타입 정의(typedef) (이들을 통틀어 이름이 있는 정의이라 함) 그리고 모든 상수, 속성, 딕셔너리 멤버식별자를 가지며, 일부 연산도 마찬가지입니다. 식별자는 선언 내 어딘가에 등장하는 identifier 토큰에 의해 결정됩니다:

참고: 연산은 getter, setter와 같은 특수 연산을 선언할 때 식별자가 없을 수 있습니다.

이러한 모든 구조에서, 식별자identifier 토큰 값에서 앞에 오는 U+005F (_)를 제거한 값입니다.

참고: 앞에 오는 U+005F (_)는 식별자가 예약어처럼 보이지 않게 하기 위해 사용되며, 예를 들어 "interface"라는 이름의 인터페이스를 정의할 수 있습니다. 식별자를 해제할 때는 앞의 U+005F (_)를 삭제합니다.

연산의 인자(argument)는 더 넓은 범위의 식별자 집합을 가질 수 있습니다. 연산 선언에서 인자의 식별자는 타입 뒤에 바로 명시되며, identifier 토큰 또는 ArgumentNameKeyword 심볼에 매칭되는 키워드 중 하나로 지정됩니다. 이런 키워드가 사용될 경우, 앞에 밑줄로 이스케이프할 필요가 없습니다.

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

identifier 토큰이 사용된 경우, 연산 인자의 식별자는 해당 토큰 값에서 앞의 U+005F (_)를 제거한 값입니다. 만약 ArgumentNameKeyword 키워드 토큰이 사용된다면, 연산 인자의 식별자는 그 토큰 자체입니다.

위에 언급된 IDL 구조(연산 인자 제외)의 식별자는 "constructor", "toString"이거나 U+005F (_)로 시작해서는 안 됩니다. 이런 것들은 예약 식별자라 부릅니다.

"toJSON" 식별자예약 식별자는 아니지만, 정상 연산에서만 객체를 JSON 타입으로 변환하는 목적으로 사용해야 하며, § 2.5.3.1 toJSON에서 설명합니다.

참고: 특정 구조에 대한 식별자 명명 제한은 이후 섹션에서 추가될 수 있습니다.

주어진 구현체가 지원하는 IDL 프래그먼트 집합 내에서, 모든 인터페이스, 네임스페이스, 딕셔너리, 열거형, 콜백 함수, 콜백 인터페이스, 타입 정의식별자는 서로 같아서는 안 됩니다.

하나의 IDL 프래그먼트 내에서는, 정의에 대한 참조가 참조된 정의의 선언 뒤에 등장하지 않아도 됩니다. 또한 IDL 프래그먼트 간에도 참조할 수 있습니다.

따라서, 아래의 IDL 프래그먼트는 유효합니다:

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

[Exposed=Window]
interface A {
};

typedef sequence<long> SequenceOfLongs;

아래의 IDL 프래그먼트는 정의와 인터페이스 멤버에 어떻게 식별자가 부여되는지 보여줍니다.

// 타입 정의 식별자: "number"
typedef double number;

// 인터페이스 식별자: "System"
[Exposed=Window]
interface System {

  // 연산 식별자:          "createObject"
  // 연산 인자 식별자: "interface"
  object createObject(DOMString _interface);

  // 연산 인자 식별자: "interface"
  sequence<object> getObjects(DOMString interface);

  // 연산에는 식별자가 없음; getter 선언임.
  getter DOMString (DOMString keyName);
};

// 인터페이스 식별자: "TextField"
[Exposed=Window]
interface TextField {

  // 속성 식별자: "const"
  attribute boolean _const;

  // 속성 식별자: "value"
  attribute DOMString? _value;
};

TextField 인터페이스의 두 번째 속성은 (IDL 문법에서 "value"가 키워드가 아니므로) 반드시 밑줄로 이스케이프할 필요는 없지만, 그래도 속성의 식별자를 얻기 위해 언이스케이프됩니다.

2.2. 인터페이스

IDL 프래그먼트는 객체 지향 시스템을 기술하는 데 사용됩니다. 이러한 시스템에서 객체란 정체성을 가지고 있으며, 상태와 행동을 캡슐화한 엔티티입니다. 인터페이스는 (interface InterfaceRest에 일치) 해당 인터페이스를 구현하는 객체가 노출하는 상태와 행동을 선언하는 정의입니다.

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

인터페이스는 인터페이스 멤버 (InterfaceMembers에 일치)의 집합을 명세합니다. 인터페이스 선언 중괄호 사이에 등장하는 멤버들이 이에 해당합니다.

웹 IDL의 인터페이스는 해당 인터페이스를 구현하는 객체가 어떻게 동작하는지 기술합니다. 객체 지향 언어 바인딩에서는, 특정 IDL 인터페이스를 구현하는 객체가 객체의 상태를 검사하고 수정하며, 인터페이스가 기술하는 동작을 호출할 수 있도록 제공하는 것이 기대됩니다.

인터페이스는 다른 인터페이스를 상속하도록 정의할 수 있습니다. 만약 인터페이스 식별자 뒤에 U+003A (:)와 식별자가 오면, 해당 식별자가 상속받는 인터페이스를 나타냅니다. 어떤 객체가 다른 인터페이스를 상속한 인터페이스를 구현하면, 그 객체는 상속받은 인터페이스도 구현하게 됩니다. 즉, 객체는 상속된 인터페이스의 멤버도 가지게 됩니다.

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

멤버의 등장 순서는 자바스크립트 바인딩에서 프로퍼티 열거에 영향을 미칩니다.

인터페이스는 상속받은 인터페이스의 멤버와 같은 이름의 인터페이스 멤버를 명시할 수도 있습니다. 파생 인터페이스를 구현하는 객체는 파생 인터페이스의 멤버를 노출합니다. 오버라이드된 멤버를 객체에서 접근할 수 있는지는 언어 바인딩에 따라 다릅니다.

다음 두 개의 인터페이스를 살펴봅시다.

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

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

자바스크립트 바인딩에서 B의 인스턴스는 아래와 같은 프로토타입 체인을 가집니다:

[Object.prototype: Object 프로토타입 객체]
     ↑
[A.prototype: A의 인터페이스 프로토타입 객체]
     ↑
[B.prototype: B의 인터페이스 프로토타입 객체]
     ↑
[instanceOfB]

자바스크립트에서 instanceOfB.f()를 호출하면 B에 정의된 f가 실행됩니다. 하지만 A의 f도 A.prototype.f.call(instanceOfB)로 호출할 수 있습니다.

주어진 인터페이스 A상속 인터페이스들A가 직접 또는 간접적으로 상속하는 모든 인터페이스의 집합입니다. A가 다른 인터페이스를 상속하지 않으면 집합은 비어 있습니다. 그렇지 않으면, 집합에는 A상속하는 인터페이스 BB상속 인터페이스들이 포함됩니다.

인터페이스의 상속 계층에 순환(cycle)이 있어서는 안 됩니다. 즉, 인터페이스 A가 자기 자신을 상속하거나, B에서 A를 상속하는 등 반복적으로 상속할 수 없습니다.

리스트로서 포함된 상속 인터페이스들인터페이스 I에 대해 다음과 같이 정의됩니다:
  1. result를 « »로 둔다.

  2. interfaceI로 둔다.

  3. interface가 null이 아닐 동안:

    1. result에 interface를 추가한다.

    2. interfaceI상속하는 인터페이스로 설정하고, 없으면 null로 한다.

  4. result를 반환한다.

일반적인 인터페이스의 다중 상속은 지원하지 않으며, 객체도 임의의 인터페이스 집합을 구현할 수 없습니다. 객체는 하나의 주어진 인터페이스 A를 구현하도록 정의되며, 이는 A상속 인터페이스들도 구현함을 의미합니다. 추가로, includes 문을 사용하여 인터페이스 A를 구현하는 객체가 인터페이스 믹스인 멤버도 항상 포함하도록 정의할 수 있습니다. Ainclude하는 인터페이스 믹스인의 멤버를 포함합니다.

각 인터페이스 멤버는 확장 속성 리스트(ExtendedAttributeList에 일치)가 앞에 올 수 있으며, 이는 해당 멤버가 언어 바인딩에서 어떻게 처리될지 제어합니다.

[extended_attributes]
interface identifier {

  [extended_attributes]
  const type constant_identifier = 42;

  [extended_attributes]
  attribute type identifier;

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

인터페이스에 대한 IDL은 부분 인터페이스 정의(partial interface PartialInterfaceRest에 일치)를 사용하여 여러 부분으로 나눌 수 있습니다. 부분 인터페이스 정의의 식별자는 반드시 인터페이스 정의의 식별자와 같아야 합니다. 각 부분 인터페이스에 등장하는 모든 멤버는 실제 인터페이스의 멤버로 간주합니다.

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

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

참고: 부분 인터페이스 정의는 명세 편집 시, 하나의 인터페이스 정의를 여러 문서 또는 여러 섹션에 나눠서 기술하는 데 도움을 주기 위한 것입니다.

인터페이스 정의와 그 부분 인터페이스 정의의 등장 순서는 중요하지 않습니다.

참고: 부분 인터페이스 정의는 인터페이스가 다른 인터페이스를 상속하도록 지정할 수 없습니다. 상속은 원래의 인터페이스 정의에서 지정해야 합니다.

적용되는 언어 바인딩이 인터페이스가 해당 언어의 구조와 어떻게 대응되는지 결정합니다.

다음 확장 속성들이 인터페이스에 적용될 수 있습니다: [CrossOriginIsolated], [Exposed], [Global], [LegacyFactoryFunction], [LegacyNoInterfaceObject], [LegacyOverrideBuiltIns], [LegacyWindowAlias], [SecureContext].

다음 확장 속성들은 부분 인터페이스에 적용될 수 있습니다: [CrossOriginIsolated], [Exposed], [LegacyOverrideBuiltIns], [SecureContext].

인터페이스는 반드시 [Exposed] 확장 속성으로 주석 처리해야 합니다.

인터페이스 interface정규화된 이름은 다음과 같이 정의됩니다:

  1. identifierinterface식별자로 둔다.

  2. interface에 [LegacyNamespace] 확장 속성이 있으면:

    1. namespace를 [LegacyNamespace] 확장 속성의 식별자 인자로 둔다.

    2. « namespace, identifier »를 U+002E (.)로 연결하여 반환한다.

  3. identifier를 반환한다.

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

아래 IDL 프래그먼트는 상호 참조하는 두 인터페이스의 정의를 보여줍니다. HumanDog는 모두 Animal을 상속합니다. 이 두 인터페이스를 구현하는 객체는 name 속성을 갖게 됩니다.

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

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

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

아래 IDL 프래그먼트는 DOM 인터페이스콜백 인터페이스의 단순화된 정의를 보여줍니다.

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

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

일반 객체는 EventListener와 같은 콜백 인터페이스를 구현할 수 있습니다:

var node = getNode();                                // Node 인스턴스 얻기

var listener = {
  handleEvent: function(event) {
    // ...
  }
};
node.addEventListener("click", listener);            // 동작함

node.addEventListener("click", function() { ... });  // 이것도 동작함

이런 객체는 Node와 같은 인터페이스를 구현할 수는 없습니다:

var node = getNode();  // Node 인스턴스 얻기

var newNode = {
  nodeName: "span",
  parentNode: null,
  appendChild: function(newchild) {
    // ...
  },
  addEventListener: function(type, listener) {
    // ...
  }
};
node.appendChild(newNode);  // TypeError 예외 발생

2.3. 인터페이스 믹스인

인터페이스 믹스인은 (interface MixinRest에 일치) 하나 이상의 인터페이스에서 include하여 객체가 노출할 수 있는 상태와 행동을 선언합니다. 인터페이스에서 include인터페이스 믹스인을 구현하는 객체에 의해 노출됩니다.

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

참고: 인터페이스 믹스인부분 인터페이스와 마찬가지로, 명세 편집의 편의를 위해 사용되어 일관된 기능 집합을 묶고, 여러 인터페이스(문서 간 포함 가능)에 포함할 수 있게 합니다. 언어 바인딩을 통해 직접 노출되도록 의도된 것이 아닙니다. § 2.3.1 믹스인 및 부분 사용에서 부분 인터페이스, 인터페이스 믹스인, 부분 인터페이스 믹스인 중 어느 것을 선택할지 설명합니다.

인터페이스 믹스인인터페이스 믹스인 멤버 (MixinMembers에 일치) 집합을 명세합니다. 즉, 상수, 일반 연산, 일반 속성, 문자열 변환자들이 중괄호 사이에 선언됩니다.

이러한 상수, 일반 연산, 일반 속성, 문자열 변환자는 해당 객체가 구현할 수 있는 동작을 기술하며, 마치 이를 인터페이스에 직접 명세한 것처럼 동작합니다.

정적 속성, 정적 연산, 특수 연산, 이터러블, 비동기 이터러블, maplike, setlike 선언인터페이스 믹스인 선언에 포함될 수 없습니다.

인터페이스와 마찬가지로, 인터페이스 믹스인의 IDL도 부분 인터페이스 믹스인 정의(partial interface MixinRest에 일치)를 이용해 여러 부분으로 나눌 수 있습니다. 부분 인터페이스 믹스인 정의식별자는 해당 인터페이스 믹스인 정의의 식별자와 같아야 합니다. 각 부분 인터페이스 믹스인에 등장하는 모든 멤버는 실제 인터페이스 믹스인의 멤버로 간주되고, 인터페이스include할 때도 포함됩니다.

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

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

멤버의 등장 순서는 자바스크립트 바인딩에서 프로퍼티 열거에 영향을 줍니다.

인터페이스딕셔너리와 달리, 인터페이스 믹스인은 타입을 생성하지 않습니다.

이 명세에서 정의된 확장 속성 중, [CrossOriginIsolated], [Exposed], [SecureContext] 만 인터페이스 믹스인에 적용됩니다.

includes 문은 (IncludesStatement에 일치) 모든 인터페이스 I (첫 번째 식별자로 식별됨)를 구현하는 객체가 멤버인터페이스 믹스인 M (두 번째 식별자로 식별됨)의 멤버를 추가로 포함해야 함을 선언하는 정의입니다. 인터페이스 Iinclude 인터페이스 믹스인 M을 포함한다고 합니다.

interface_identifier includes mixin_identifier;

첫 번째 식별자인터페이스 I를 참조해야 하며, 두 번째 식별자는 인터페이스 믹스인 M을 참조해야 합니다.

M의 각 멤버인터페이스 I, J, Kinclude하는 모든 인터페이스의 멤버로 간주됩니다. 즉, M의 멤버 m에 대해 I멤버 mI, J멤버 mJ, K멤버 mK를 갖게 됩니다. 호스트 인터페이스mI, mJ, mK의 각각의 I, J, K를 말합니다.

참고: 자바스크립트에서는, 인터페이스 믹스인 멤버로 선언된 일반 연산내장 함수 객체 값의 데이터 속성으로 노출될 때, 각 인터페이스 프로토타입 객체마다 별도 내장 함수 객체가 생성됩니다. 속성도 마찬가지로 접근자 속성의 getter와 setter가 각각 별도 내장 함수 객체가 됩니다.

includes 문의 등장 순서는 호스트 인터페이스에서 인터페이스 믹스인이 포함되는 순서에 영향을 줍니다.

멤버 순서는 명확히 규정되어 있지 않으며, 특히 인터페이스 믹스인이 별도 문서에 정의될 때 더욱 그렇습니다. issue #432에서 논의되고 있습니다.

이 명세에서 정의된 확장 속성 중 includes 문에 적용 가능한 것은 없습니다.

아래 IDL 프래그먼트인터페이스 Entry인터페이스 믹스인 Observable의 정의를 보여줍니다. includes 문Observable멤버들이 Entry를 구현하는 모든 객체에 항상 포함된다는 것을 명시합니다.

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

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

Entry includes Observable;

자바스크립트 구현에서는 모든 Entry의 프로토타입 체인에 addEventListener 속성이 있게 됩니다:

var e = getEntry();          // Entry 인스턴스 얻기
typeof e.addEventListener;   // "function"으로 평가됨
CallbackOrInterfaceOrMixin ::
    callback CallbackRestOrInterface
    interface InterfaceOrMixin
InterfaceOrMixin ::
    InterfaceRest
    MixinRest
Partial ::
    partial PartialDefinition
PartialDefinition ::
    interface PartialInterfaceOrPartialMixin
    PartialDictionary
    Namespace
MixinRest ::
    mixin identifier { MixinMembers } ;
MixinMembers ::
    ExtendedAttributeList MixinMember MixinMembers
    ε
MixinMember ::
    Const
    RegularOperation
    Stringifier
    OptionalReadOnly AttributeRest
IncludesStatement ::
    identifier includes identifier ;

2.3.1. 믹스인 및 부분 사용

이 섹션은 참고용입니다.

인터페이스 믹스인속성, 상수, 연산여러 인터페이스에 공유할 수 있게 해줍니다. 만약 하나의 인터페이스만 확장하려는 경우라면 부분 인터페이스 사용을 고려할 수 있습니다.

예를 들면, 다음과 같이 하지 말고:

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

이렇게 하세요:

partial interface Window {
  readonly attribute Storage sessionStorage;
};

또한, 다른 명세에서 노출하는 인터페이스 믹스인을 확장하여 window와 worker 등 여러 컨텍스트에 속성, 상수, 연산을 노출하는 등 공통적인 활용 사례를 타겟할 수도 있습니다.

예를 들어, 흔하지만 장황한 방식 대신:

interface mixin GlobalCrypto {
  readonly attribute Crypto crypto;
};

Window includes GlobalCrypto;
WorkerGlobalScope includes GlobalCrypto;

WindowOrWorkerGlobalScope 인터페이스 믹스인부분 인터페이스 믹스인으로 확장할 수 있습니다:

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

2.4. 콜백 인터페이스

콜백 인터페이스정의로, callback interface identifier { CallbackInterfaceMembers } ;에 일치합니다. § 2.12 인터페이스를 구현하는 객체에서 설명한 대로, 어떤 객체든 구현할 수 있습니다.

참고: 콜백 인터페이스인터페이스가 아닙니다. 명칭과 문법은 표준의 이전 버전에서 유래된 것으로, 당시에는 개념적으로 더 많은 공통점이 있었습니다.

콜백 인터페이스콜백 인터페이스 멤버 (CallbackInterfaceMembers에 일치)의 집합을 명세합니다. 이들은 인터페이스 선언의 중괄호 사이에 등장하는 멤버입니다.

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

참고: 유사한 명칭의 콜백 함수 정의도 참고하세요.

콜백 인터페이스는 정확히 하나의 일반 연산을 정의해야 합니다.

명세 저자는 콜백 인터페이스를 기존 API의 요구사항을 기술할 필요가 없는 한 정의하지 않아야 합니다. 대신 콜백 함수를 사용하는 것이 좋습니다.

EventListener콜백 인터페이스로 정의한 것은, 특정 속성(여기서는 handleEvent)을 가진 객체가 해당 인터페이스를 구현한 것으로 간주될 수 있도록 해야 하는 기존 API의 예입니다. 새로운 API나 호환성 문제가 없는 경우에는, 콜백 함수를 사용하면 자바스크립트 바인딩에서 함수 객체만 허용됩니다.

콜백 인터페이스상수를 선언하는 경우 반드시 [Exposed] 확장 속성으로 주석 처리해야 합니다.

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

2.5. 멤버

인터페이스, 인터페이스 믹스인, 네임스페이스는 중괄호 안에 등장하는 멤버(각각 InterfaceMembers, MixinMembers, NamespaceMembers에 일치)을 명세합니다. 멤버에는 상수, 속성, 연산, 기타 선언이 있습니다. 속성은 해당 인터페이스, 인터페이스 믹스인, 네임스페이스를 구현하는 객체가 노출하는 상태를 설명하며, 연산은 객체에서 호출할 수 있는 동작을 설명합니다. 상수는 시스템 내 객체 사용자에게 편의를 제공하기 위한 이름 있는 상수 값을 선언합니다.

어떤 인터페이스인터페이스 믹스인include하면, 해당 인터페이스 믹스인의 멤버들도 인터페이스의 멤버로 간주됩니다. 반면, 상속받은 인터페이스 멤버는 해당 인터페이스의 멤버로 간주하지 않습니다.

여러 멤버에 대해 정의되는 생성자 단계, getter 단계, setter 단계, 메서드 단계는 해당 인터페이스 또는 인터페이스 믹스인 위에 정의된 멤버에서 this 값을 사용할 수 있습니다. 이는 멤버가 선언된 인터페이스 타입, 혹은 멤버가 선언된 인터페이스 믹스인을 include한 타입의 IDL 값입니다.

setter 단계에서는 지정된 값도 사용할 수 있는데, 이는 해당 속성이 선언된 타입의 IDL 값입니다.

인터페이스, 인터페이스 믹스인, 콜백 인터페이스, 네임스페이스는 각각 지원하는 멤버의 종류가 다르며, § 2.2 인터페이스, § 2.3 인터페이스 믹스인, § 2.4 콜백 인터페이스, § 2.6 네임스페이스에서 설명합니다. 아래 표는 이를 요약한 참고용 표입니다:

인터페이스 콜백 인터페이스 인터페이스 믹스인 네임스페이스
상수
일반 속성 오직 읽기 전용 속성만
정적 속성
일반 연산
문자열 변환자
특수 연산
정적 연산
이터러블 선언
비동기 이터러블 선언
maplike 선언
setlike 선언

2.5.1. 상수

상수는 (Const에 일치) 이름에 상수값을 바인딩하는 선언입니다. 상수는 인터페이스콜백 인터페이스에 등장할 수 있습니다.

상수는 과거에 주로 열거형 스타일로 명명된 정수 코드를 정의하는 데 사용되었습니다. 웹 플랫폼은 문자열 사용으로 이 패턴에서 벗어나고 있습니다. 이 기능을 사용하려는 편집자는 진행하기 전에 이슈를 등록하여 논의할 것을 강력히 권고합니다.

const type constant_identifier = 42;

상수식별자는 동일한 인터페이스 멤버 또는 콜백 인터페이스 멤버의 식별자와 같아서는 안 됩니다(동일한 인터페이스콜백 인터페이스에 정의된). 또한 "length", "name", "prototype"이어서는 안 됩니다.

참고: 이 세 이름은 자바스크립트 바인딩에서 인터페이스 객체에 정의된 프로퍼티 이름입니다.

상수의 타입(ConstType에 일치)은 원시 타입이어야 하며, 그 외 타입은 허용되지 않습니다. 식별자가 사용되는 경우, 해당 식별자는 원시 타입인 타입 정의를 참조해야 합니다.

상수 선언의 ConstValue 부분은 상수의 값을 나타내며, 두 개의 불리언 리터럴 토큰(true, false), integer 토큰, decimal 토큰, 또는 세 가지 특수 부동소수점 상수값(-Infinity, Infinity, NaN) 중 하나일 수 있습니다.

참고: 이 값들은(문자열, 빈 시퀀스 포함) 딕셔너리 멤버의 기본값이나 옵션 인자 기본값으로도 사용할 수 있습니다. 단, 문자열, 빈 시퀀스 [], 기본 딕셔너리 {}상수의 값으로 사용할 수 없습니다.

불리언 리터럴 토큰 truefalse의 값은 IDL boolean 타입의 truefalse입니다.

integer 토큰의 값은 다음과 같이 결정된 정수입니다:

  1. Sinteger 토큰에 일치하는 스칼라 값의 시퀀스로 둡니다.

  2. S가 U+002D(-)로 시작하면 sign는 −1, 그렇지 않으면 1입니다.

  3. 선택적 U+002D(-) 뒤의 스칼라 값에 따라 base를 결정합니다:

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

    base는 16입니다.

    U+0030 (0)

    base는 8입니다.

    기타

    base는 10입니다.

  4. 남은 스칼라 값을 base base로 해석한 결과를 number로 둡니다.

  5. sign × number를 반환합니다.

integer 토큰의 타입은 사용되는 상수, 딕셔너리 멤버, 옵션 인자의 타입과 동일합니다. 해당 토큰의 값은 § 2.13 타입에서 주어진 타입의 유효 범위를 벗어나면 안 됩니다.

decimal 토큰의 값은, 해당 상수, 딕셔너리 멤버, 옵션 인자가 float, unrestricted float, double, unrestricted double 타입 중 무엇인지에 따라 IEEE 754 단정밀도 또는 배정밀도 부동소수점 숫자가 됩니다:
  1. Sdecimal 토큰에 일치하는 스칼라 값의 시퀀스로 둡니다.

  2. S를 자바스크립트 NumericLiteral로 파싱했을 때의 수학적 값을 result로 둡니다.

  3. 해당 토큰이 float 또는 unrestricted float의 값으로 사용되면, result에 가장 가까운 IEEE 754 단정밀도 부동소수점 숫자가 값입니다.

  4. 그 외에는 double 또는 unrestricted double의 값으로 사용되며, result에 가장 가까운 IEEE 754 배정밀도 부동소수점 숫자가 값입니다. [IEEE-754]

상수값이 Infinity, -Infinity, NaN로 지정된 경우, 상수, 딕셔너리 멤버, 옵션 인자의 타입에 따라 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

값은 비트 패턴 0x7fc00000의 IEEE 754 단정밀도 NaN입니다.

타입 unrestricted double, 상수값 NaN

값은 비트 패턴 0x7ff8000000000000의 IEEE 754 배정밀도 NaN입니다.

decimal 토큰의 타입은 사용되는 상수, 딕셔너리 멤버, 옵션 인자의 타입과 동일합니다. 해당 토큰의 값은 § 2.13 타입에서 주어진 타입의 유효 범위를 벗어나면 안 됩니다. 또한, Infinity, -Infinity, NaNfloatdouble 타입의 값으로 사용할 수 없습니다.

null 토큰의 값은 null 값이며, 널 허용 타입의 멤버입니다. null 토큰의 타입은 해당 상수, 딕셔너리 멤버, 옵션 인자의 타입과 동일합니다.

상수에 할당된 값의 타입 VT와 상수, 딕셔너리 멤버, 옵션 인자 자체의 타입 DT는 호환되어야 하며, DTVT가 동일하거나, DT널 허용 타입이고 내부 타입VT인 경우에 해당합니다.

상수는 해당 인터페이스 또는 콜백 인터페이스의 특정 인스턴스와 연결되지 않습니다. 인스턴스에서 상수가 노출되는지 여부는 언어 바인딩에 따라 다릅니다.

자바스크립트 바인딩에서는 해당 IDL 인터페이스를 구현하는 객체를 통해 상수에 접근할 수 있습니다. 예를 들어, 다음과 같은 IDL에서:

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

상수값은 자바스크립트에서 A.rambaldi 또는 instanceOfA.rambaldi로 접근할 수 있습니다.

상수에 적용 가능한 확장 속성은 다음과 같습니다: [CrossOriginIsolated], [Exposed], [SecureContext].

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

아래 IDL 프래그먼트는 위의 타입의 상수가 어떻게 정의될 수 있는지 보여줍니다.

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

2.5.2. 속성

속성인터페이스 멤버 또는 네임스페이스 멤버로, (inherit AttributeRest, static OptionalReadOnly AttributeRest, stringifier OptionalReadOnly AttributeRest, OptionalReadOnly AttributeRest, 또는 AttributeRest에 일치) 주어진 타입과 식별자를 가진 데이터 필드를 선언하며, 해당 값은 조회되거나(일부 경우) 변경될 수 있습니다. 속성에는 두 가지 종류가 있습니다:

  1. 일반 속성은 해당 인터페이스를 구현하는 객체가 지정된 식별자의 데이터 필드 멤버를 갖도록 선언합니다.

    interface interface_identifier {
      attribute type identifier;
    };
    
  2. 정적 속성은 인터페이스를 구현하는 특정 객체와 관련되지 않은 속성을 선언할 때 사용합니다.

    interface interface_identifier {
      static attribute type identifier;
    };
    

속성에 static 키워드가 없으면 일반 속성을 선언한 것이고, 있으면 정적 속성을 선언한 것입니다. 참고로 인터페이스 멤버 외에도, 읽기 전용 일반 속성네임스페이스 멤버가 될 수도 있습니다.

속성 attrgetter 단계는 “attr getter 단계는 다음과 같다:”(목록) 또는 “attr getter 단계는 다음을 수행한다”(인라인 설명)와 같은 텍스트로 소개해야 합니다.

속성 attrsetter 단계는 “attr setter 단계는 다음과 같다:”(목록) 또는 “attr setter 단계는 다음을 수행한다”(인라인 설명)와 같은 텍스트로 소개해야 합니다.

참고: getter 단계를 정의할 때는 this에 암묵적으로 접근할 수 있습니다. setter 단계를 정의할 때는 this지정된 값에 암묵적으로 접근할 수 있습니다.

속성식별자는 동일한 인터페이스에 정의된 다른 인터페이스 멤버의 식별자와 같아서는 안 됩니다. 정적 속성의 식별자는 "prototype"이면 안 됩니다.

속성의 타입은 attribute 키워드 뒤에 등장하는 타입(Type에 일치)으로 정해집니다. 만약 Type식별자거나 식별자 다음에 ?가 붙은 경우, 해당 식별자는 인터페이스, 열거형, 콜백 함수, 콜백 인터페이스, 타입 정의를 식별해야 합니다.

타입 정의를 해석한 후, 속성의 타입은 다음 타입의 널 허용 또는 비허용 버전이 되어서는 안 됩니다:

속성은 읽기 전용이며, readonly 키워드가 attribute 키워드 앞에 있으면 그렇게 됩니다. 읽기 전용 속성이 정의된 인터페이스를 구현하는 객체는 해당 속성에 값을 할당할 수 없습니다. 언어 바인딩마다 할당이 단순히 금지되는지, 무시되는지, 예외가 발생하는지 다를 수 있습니다.

interface interface_identifier {
  readonly attribute type identifier;
};

타입이 프라미스 타입인 속성은 반드시 읽기 전용이어야 하며, 또한 [LegacyLenientSetter], [PutForwards], [Replaceable], [SameObject] 확장 속성을 가질 수 없습니다.

읽기 전용이 아닌 일반 속성은 상위 인터페이스에서 getter를 상속받도록 선언할 수 있습니다. 이를 통해 상위 인터페이스의 읽기 전용 속성을 파생 인터페이스에서 쓰기 가능하게 만들 수 있습니다. 속성이 getter를 상속하려면 선언에 inherit이 포함되어야 합니다. getter를 상속받는 속성은 가장 가까운 상위 인터페이스에서 동일한 식별자를 가진 속성입니다. getter를 상속받는 속성과 상속하는 속성의 타입은 같아야 합니다.

참고: 문법상 inherit읽기 전용 속성이나 정적 속성에 사용할 수 없습니다.

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

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

stringifier 키워드가 일반 속성 선언에 사용되면, 해당 인터페이스를 구현하는 객체가 해당 속성 값으로 문자열 변환됨을 의미합니다. 자세한 내용은 § 2.5.5 문자열 변환자를 참조하세요.

interface interface_identifier {
  stringifier attribute DOMString identifier;
};

다음 확장 속성은 일반 및 정적 속성에 적용 가능합니다: [CrossOriginIsolated], [Exposed], [SameObject], [SecureContext].

다음 확장 속성은 일반 속성에만 적용됩니다: [LegacyLenientSetter], [LegacyLenientThis], [PutForwards], [Replaceable], [LegacyUnforgeable].

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

아래 IDL 프래그먼트인터페이스속성을 선언하는 방법을 보여줍니다:

[Exposed=Window]
interface Animal {

  // 임의의 문자열 값으로 설정 가능한 단순 속성.
  readonly attribute DOMString name;

  // 값을 할당할 수 있는 속성.
  attribute unsigned short age;
};

[Exposed=Window]
interface Person : Animal {

  // Animal에서 getter 동작을 상속받으며, Person 설명에서 별도 명시 필요 없음.
  inherit attribute DOMString name;
};

2.5.3. 연산

연산인터페이스 멤버, 콜백 인터페이스 멤버, 네임스페이스 멤버 (static RegularOperation, stringifier, RegularOperation 또는 SpecialOperation에 일치) 해당 인터페이스를 구현하는 객체에서 호출할 수 있는 동작을 정의합니다. 연산에는 세 가지 종류가 있습니다:

  1. 일반 연산은 해당 인터페이스를 구현하는 객체가 지정된 식별자의 메서드를 갖도록 선언합니다.

    interface interface_identifier {
      return_type identifier(/* arguments... */);
    };
    
  2. 특수 연산은 객체 인덱싱, 문자열 변환 등 특별한 동작을 구현하는 객체에 선언할 때 사용합니다.

    interface interface_identifier {
      /* special_keyword */ return_type identifier(/* arguments... */);
      /* special_keyword */ return_type (/* arguments... */);
    };
    
  3. 정적 연산은 인터페이스를 구현하는 특정 객체와 관련되지 않은 연산을 선언할 때 사용합니다.

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

연산에 식별자가 있고 static 키워드가 없으면 일반 연산을 선언한 것입니다. 연산에 선언에 특수 키워드(Special에 일치하는 키워드 또는 stringifier 키워드)가 있으면 특수 연산을 선언합니다. 하나의 연산이 일반 연산과 특수 연산을 동시에 선언할 수도 있습니다. 자세한 내용은 § 2.5.6 특수 연산을 참조하세요. 참고로, 일반 연산은 인터페이스 멤버 외에도, 콜백 인터페이스 멤버네임스페이스 멤버가 될 수 있습니다.

연산에 식별자가 없으면 반드시 특수 키워드를 사용하여 특수 연산으로 선언해야 합니다.

일반 연산 또는 정적 연산의 식별자는 동일한 인터페이스, 콜백 인터페이스, 네임스페이스에 정의된 상수속성의 식별자와 같아서는 안 됩니다. 정적 연산의 식별자는 "prototype"이면 안 됩니다.

참고: 연산의 식별자는 동일 인터페이스의 다른 연산과 같을 수 있습니다. 이는 연산 오버로딩을 명세하는 방식입니다.

참고: 정적 연산의 식별자는 동일 인터페이스에 정의된 일반 연산의 식별자와 같을 수 있습니다.

연산의 반환 타입은 연산 선언에서 식별자 앞에 등장하는 타입(Type에 일치)으로 정해집니다. 반환 타입이 ?가 붙은 식별자인 경우, 해당 식별자는 인터페이스, 딕셔너리, 열거형, 콜백 함수, 콜백 인터페이스, 타입 정의를 식별해야 합니다.

연산의 인자(ArgumentList에 일치)는 선언의 괄호 사이에 명시됩니다. 각 인자는 타입(Type에 일치) 뒤에 식별자(ArgumentName에 일치)로 지정합니다.

참고: 표현력을 위해, 연산 인자의 식별자는 ArgumentNameKeyword 심볼에 일치하는 키워드 중 하나로 지정할 수 있으며, 이 경우 이스케이프할 필요가 없습니다.

연산 인자의 Type?가 붙은 식별자인 경우, 해당 식별자는 인터페이스, 열거형, 콜백 함수, 콜백 인터페이스, 타입 정의를 식별해야 합니다. ?가 없는 식별자 타입인 경우, 해당 식별자는 위의 정의들 중 하나 또는 딕셔너리를 식별해야 합니다.

인자 타입을 타입 정의 해석 후, 널 허용 타입(nullable type)이면, 그 내부 타입딕셔너리 타입일 수 없습니다.

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

각 인자의 식별자는 동일 연산 선언 내의 다른 인자 식별자와 같아서는 안 됩니다.

각 인자는 확장 속성 리스트(ExtendedAttributeList에 일치)가 앞에 올 수 있으며, 이는 해당 인자 값이 언어 바인딩에서 어떻게 처리되는지 제어합니다.

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

아래 IDL 프래그먼트인터페이스일반 연산을 선언하는 방법을 보여줍니다:

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

[Exposed=Window]
interface Button {

  // 인자를 받지 않고 불리언을 반환하는 연산.
  boolean 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 프래그먼트는 두 개의 가변 인자 연산을 가진 인터페이스를 정의합니다:

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

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

자바스크립트 바인딩에서 가변 인자 연산은 추가 인자를 받을 수 있는 함수로 구현됩니다:

var s = getIntegerSet();  // IntegerSet 인스턴스 얻기

s.union();                // 'ints'에 해당하는 인자를 안 넘김
s.union(1, 4, 7);         // 'ints'에 해당하는 인자를 세 개 넘김

가변 인자 함수를 지원하지 않는 언어 바인딩에서는 명시적으로 배열이나 리스트를 인자로 넘기도록 명세할 수 있습니다.

인자에 optional 키워드가 있으면 옵션 인자로 간주합니다. 가변 인자(variadic) 연산의 마지막 인자도 옵션 인자로 간주됩니다. 인자를 옵션으로 선언하면 연산 호출 시 해당 인자를 생략할 수 있습니다. 연산이 가변 인자일 때 마지막 인자는 명시적으로 옵션 인자로 선언할 수 없습니다.

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

옵션 인자는 기본값도 가질 수 있습니다. 인자 식별자 뒤에 U+003D(=)와 값(DefaultValue에 일치)이 오면, 그 값이 옵션 인자의 기본값이 됩니다. 가변 인자 연산의 마지막(암시적 옵션) 인자에는 기본값을 지정할 수 없습니다. 기본값은 해당 인자가 생략되어 호출될 때 적용됩니다.

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

boolean 타입의 옵션 인자에 true를 기본값으로 사용하는 것은 권장하지 않습니다. 저자는 기본 변환(즉 undefinedfalse)을 예상할 수 있으므로 혼동을 줄 수 있습니다. [API-DESIGN-PRINCIPLES]

인자 타입이 딕셔너리 타입 또는 유니온 타입이며, 해당 딕셔너리 타입 및 조상에 필수 멤버가 없고, 인자가 마지막이거나 뒤따르는 인자들이 모두 옵션 인자라면, 해당 인자는 옵션으로 선언되고 기본값을 지정해야 합니다.

이는 API 설계시 사용자가 딕셔너리의 기본값만 사용하고 싶을 때 빈 딕셔너리 값을 굳이 넘기지 않아도 되도록 하기 위함입니다.

대개 기본값으로 {}를 사용하지만, 유니온 타입에서 딕셔너리가 멤버 타입 중 하나라면 다른 멤버 초기화용 기본값을 지정할 수도 있습니다.

불리언 리터럴 토큰(true, false), null 토큰, integer 토큰, decimal 토큰, Infinity, -Infinity, NaN 중 하나가 옵션 인자 기본값으로 사용되면, 상수에 대해와 동일하게 해석합니다.

undefined 토큰이 옵션 인자 기본값으로 사용된 경우, 값은 IDL undefined입니다.

옵션 인자 기본값은 string 토큰으로도 지정할 수 있습니다. 은 아래와 같이 문자열 타입으로 결정됩니다:
  1. Sstring 토큰에서 양끝 U+0022(")를 제거한 후 남은 스칼라 값 시퀀스로 둡니다.

  2. 인자 타입에 따라:

    DOMString
    USVString
    열거형 타입

    string 토큰의 값은 S입니다.

    ByteString

    단, S에는 U+00FF를 초과하는 코드 포인트가 없어야 합니다.

    string 토큰의 값은 동형 인코딩S입니다.

옵션 인자의 타입이 열거형이면, 지정된 기본값은 반드시 해당 열거형 값 중 하나여야 합니다.

옵션 인자 기본값으로 두 토큰 값 []를 사용할 수 있으며, 이는 빈 시퀀스 값을 나타냅니다. 타입은 해당 옵션 인자의 타입과 동일해야 하며, 반드시 시퀀스 타입, 널 허용 타입 중 내부 타입이 시퀀스 타입인 것, 유니온 타입, 널 허용 유니온 타입시퀀스 타입평탄화된 멤버 타입 중 하나로 가져야 합니다.

옵션 인자 기본값으로 두 토큰 값 {}도 사용할 수 있으며, 이는 기본 초기화된(ES null 또는 속성이 없는 객체와 같이) 딕셔너리 값을 의미합니다. 타입은 해당 옵션 인자의 타입과 동일해야 하며, 반드시 딕셔너리 타입이거나 유니온 타입딕셔너리 타입평탄화된 멤버 타입 중 하나로 가져야 합니다.

아래 IDL 프래그먼트는 두 가지 인자 리스트 길이로 호출 가능한 단일 연산을 가진 인터페이스를 정의합니다:

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

이는 아래처럼 두 개의 오버로딩된 연산을 가진 것과 같습니다:

[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을 인자 하나만 넘겨 호출하면, 두 번째 인자는 기본 초기화된 LookupOptions 딕셔너리가 되며, caseSensitivefalse로 설정됩니다.

연산에 적용 가능한 확장 속성은 다음과 같습니다: [CrossOriginIsolated], [Default], [Exposed], [LegacyUnforgeable], [NewObject], [SecureContext].

연산 operation메서드 단계는 “operation(arg1, arg2, ...) 메서드 단계는 다음과 같다:”(목록) 또는 “operation(arg1, arg2, ...) 메서드 단계는 다음을 수행한다”(인라인 설명)와 같은 텍스트로 소개해야 합니다.

참고: 메서드 단계를 정의할 때는 this에 암묵적으로 접근할 수 있습니다.

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

toJSON 일반 연산을 선언함으로써, 인터페이스는 해당 인터페이스를 구현하는 객체를 JSON 타입으로 변환하는 방법을 명세합니다.

toJSON 일반 연산은 이러한 용도를 위해 예약되어 있습니다. 반드시 인자를 받지 않아야 하며, JSON 타입을 반환해야 합니다.

JSON 타입은 다음과 같습니다:

toJSON 일반 연산 이 객체에서 어떻게 노출되는지, 그리고 JSON 타입이 JSON 문자열로 변환되는 방식은 언어 바인딩에 따라 다릅니다.

참고: 자바스크립트 바인딩에서는, toJSON 메서드를 노출하여 JSON 타입을 자바스크립트 값으로 반환하고, JSON.stringify() 함수로 JSON 문자열로 변환할 수 있도록 합니다. 또한, 자바스크립트 바인딩에서 toJSON 연산에 [Default] 확장 속성을 사용할 수 있으며, 이 경우 기본 toJSON 단계가 대신 노출됩니다.

아래 IDL 프래그먼트Transaction 인터페이스에 toJSON 메서드를 프로즈로 정의한 예시입니다:

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

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

Transaction 인터페이스toJSON 일반 연산은 다음과 같이 정의할 수 있습니다:

toJSON() 메서드 단계는 다음과 같다:

  1. json을 새 으로둡니다.

  2. 속성 identifier attr에 대해 «"from", "to", "amount", "description"»:

    1. valuegetter 단계this에 대해 실행한 결과로 둡니다.

    2. json[attr]에 value를 설정합니다.

  3. json을 반환합니다.

자바스크립트 바인딩에서는 Transaction 객체에 toJSON() 메서드가 존재합니다:

// Transaction 인스턴스 얻기
var txn = getTransaction();

// 아래와 같은 객체로 평가됨:
// {
//   from: "Bob",
//   to: "Alice",
//   amount: 50,
//   description: "books"
// }
txn.toJSON();

// 아래와 같은 문자열로 평가됨:
// '{"from":"Bob","to":"Alice","amount":50,"description":"books"}'
JSON.stringify(txn);

2.5.4. 생성자 연산

인터페이스생성자 연산 멤버(Constructor에 일치)가 있으면, 해당 인터페이스를 구현하는 객체를 생성자를 통해 만들 수 있다는 뜻입니다.

하나의 인터페이스에는 여러 개의 생성자 연산이 있을 수 있습니다. 각각의 생성자 연산에 대해, 지정된 인자를 넘겨 인스턴스를 생성할 방법이 제공됩니다.

생성자 연산이 인터페이스 interface의 멤버일 때 생성자 단계는 “The new interface(arg1, arg2, ...) 생성자 단계는 다음과 같다:”(목록) 또는 “The new interface(arg1, arg2, ...) 생성자 단계는 다음을 수행한다”(인라인 설명)와 같은 텍스트로 소개해야 합니다.

생성자 단계는 아무 것도 하지 않거나, this에 전달된 값을 초기화하거나, 예외를 던질 수 있습니다.

생성자가 this를 초기화하지 않는 경우, “The new Example(init) 생성자 단계는 아무 것도 하지 않는다.”라고 쓸 수 있습니다.

§ 3.7.1 인터페이스 객체에서 생성자 연산이 어떻게 구현되는지 자세히 설명합니다.

아래 IDL은 두 개의 인터페이스를 정의합니다. 두 번째 인터페이스에는 생성자 연산이 있지만, 첫 번째에는 없습니다.

[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;
};

이 인터페이스들을 지원하는 자바스크립트 구현에서는 Circle 인터페이스 객체에 [[Construct]] 내부 메서드를 구현하며, 이를 통해 해당 인터페이스를 구현하는 새 객체를 반환합니다. 인자는 0개 또는 1개를 받을 수 있습니다.

NodeList 인터페이스 객체가 [[Construct]] 내부 메서드를 구현하는지는 명확하지 않습니다. 어쨌든 이를 생성자로 사용하려 하면 TypeError가 발생합니다. [whatwg/webidl Issue #698]

var x = new Circle();      // 0개 인자 생성자로 Circle 인터페이스 구현 객체 생성
                           // 플랫폼 객체 참조 반환

var y = new Circle(1.25);  // 1개 인자 생성자로 Circle 객체 생성

var z = new NodeList();    // 생성자 선언이 없으므로 TypeError 발생
Constructor ::
    constructor ( ArgumentList ) ;
ArgumentList ::
    Argument Arguments
    ε
Arguments ::
    , Argument Arguments
    ε
Argument ::
    ExtendedAttributeList ArgumentRest
ArgumentRest ::
    optional TypeWithExtendedAttributes ArgumentName Default
    Type Ellipsis ArgumentName
ArgumentName ::
    ArgumentNameKeyword
    identifier
Ellipsis ::
    ...
    ε
ArgumentNameKeyword ::
    attribute
    callback
    const
    constructor
    deleter
    dictionary
    enum
    getter
    includes
    inherit
    interface
    iterable
    maplike
    mixin
    namespace
    partial
    readonly
    required
    setlike
    setter
    static
    stringifier
    typedef
    unrestricted

2.5.5. 문자열 변환자

인터페이스문자열 변환자가 있으면, 해당 인터페이스를 구현하는 객체가 기본값이 아닌 문자열 변환(conversion)을 갖는다는 의미입니다. 문자열 변환자는 stringifier 키워드로 지정할 수 있으며, 단독으로 사용될 경우 문자열 변환 연산을 만듭니다.

interface interface_identifier {
  stringifier;
};

인터페이스와 함께 설명되는 프로즈(prose)에서는 해당 인터페이스의 문자열 변환 동작을 정의해야 합니다.

stringifier 키워드는 속성에도 사용할 수 있습니다. 이 경우, 객체를 문자열로 변환할 때 사용할 값은 해당 속성의 값입니다. stringifier 키워드는 반드시 DOMString 또는 USVString 타입의 속성에만 사용할 수 있습니다. 또한 정적 속성에는 사용할 수 없습니다.

interface interface_identifier {
  stringifier attribute DOMString identifier;
};

특정 인터페이스에는 문자열 변환자가 최대 하나만 존재해야 합니다.

Stringifier ::
    stringifier StringifierRest
StringifierRest ::
    OptionalReadOnly AttributeRest
    ;

아래 IDL 프래그먼트name 속성 값으로 문자열 변환되는 인터페이스를 정의합니다:

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

자바스크립트 바인딩에서 Student 객체를 문자열이 필요한 곳에서 사용하면 객체의 name 속성 값이 사용됩니다:

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

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

아래 IDL 프래그먼트는 IDL 자체에 명시되지 않은 커스텀 문자열 변환 동작을 가진 인터페이스를 정의합니다.

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

  stringifier;
};

따라서 문자열 변환 동작을 설명하는 프로즈가 필요합니다. familyNamegivenName 속성은 각각 성과 이름 개념을 나타낸다고 가정합니다.

문자열 변환 동작 단계는 다음과 같다:

  1. this의 family name이 null이면, this의 given name을 반환한다.

  2. this의 given name, U+0020 SPACE, this의 family name을 순서대로 이어붙여 반환한다.

이 IDL의 자바스크립트 구현 동작 예시는 다음과 같습니다:

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

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

2.5.6. 특수 연산

특수 연산은 해당 인터페이스를 구현하는 객체에 특정 종류의 특별한 동작을 선언하는 것입니다. 특수 연산은 연산 선언에 특수 키워드를 사용해 선언합니다.

특수 연산에는 세 가지 종류가 있습니다. 아래 표는 각 특수 연산의 종류별로 사용되는 특수 키워드와 그 목적을 나타냅니다:

특수 연산 키워드 목적
Getter getter 객체가 프로퍼티 조회를 위해 인덱싱될 때 동작을 정의합니다.
Setter setter 객체가 프로퍼티 할당 또는 생성 시 인덱싱될 때 동작을 정의합니다.
Deleter deleter 객체가 프로퍼티 삭제를 위해 인덱싱될 때 동작을 정의합니다.

모든 언어 바인딩이 네 가지 종류의 특수 객체 동작을 모두 지원하는 것은 아닙니다. 특수 연산이 식별자 없이 선언된 경우, 해당 종류의 특수 연산을 지원하지 않는 언어 바인딩에서는 해당 기능이 제공되지 않습니다.

아래 IDL 프래그먼트는 getter와 setter가 있는 인터페이스를 정의합니다:

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

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

프로퍼티 getter와 setter를 지원하지 않는 언어 바인딩에서는, Dictionary를 구현하는 객체가 해당 특별 동작을 갖지 않습니다.

특수 연산을 식별자를 사용해 정의하는 것은, 해당 특수 연산을 식별자 없이 별도의 선언으로 분리하는 것과 동등합니다. 이 방식은 인터페이스 연산의 메서드 단계를 단순화하기 위해 허용됩니다.

다음 두 인터페이스는 동등합니다:

[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);
};

특정 특수 키워드는 연산에서 두 번 이상 등장해서는 안 됩니다.

Getter와 setter에는 두 가지 종류가 있습니다: DOMString을 프로퍼티 이름으로 받는 이름 있는 프로퍼티 getter이름 있는 프로퍼티 setter가 있고, unsigned long을 프로퍼티 인덱스로 받는 인덱스 프로퍼티 getter인덱스 프로퍼티 setter가 있습니다. deleter는 한 종류만 있습니다: 이름 있는 프로퍼티 deleter. 자세한 내용은 § 2.5.6.1 인덱스 프로퍼티§ 2.5.6.2 이름 프로퍼티를 참조하세요.

특정 인터페이스에는 이름 있는 프로퍼티 deleter가 최대 하나, getter와 setter의 각 종류도 최대 하나만 존재해야 합니다.

인터페이스에 특정 종류의 setter가 있으면 반드시 같은 종류의 getter도 있어야 합니다. 이름 있는 프로퍼티 deleter가 있으면, 반드시 이름 있는 프로퍼티 getter도 있어야 합니다.

연산으로 선언된 특수 연산은 가변 인자(variadic)가 아니어야 하며, 옵션 인자를 가질 수 없습니다.

객체가 두 개 이상의 인터페이스를 구현하며, 동일한 특수 연산을 정의한다면, 실제 어떤 특수 연산이 호출되는지는 정의되지 않습니다.

2.5.6.1. 인덱스 프로퍼티

인덱스 프로퍼티 getter를 정의한 인터페이스인덱스 프로퍼티를 지원한다고 한다. 확장해서, 플랫폼 객체가 인덱스 프로퍼티를 지원한다고 하려면 해당 객체가 인덱스 프로퍼티를 지원하는 인터페이스를 구현하면 된다.

인터페이스가 인덱스 프로퍼티를 지원하면, 인터페이스 정의에는 객체가 언제든지 어떤 인덱스로 인덱싱될 수 있는지 기술이 포함되어야 한다. 이 인덱스들을 지원되는 프로퍼티 인덱스라고 한다.

인덱스 프로퍼티를 지원하는 인터페이스는 "length"라는 정수형 속성을 정의해야 한다.

인덱스 프로퍼티 getter는 반드시 unsigned long 하나의 인자를 받아야 한다. 인덱스 프로퍼티 setter는 반드시 두 개의 인자를 받아야 하며, 첫 번째 인자는 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);
};

인덱스 프로퍼티 getter와 setter 정의에는 다음 요구 사항이 적용된다:

인덱스 프로퍼티 getter나 setter가 연산에 식별자를 써서 지정된 경우, 객체를 정수로 인덱싱할 때(지원되는 프로퍼티 인덱스가 아닌 경우) 해당 연산을 해당 인덱스로 호출하는 것과 같은 동작을 반드시 하지는 않는다. 실제 동작은 언어 바인딩마다 다르다.

자바스크립트 바인딩에서는 일반 프로퍼티 조회가 실행된다. 예를 들어, 아래 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() 연산이 존재하지 않는 항목을 조회할 때 null을 반환하도록 정의된 경우, 아래 두 문장으로 충분합니다:

OrderedMap을 구현하는 객체 map은 0 ≤ index < map.size 범위의 인덱스 프로퍼티를 지원한다.

또한, get()에 넘겼을 때 null이 아닌 값을 반환하는 모든 이름에 대해 이름 프로퍼티도 지원한다.

§ 3.9 레거시 플랫폼 객체에서 설명한 대로, 자바스크립트 구현에서는 레거시 플랫폼 객체OrderedMap 인터페이스의 이름/인덱스 프로퍼티에 해당하는 프로퍼티가 생성된다. 이 프로퍼티들은 객체의 메서드를 호출하는 것과 동일하게 상호작용할 수 있으며, 아래 예시처럼 사용할 수 있습니다:

// map은 OrderedMap 인터페이스를 구현하는 레거시 플랫폼 객체라고 가정
var map = getOrderedMap();
var x, y;

x = map[0];       // map.length > 0이면 아래와 동등:
                  // x = map.getByIndex(0)
                  // 즉, map에 "0"이라는 프로퍼티가 있으므로
                  // 그렇지 않으면 x는 undefined

map[1] = false;   // 아래와 동등:
                  // map.setByIndex(1, false)

y = map.apple;    // apple이라는 이름 프로퍼티가 있으면 아래와 동등:
                  // y = map.get('apple')
                  // 없으면 y는 undefined

map.berry = 123;  // 아래와 동등:
                  // map.set('berry', 123)

delete map.cake;  // cake라는 이름 프로퍼티가 있으면 해당 프로퍼티 삭제 후 아래 동등:
                  // map.remove("cake")
2.5.6.2. 이름 프로퍼티

이름 프로퍼티 getter를 정의한 인터페이스이름 프로퍼티를 지원한다고 한다. 확장해서, 플랫폼 객체가 이름 프로퍼티를 지원한다고 하려면 해당 객체가 이름 프로퍼티를 지원하는 인터페이스를 구현하면 된다.

인터페이스가 이름 프로퍼티를 지원하면, 인터페이스 정의에는 객체를 언제든지 어떤 이름으로 인덱싱할 수 있는지(순서가 있는 이름 집합) 기술이 포함되어야 한다. 이 이름들을 지원되는 프로퍼티 이름이라고 한다.

이름 프로퍼티 getter와 deleter는 반드시 DOMString 하나의 인자를 받아야 한다. 이름 프로퍼티 setter는 반드시 두 개의 인자를 받아야 하며, 첫 번째 인자는 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);
};

이름 프로퍼티 getter, setter, deleter 정의에는 다음 요구 사항이 적용된다:

참고: 인덱스 프로퍼티와 마찬가지로, 이름 프로퍼티 getter, setter 또는 deleter 가 연산에 식별자를 써서 지정된 경우, 객체를 지원되지 않는 이름으로 인덱싱할 때 해당 연산을 해당 이름으로 호출하는 것과 반드시 같은 동작을 하는 것은 아니며, 실제 동작은 언어 바인딩마다 다릅니다.

2.5.7. 정적 속성 및 연산

정적 속성정적 연산 은 해당 인터페이스의 특정 인스턴스가 아니라 인터페이스 자체에 연결되는 속성/연산입니다. 정적 속성과 연산은 선언에 static 키워드를 사용해 지정합니다.

정적 연산을 호출하거나 정적 속성을 참조하는 것이 인터페이스 인스턴스에서 가능한지는 언어 바인딩마다 다릅니다.

StaticMember ::
    static StaticMemberRest
StaticMemberRest ::
    OptionalReadOnly AttributeRest
    RegularOperation

아래 IDL 프래그먼트Circle 인터페이스에 정적 연산이 선언된 예시입니다:

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

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

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

자바스크립트 바인딩에서는 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;               // 이 역시 undefined
circles[0].triangulationCount;        // 이것도 undefined

// 정적 연산 호출
var triangulationPoint = Circle.triangulate(circles[0], circles[1], circles[2]);

// 수행한 삼각분할 개수 확인
window.alert(Circle.triangulationCount);

2.5.8. 오버로딩

인터페이스에 정의된 일반 연산 또는 정적 연산이 동일한 종류(일반 또는 정적)의 다른 연산과 동일한 식별자를 가지면, 해당 연산은 오버로딩된 연산이라 한다. 오버로딩된 연산의 식별자가 인터페이스를 구현하는 객체에서 호출될 때, 전달된 인자의 개수와 타입에 따라 실제로 어떤 오버로딩된 연산이 호출되는지가 결정된다. 생성자 연산도 오버로딩될 수 있다. 오버로딩된 연산과 생성자가 받을 수 있는 인자에는 몇 가지 제한이 있으며, 이를 설명하기 위해 유효 오버로드 집합이라는 개념을 사용한다.

오버로딩된 연산 집합은 다음 중 하나를 만족해야 한다:

연산인터페이스, 부분 인터페이스, 인터페이스 믹스인, 부분 인터페이스 믹스인 정의를 넘나들어 오버로딩될 수 없다.

예를 들어, 아래의 fg에 대한 오버로딩은 허용되지 않는다:

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

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

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

참고로 생성자 연산과 [LegacyFactoryFunction] 확장 속성은 부분 인터페이스 정의에는 등장할 수 없으므로, 생성자 오버로딩을 추가로 금지할 필요는 없다.

유효 오버로드 집합은 특정 연산, 생성자(생성자 연산 또는 [LegacyFactoryFunction]), 또는 콜백 함수에 대해 허용되는 호출을 나타낸다. 유효 오버로드 집합 계산 알고리즘은 다음 네 가지 IDL 구조에 대해 동작하며, 각 구조마다 필요한 입력이 있다:

일반 연산의 경우
정적 연산의 경우
생성자의 경우
레거시 팩토리 함수의 경우

유효 오버로드 집합은 인터페이스에 지정된 오버로딩 연산과 생성자에 모호함이 있는지 판별하는 데 사용된다.

아이템들은 유효 오버로드 집합튜플로, (호출 객체, 타입 리스트, 옵셔널리티 리스트) 형태를 가진다. 아래에 각 아이템 설명:

튜플은 해당 타입의 인자값 리스트로 연산, 생성자, 콜백 함수를 호출할 수 있음을 의미한다. 옵션 인자가변 인자 연산/생성자 덕분에, 동일한 연산이나 생성자로 식별되는 유효 오버로드 집합 아이템이 여러 개 있을 수 있다.

아래 알고리즘은 유효 오버로드 집합 계산 방법을 설명한다. 다음 입력 변수들을 사용한다(필요한 경우):

확장 속성의 인자란, 확장 속성의 명명된 인자 리스트의 인자를 의미한다.

  1. S순서 있는 집합으로 둔다.

  2. F순서 있는 집합으로 둔다. 아이템은 유효 오버로드 집합 종류에 따라 다음과 같다:

    일반 연산의 경우

    F의 요소는 인터페이스 I에 정의된 A 식별자의 일반 연산이다.

    정적 연산의 경우

    F의 요소는 인터페이스 I에 정의된 A 식별자의 정적 연산이다.

    생성자의 경우

    F의 요소는 인터페이스 I생성자 연산이다.

    레거시 팩토리 함수의 경우

    F의 요소는 인터페이스 I에 정의된 [LegacyFactoryFunction] 확장 속성 중 명명된 인자 리스트의 식별자가 A인 것들이다.

  3. maxargF의 연산, 레거시 팩토리 함수, 콜백 함수에서 선언된 최대 인자 개수로 둔다. 가변 인자 연산 및 레거시 팩토리 함수에서, ...이 붙은 인자는 1개로 센다.

    참고: undefined f(long x, long... y);는 인자 2개로 간주된다.

  4. maxmax(maxarg, N)로 둔다.

  5. F의 연산 또는 확장 속성 X에 대해:

    1. argumentsX에 선언된 인자들의 리스트로 둔다.

    2. narguments크기로 둔다.

    3. types타입 리스트로 둔다.

    4. optionalityValues옵셔널리티 리스트로 둔다.

    5. argumentsargument에 대해:

      1. typesargument의 타입을 추가한다.

      2. optionalityValues에, argument가 마지막 가변 인자면 "variadic", 옵션 인자면 "optional", 그 외는 "required"를 추가한다.

    6. S에 (X, types, optionalityValues) 튜플을 추가한다.

    7. X가변 인자로 선언되었다면:

      1. i ∈ [n, max−1]:

        1. t타입 리스트로 둔다.

        2. o옵셔널리티 리스트로 둔다.

        3. j ∈ [0, n−1]:

          1. ttypes[j]를 추가한다.

          2. ooptionalityValues[j]를 추가한다.

        4. j ∈ [n, i]:

          1. ttypes[n−1]를 추가한다.

          2. o에 "variadic"을 추가한다.

        5. S에 (X, t, o) 튜플을 추가한다.

    8. in−1로 둔다.

    9. i ≥ 0인 동안:

      1. arguments[i]가 옵션 인자가 아니면 break.

      2. t타입 리스트로 둔다.

      3. o옵셔널리티 리스트로 둔다.

      4. j ∈ [0, i−1]:

        1. ttypes[j]를 추가한다.

        2. ooptionalityValues[j]를 추가한다.

      5. S에 (X, t, o) 튜플을 추가한다.

        참고: i가 0이면 S에 (X, « », « ») (여기서 "« »"는 빈 리스트)를 추가한다는 뜻이다.

      6. ii−1로 둔다.

  6. S를 반환한다.

다음 인터페이스에 대해:

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

NodeEvent가 서로 다른 인터페이스이며, 어떤 객체도 둘 다를 구현할 수 없다면, 식별자 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 »)
»

두 타입이 구별 가능하다는 것은 다음 알고리즘이 true를 반환하는 경우이다.

  1. 한 타입이 널 허용 타입을 포함하고, 다른 타입이 널 허용 타입을 포함하거나, 유니온 타입이며 평탄화된 멤버 타입딕셔너리 타입이 포함되거나, 딕셔너리 타입이면, false를 반환한다.

    아래 쌍들은 구별 불가능하다:
  2. 두 타입 모두 유니온 타입 또는 널 허용 유니온 타입이면, 각 멤버 타입이 서로 구별 가능하면 true, 아니면 false를 반환한다.

  3. 한 타입이 유니온 타입 또는 널 허용 유니온 타입이면, 유니온 타입의 각 멤버 타입이 비유니온 타입과 구별 가능하면 true, 아니면 false를 반환한다.

  4. 각 타입의 내부 타입(주석 타입이면)과 내부 타입(그 결과가 널 허용 타입이면)을 취한 "가장 안쪽" 타입을 고려한다. 이 두 타입이 아래 표의 카테고리에 속하고, 해당 교차점에 ● 또는 지정된 조건(a, b, c, d)이 만족되면 true, 아니면 false를 반환한다.

    카테고리:

    interface-like
    dictionary-like
    sequence-like
    undefined
    boolean
    numeric types
    bigint
    string types
    object
    symbol
    interface-like
    callback function
    dictionary-like
    async sequence
    sequence-like
    undefined
    boolean
    numeric types (b)
    bigint
    string types (d)
    object
    symbol
    interface-like (a)
    callback function (c)
    dictionary-like
    async sequence
    sequence-like
    1. 식별된 두 interface-like 타입이 서로 다르고, 어떤 플랫폼 객체도 두 타입을 모두 구현하지 않는다.

    2. 타입이 구별 가능하지만, 오버로딩에서 사용에 별도의 제한이 있다. 또한 이 타입의 유니온 사용에 관한 조언도 참고할 것.

    3. [LegacyTreatNonObjectAsNull] 확장 속성이 없는 콜백 함수는 dictionary-like 카테고리 타입과 구별 가능하다.

      예를 들어, ECMAScript 값을 콜백 함수와 딕셔너리-like 타입을 포함하는 유니온 타입으로 변환할 때, 값이 호출 가능이면 콜백 함수로, 아니면 딕셔너리-like 타입으로 변환된다.
    4. 타입이 구별 가능하지만, ECMAScript 값 변환 시 문자열 객체비동기 시퀀스 타입으로 변환되지 않는다(해당 타입의 오버로드나 유니온이 있으면).

    doubleDOMString숫자 타입문자열 타입 교차점에 ●이 있으므로 구별 가능하다.
    doublelong은 모두 숫자 타입이므로, 숫자 타입 교차점에 ●이나 문자가 없으므로 구별 불가능하다.
    다음과 같을 때:
    callback interface CBIface {
        undefined handle();
    };
    
    [Exposed=Window]
    interface Iface {
        attribute DOMString attr2;
    };
    
    dictionary Dict {
        DOMString field1;
    };
    

    CBIfaceIface와는 구별 가능하다(딕셔너리-like와 인터페이스-like 교차점에 ●이 있음). 하지만 Dict와는 구별 불가능하다(딕셔너리-like 교차점에 ● 없음).

    프라미스 타입은 위 표에 없으므로, 어떤 다른 타입과도 구별 불가능하다.

하나의 항목 이상이 주어진 효과적 오버로드 집합에 있고, 해당 항목들이 같은 타입 리스트 크기를 가진 경우, 그러한 항목들에 대해 어떤 인덱스 i가 존재해야 하며, 각 항목 쌍에 대해 인덱스 i의 타입들이 구별 가능해야 합니다. 이러한 최소 인덱스를 해당 타입 리스트 크기를 가진 효과적 오버로드 집합의 항목에 대한 구별 인자 인덱스라고 합니다.

하나의 효과적 오버로드 집합에는 같은 항목이 동일한 타입 리스트 크기를 가질 때, 하나의 항목bigint 인자를 구별 인자 인덱스에서 가지며, 다른 항목이 숫자 타입 인자를 동일한 구별 인자 인덱스에서 갖는 경우가 둘 이상 존재해서는 안 됩니다.

앞 예시의 유효 오버로드 집합을 생각해보자. type list가 2, 3, 4인 아이템이 여러 개 있다. 각 type list 크기별로 구별 인자 인덱스는 0이다. NodeEvent구별 가능이기 때문이다.

아래와 같은 오버로딩은 허용되지 않는다:

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

DOMStringUSVString 은 구별 불가능하기 때문이다.

또한, 어떤 type list 크기의 구별 인자 인덱스보다 작은 인덱스 j에 대해, 모든 아이템의 type list에서 j번째 타입이 같아야 하며, 모든 아이템의 optionality list에서 j번째 optionality 값도 같아야 한다.

다음은 허용되지 않는다:

[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 »)
»

type list 크기가 4인 아이템들에서, 구별 인자 인덱스 는 2이다. NodeDOMString구별 가능이기 때문이다. 그러나 이 두 오버로드의 0번째 인자 타입이 다르므로, 오버로딩은 허용되지 않는다.

2.5.8.1. 오버로딩 vs. 유니온 타입

이 섹션은 참고용입니다.

IDL 연산을 정의하는 명세에서, 오버로딩유니온 타입, 옵션 인자 조합이 기능적으로 겹치는 부분이 있어 보일 수 있습니다.

먼저 오버로딩유니온 타입이나 옵션 인자와는 동작이 다르며, 하나로 완전히 대체할 수 없다(물론 추가적인 프로즈가 있으면 가능하지만, 이는 Web IDL 타입 시스템의 목적에 어긋난다). 예를 들어 stroke() 연산이 CanvasDrawPath 인터페이스에 정의되어 있다고 하자 [HTML]:

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

자바스크립트 바인딩에서는, stroke(undefined)를 호출하면 두 번째 오버로드가 선택되며, TypeError 가 발생한다. undefinedPath2D변환될 수 없기 때문이다. 하지만 연산이 옵션 인자로 하나로 합쳐진다면,

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

오버로드 결정 알고리즘path 인자를 누락된 것으로 처리하고 예외를 발생시키지 않습니다.

참고: 이 예시에서 후자의 동작이 실제로 Web 개발자가 기대하는 것입니다. CanvasDrawPath 를 새로 설계한다면 옵션 인자stroke()를 정의할 것입니다.

또한 의미적 차이도 있습니다. 유니온 타입은 "어떤 타입이든 동작이 대체로 같다"는 의미로 주로 쓰이고, 오버로딩된 연산은 C++ 등 언어의 오버로딩과 잘 대응되는 구조로, 인자 타입에 따라 동작이 크게 달라지는 경우에 더 적합합니다. 하지만 이런 경우 대부분은 혼동을 피하기 위해 연산 이름을 다르게 하는 것이 좋으며, 자바스크립트는 언어 차원의 오버로딩을 제공하지 않으므로 새로운 API에는 오버로딩은 거의 적합하지 않고, 레거시 API나 특수한 경우에만 사용됩니다.

그래도 어떤 IDL 기능을 사용할지 어려울 때 아래와 같은 권고와 예시를 참고하세요:

위 경우에 해당하지 않으면 명세 작성자가 스타일을 선택하면 됩니다. 둘 중 어느 쪽도 의도한 동작을 충분히 표현할 수 있기 때문입니다. 단, 변환 알고리즘유니온 타입, 옵션 인자의 정의가 오버로딩 결정 알고리즘보다 구현과 이해가 쉽고, 자바스크립트 바인딩에 더 적합한 API를 만드는 경우가 많다. 특별한 이유가 없다면 유니온 타입, 옵션 인자를 기본 선택으로 삼길 권장한다.

명세는 필요하다면 유니온 타입과 오버로딩을 혼합해 사용할 수도 있다.

2.5.9. 이터러블 선언

인터페이스이터러블로 선언될 수 있으며, 이는 인터페이스 본문에 이터러블 선언(Iterable에 일치)을 사용하여 지정한다.

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

인터페이스를 이터러블로 구현한 객체는 값을 시퀀스로 얻을 수 있도록 반복(iterate)할 수 있다.

참고: 자바스크립트 바인딩에서는 이터러블 인터페이스의 인터페이스 프로토타입 객체entries, forEach, keys, values, %Symbol.iterator% 프로퍼티가 있다.

타입 파라미터가 하나면 값 이터레이터이며, 해당 타입의 값을 제공한다. 타입 파라미터가 둘이면 쌍 이터레이터이며, 값 쌍을 제공한다.

값 쌍은 키 타입과 값 타입이 주어졌을 때 두 개의 구조체 아이템으로 이루어진다:

  1. 아이템이름이 "key"이고, 값 쌍라 하며, 값은 키 타입의 IDL 값이다;

  2. 아이템이름이 "value"이고, 값 쌍이라 하며, 값은 값 타입의 IDL 값이다.

값 이터레이터는 반드시 인덱스 프로퍼티를 지원하는 인터페이스에만 선언될 수 있다. 값 이터레이터의 value-type은 인덱스 프로퍼티 getter가 반환하는 타입과 같아야 한다. 값 이터레이터는 해당 객체의 인덱스 프로퍼티를 반복(iterate)하는 것으로 암묵적으로 정의된다.

쌍 이터레이터인덱스 프로퍼티를 지원하는 인터페이스에 선언될 수 없다.

페어 반복자가 있는 인터페이스에 대한 설명은 각 인터페이스 인스턴스마다 리스트값 쌍의 형태로 정의해야 하며, 이 리스트는 반복할 값 쌍입니다.

자바스크립트에서 값 이터레이터의 forEach 메서드는 Array.prototype.forEach처럼 콜백을 호출하고, 쌍 이터레이터의 forEach는 Map.prototype.forEach처럼 호출한다.

값 이터레이터는 현재 인덱스 프로퍼티를 지원하는 인터페이스에만 허용되므로 Array 스타일 forEach가 적합하다. 인덱스 프로퍼티를 지원하지 않는 인터페이스나, Set.prototype.forEach처럼 key와 value가 같은 forEach가 필요한 값을 반복하는 이터레이터가 필요하다면, 이슈를 등록해 주세요.

참고: 이는 array 이터레이터 객체 동작 방식이다. 인덱스 프로퍼티를 지원하는 인터페이스의 경우, entries, keys, values, %Symbol.iterator% 가 반환하는 이터레이터 객체는 실제 array 이터레이터 객체이다.

이터러블 선언이 있는 인터페이스에는 "entries", "forEach", "keys", "values"라는 이름의 속성, 상수, 일반 연산이 존재해서는 안 되며, 상속받은 인터페이스에도 이 이름의 속성, 상수, 일반 연산이 존재해서는 안 된다.

다음 SessionManager 인터페이스는 username을 키로 Session 객체를 참조할 수 있다:

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

  iterable<DOMString, Session>;
};

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

이터레이터의 동작은 아래처럼 정의될 수 있다:

반복할 값 쌍은 username을 key, 해당 username에 대응하는 SessionManager 객체의 열린 Session 객체를 value로 하여, username 기준으로 정렬된 값 쌍 리스트이다.

자바스크립트 바인딩에서 SessionManager 인터페이스인터페이스 프로토타입 객체에는 values 메서드가 있고, 이 함수는 호출 시 다음 값을 반환하는 next 메서드를 가진 이터레이터 객체를 반환한다. keysentries 메서드는 각각 session 객체의 username, username/Session 객체 쌍을 반복한다. %Symbol.iterator% 메서드도 있어서 SessionManagerfor..of 루프에서 사용할 수 있으며, entries와 같은 값을 반복한다:

// SessionManager 인스턴스를 얻는다.
// 예를 들어 "anna", "brian" 유저 세션이 있다고 가정.
var sm = getSessionManager();

typeof SessionManager.prototype.values;            // "function" 반환
var it = sm.values();                              // values()는 이터레이터 객체 반환
String(it);                                        // "[object SessionManager Iterator]" 반환
typeof it.next;                                    // "function" 반환

// 아래 루프는 "anna", "brian"을 로그한다.
for (;;) {
  let result = it.next();
  if (result.done) {
    break;
  }
  let session = result.value;
  console.log(session.username);
}

// 이것도 "anna", "brian"을 로그한다.
for (let username of sm.keys()) {
  console.log(username);
}

// 아래도 동일하다.
for (let [username, session] of sm) {
  console.log(username);
}

인터페이스에는 하나의 이터러블 선언만 존재해야 한다. 상속받은 인터페이스에도 이터러블 선언이 있으면 안 된다. 이터러블 선언이 있는 인터페이스와 그 상속 인터페이스에는 maplike 선언, setlike 선언, 비동기 이터러블 선언이 있어서는 안 된다.

이터러블 선언에 적용 가능한 확장 속성: [CrossOriginIsolated], [Exposed], [SecureContext].

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

2.5.10. 비동기 이터러블 선언

인터페이스비동기 이터러블 선언 (AsyncIterable에 일치)을 본문에 사용함으로써 비동기 이터러블로 선언할 수 있다.

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

비동기 이터러블로 선언된 인터페이스구현하는 객체는 값을 비동기로 반복(iterate)해서 얻을 수 있다.

타입 파라미터가 하나면 값 비동기 이터러블 선언이며, 해당 타입의 값을 비동기로 제공한다. 두 개면 쌍 비동기 이터러블 선언이며, 값 쌍을 비동기로 제공한다.

인자가 있다면, 비동기 이터러블 선언의 인자(ArgumentList에 일치)는 모두 옵션 인자여야 한다.

자바스크립트 바인딩에서, 비동기 이터러블 인터페이스의 인터페이스 프로토타입 객체에는 %Symbol.asyncIterator%values 프로퍼티가 있다. 쌍 비동기 이터러블 선언이면 entries, keys 프로퍼티도 있다. 이 모든 메서드는 옵션 인자를 받을 수 있으며, 전달된 인자는 비동기 이터러블 선언의 인자 리스트에 대응하며, 비동기 이터레이터 초기화 단계에서 처리된다.

이 요구조건 덕분에 자바스크립트 바인딩에서 for-await-of가 인터페이스 인스턴스에 바로 쓸 수 있다. for-await-of%Symbol.asyncIterator%를 인자 없이 호출하기 때문이다.

비동기 이터러블 선언이 있는 인터페이스의 프로즈에는 다음 반복 결과 얻기 알고리즘을 정의해야 한다. 이 알고리즘은 반복 중인 인터페이스 인스턴스와 비동기 이터레이터 객체를 받으며(상태 저장에 유용), Promise를 반환해야 한다. 이 Promise는 reject되거나, 반복 종료 신호를 나타내는 반복 종료 값을 resolve하거나, 아래 중 하나를 resolve한다:

값 비동기 이터러블 선언의 경우:

선언된 타입의 값

쌍 비동기 이터러블 선언의 경우:

선언된 두 타입의 값을 포함하는 튜플

또한 프로즈에서 비동기 이터레이터 반환 알고리즘을 정의할 수 있다. 이 알고리즘은 반복 중인 인터페이스 인스턴스, 비동기 이터레이터 객체, any 타입의 인자 하나를 받는다. 이는 이터레이터가 중단될 때 호출되며, Promise를 반환해야 하며, fulfill되면 값은 무시되고, reject되면 에러가 사용자에게 전달된다.

자바스크립트 바인딩에서는 이 알고리즘을 통해 async iterator의 return()이 호출될 때 동작을 커스터마이즈할 수 있다. 이는 breakreturn으로 for-await-of 루프를 빠져나갈 때 가장 흔히 발생한다.

throw()에 대한 유사한 hook도 추가할 수 있다. 현재까지 필요가 없었지만, 그런 API가 필요하다면 이슈를 등록해 주세요.

또한 프로즈에서 비동기 이터레이터 초기화 단계도 정의할 수 있다. 이는 반복 중인 인터페이스 인스턴스, 새로 생성된 이터레이터 객체, 전달된 인자를 나타내는 IDL 값 리스트를 받는다.

비동기 이터러블 선언이 있는 인터페이스에는 "entries", "keys", "values"라는 이름의 속성, 상수, 일반 연산이 존재해서는 안 되며, 상속받은 인터페이스에도 이 이름의 속성, 상수, 일반 연산이 존재해서는 안 된다.

다음 SessionManager 인터페이스는 username을 키로 Session 객체를 참조할 수 있다:

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

  async_iterable<DOMString, Session>;
};

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

이터레이터의 동작은 아래처럼 정의될 수 있다:

SessionManager 비동기 이터레이터 iterator비동기 이터레이터 초기화 단계:

  1. iterator현재 상태를 "아직 시작하지 않음"으로 설정한다.

SessionManager manager와 비동기 이터레이터 iterator에 대해 다음 반복 결과 얻기:

  1. promise를 새 Promise로 둔다.

  2. key를 다음 값으로 둔다(없으면 null):

    만약 iterator현재 상태가 "아직 시작하지 않음"이라면

    manager의 열린 세션 중 username이 가장 작은 값(사전순)

    그 외

    manager의 열린 세션 중 iterator의 현재 상태보다 큰 username 중 가장 작은 값(사전순)

    참고: iterator현재 상태가 이미 열린 세션에 없을 수도 있다.

  3. key가 null이면:

    1. promise반복 종료로 resolve한다.

  4. 그 외:

    1. sessionkey에 대응하는 Session 객체로 둔다.

    2. promise를 (username, session)로 resolve한다.

    3. iterator현재 상태username으로 설정한다.

  5. promise를 반환한다.

자바스크립트 바인딩에서 SessionManager 인터페이스인터페이스 프로토타입 객체에는 values 메서드가 있고, 이 함수는 호출 시 다음 값을 반환하는 next 메서드를 가진 비동기 이터레이터 객체를 반환한다. keysentries 메서드는 각각 session 객체의 username, username/Session 객체 쌍을 반복한다. %Symbol.asyncIterator% 메서드도 있어서 SessionManagerfor await..of 루프에서 사용할 수 있으며, entries와 같은 값을 반복한다:

// SessionManager 인스턴스를 얻는다.
// 예를 들어 "anna", "brian" 유저 세션이 있다고 가정.
var sm = getSessionManager();

typeof SessionManager.prototype.values;            // "function" 반환
var it = sm.values();                              // values()는 이터레이터 객체 반환
typeof it.next;                                    // "function" 반환

// 아래 루프는 "anna", "brian"을 로그한다.
for await (let username of sm.keys()) {
  console.log(username);
}

// 이것도 동일하다.
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 선언 (ReadWriteMaplike 또는 readonly MaplikeRest에 일치)을 사용해 지정한다.

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

maplike로 선언된 인터페이스를 구현하는 객체는, 처음에는 비어 있고, 키–값 쌍의 순서 있는 map을 나타내며, 이를 해당 객체의 map 엔트리라고 한다. 키와 값의 타입은 maplike 선언의 꺾쇠 괄호에 지정된다. 키는 반드시 고유해야 한다.

명세 작성자는 map 엔트리의 내용을 수정할 수 있으며, 이는 자바스크립트 코드에서 객체의 내용에 자동으로 반영된다.

maplike 인터페이스는 언어 바인딩에 적절한 map 엔트리 질의 API를 지원한다. readonly 키워드가 없으면, map 엔트리 수정 API도 지원한다.

참고: 자바스크립트 바인딩에서는 map 엔트리와 상호작용하는 API는 자바스크립트 Map 객체와 유사하다. readonly 키워드가 있을 때는 entries, forEach, get, has, keys, values, %Symbol.iterator% 메서드, 그리고 size getter를 포함한다. 읽기–쓰기 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 선언, 인덱스 프로퍼티 getter가 있어서는 안 된다.

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

이 명세에서 정의된 확장 속성maplike 선언에 적용되지 않는다.

예시 추가 필요.

2.5.12. Setlike 선언

인터페이스setlike로 선언될 수 있으며, 이는 인터페이스 본문에 setlike 선언 (ReadWriteSetlike 또는 readonly SetlikeRest에 일치)을 사용해 지정한다.

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

setlike로 선언된 인터페이스를 구현하는 객체는, 처음에는 비어 있고, 값의 순서 있는 집합을 나타내며, 이를 해당 객체의 set 엔트리라고 한다. 값의 타입은 setlike 선언의 꺾쇠 괄호에 지정된다. 값은 반드시 고유해야 한다.

명세 작성자는 set 엔트리의 내용을 수정할 수 있으며, 이는 자바스크립트 코드에서 객체의 내용에 자동으로 반영된다.

setlike 인터페이스는 언어 바인딩에 적절한 set 엔트리 질의 API를 지원한다. readonly 키워드가 없으면, set 엔트리 수정 API도 지원한다.

참고: 자바스크립트 바인딩에서는 set 엔트리와 상호작용하는 API는 자바스크립트 Set 객체와 유사하다. readonly 키워드가 있을 때는 entries, forEach, has, keys, values, %Symbol.iterator% 메서드, 그리고 size getter를 포함한다. 읽기–쓰기 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 선언, 인덱스 프로퍼티 getter가 있어서는 안 된다.

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

이 명세에서 정의된 확장 속성setlike 선언에 적용되지 않는다.

예시 추가 필요.

2.6. 네임스페이스

네임스페이스란, 전역 싱글턴과 관련 동작을 선언하는 정의(Namespace에 일치)입니다.

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

네임스페이스는 네임스페이스 멤버들의 명세(NamespaceMembers에 일치)입니다. 네임스페이스 멤버란, 네임스페이스 선언의 중괄호 사이에 등장하는 일반 연산, 읽기 전용 일반 속성, 상수입니다. 이 연산과 속성들은 네임스페이스에 패키징되는 동작을 설명합니다.

인터페이스와 마찬가지로, 네임스페이스의 IDL도 부분 네임스페이스 정의(partial Namespace에 일치)를 사용해 여러 부분으로 나눌 수 있습니다. 부분 네임스페이스 정의의 식별자는 네임스페이스 정의의 식별자와 동일해야 합니다. 각 부분 네임스페이스 정의에 등장하는 모든 멤버는 네임스페이스 자체의 멤버로 간주됩니다.

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

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

참고: 부분 인터페이스 정의처럼, 부분 네임스페이스 정의는 명세 편집을 돕기 위한 것으로, 네임스페이스 정의를 문서의 여러 섹션 또는 여러 문서에 걸쳐 분리해 기술할 수 있게 해줍니다.

멤버가 등장하는 순서는 JavaScript 바인딩에서 프로퍼티 열거에 영향을 미칩니다.

인터페이스나 딕셔너리와 다르게, 네임스페이스는 타입을 생성하지 않습니다.

이 명세에서 정의된 확장 속성 중, [CrossOriginIsolated], [Exposed], [SecureContext]만 네임스페이스에 적용할 수 있습니다.

네임스페이스는 반드시 [Exposed] 확장 속성으로 어노테이트해야 합니다.

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

아래 IDL 프래그먼트네임스페이스를 정의합니다.

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

자바스크립트 구현에서는 전역 VectorUtils 데이터 프로퍼티가 노출되며, 이는 단순 객체(프로토타입은 %Object.prototype%) 이고, 선언된 연산마다 열거 가능한 데이터 프로퍼티, 선언된 속성마다 열거 가능한 읽기 전용 접근자를 가집니다:

Object.getPrototypeOf(VectorUtils);                         // Object.prototype 반환
Object.keys(VectorUtils);                                   // ["dotProduct", "crossProduct"] 반환
Object.getOwnPropertyDescriptor(VectorUtils, "dotProduct"); // { value: <a function>, enumerable: true, configurable: true, writable: true } 반환
Object.getOwnPropertyDescriptor(VectorUtils, "unit");       // { get: <a function>, enumerable: true, configurable: true } 반환

2.7. 딕셔너리

딕셔너리란, Dictionary에 일치하는 정의로, 고정된 순서의 순서 있는 map 데이터 타입을 정의하는 데 사용된다. 이 map의 엔트리들은 딕셔너리 멤버라 하며, 는 문자열이고 은 정의에서 지정한 특정 타입이다.

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

딕셔너리 인스턴스는 언어별 표현(예: 해당하는 자바스크립트 객체)에 대한 참조를 유지하지 않는다. 예를 들어, 딕셔너리를 연산에서 반환하면, 현재 딕셔너리 값으로부터 새로운 자바스크립트 객체가 생성된다. 반대로 연산에서 딕셔너리를 인자로 받을 경우, 전달된 자바스크립트 값으로부터 딕셔너리로 한 번만 변환이 수행된다. 딕셔너리를 수정해도 해당 자바스크립트 객체에는 반영되지 않고, 그 반대도 마찬가지다.

딕셔너리는 속성이나 상수의 타입으로 사용될 수 없다.

딕셔너리는 다른 딕셔너리를 상속하도록 정의할 수 있다. 딕셔너리의 식별자 뒤에 콜론과 식별자가 오면, 해당 식별자는 상속받는 딕셔너리를 식별한다. 반드시 딕셔너리를 식별해야 한다.

딕셔너리의 상속 계층에 순환 구조가 있으면 안 된다. 즉, 딕셔너리 A가 자기 자신을 상속하거나, B를 상속하면서 B가 다시 A를 상속하는 방식은 금지된다.

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

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

딕셔너리 D상속된 딕셔너리들D가 직접 또는 간접적으로 상속받는 모든 딕셔너리 집합을 의미한다. D가 다른 딕셔너리를 상속하지 않으면 집합은 비어 있다. 그렇지 않으면, D가 상속한 딕셔너리 EE상속된 딕셔너리들이 모두 포함된다.

딕셔너리 멤버필수로 지정될 수 있다. 이 경우, 해당 멤버에 값을 제공하지 않으면 언어별 값에서 딕셔너리로 변환할 때 오류가 발생한다. 필수가 아닌 멤버는 옵션이다.

딕셔너리 멤버필수로 지정하는 것은, 언어별 딕셔너리 표현(예: 연산 인자로 자바스크립트 값을 전달할 때)에서만 효과가 있다. 이외의 경우, 즉 딕셔너리를 반환 타입으로만 사용하는 경우 등에는 멤버를 옵션으로 남겨두는 것이 좋다.

타입 D의 딕셔너리 값에는, DD상속된 딕셔너리들에 정의된 모든 딕셔너리 멤버에 대한 엔트리가 있을 수 있다. 필수 또는 기본값이 지정된 멤버는 반드시 엔트리가 존재한다. 그 외 멤버의 엔트리는 존재할 수도 있고, 아닐 수도 있다.

자바스크립트 바인딩에서는, 딕셔너리 멤버에 해당하는 프로퍼티 값이 undefined면, 해당 프로퍼티가 생략된 것과 동일하게 처리된다. 즉, 필수라면 오류가 발생하고, 기본값이 있으면 그 값이 사용되며, 그 외에는 딕셔너리 값에 해당 엔트리가 존재하지 않는다.

연산 인자 기본값과 마찬가지로, boolean 타입 딕셔너리 멤버의 기본값으로 true를 사용하지 말 것을 강력히 권장한다. 이는 undefined의 기본 변환이 false가 되기를 기대하는 저자에게 혼란을 줄 수 있기 때문이다. [API-DESIGN-PRINCIPLES]

문자열 를 가진 순서 있는 map은, 모든 엔트리가 딕셔너리 D딕셔너리 멤버에 대응하고, 타입이 맞고, 필수 또는 기본값 멤버에 대한 엔트리가 모두 존재하면 암묵적으로 D 타입의 딕셔너리 값으로 간주될 수 있다.

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

Descriptor 딕셔너리는 다음과 같이 생성할 수 있다:

  1. identifiers를 « 1, 3, 7 »로 둔다.

  2. «[ "name" → "test", "serviceIdentifiers" → identifiers ]»를 반환한다.

딕셔너리 멤버(DictionaryMember에 일치)는 Type에 일치하는 타입 뒤에 식별자가 따라온다(타입 뒤에 identifier 토큰). 이 식별자가 키–값 쌍의 키 이름이다. Type식별자 뒤에 ?가 붙으면, 해당 식별자는 인터페이스, 열거형, 콜백 함수, 콜백 인터페이스, 타입 정의 중 하나를 식별해야 한다. ?가 없으면, 위 타입들 중 하나 또는 딕셔너리여야 한다.

딕셔너리 멤버의 타입이 typedef 해석 후 널 허용 타입이면, 내부 타입딕셔너리 타입이면 안 된다.

dictionary identifier {
  type identifier;
};

옵션 딕셔너리 멤버의 식별자 뒤에 U+003D(=)와 값(DefaultValue에 일치)이 오면, 해당 멤버의 기본값이 된다. 이 값은 코드나 명세에서 값을 지정하지 않을 경우 기본으로 사용된다.

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

불리언 리터럴 토큰(true 또는 false), null 토큰, integer 토큰, decimal 토큰, 세 가지 특수 부동소수점 리터럴(Infinity, -Infinity, NaN), string 토큰, [] 또는 {} 토큰 시퀀스가 기본값으로 사용되면, 연산옵션 인자 기본값과 같은 방식으로 해석된다.

딕셔너리 멤버 타입이 열거형이면, 기본값은 반드시 열거형의 값 중 하나여야 한다.

딕셔너리 멤버 타입 앞에 required 키워드가 있으면, 해당 멤버는 필수 딕셔너리 멤버로 간주된다.

dictionary identifier {
  required type identifier;
};

딕셔너리 멤버의 타입에는 해당 딕셔너리가 포함되면 안 된다. 타입이 딕셔너리 D를 포함한다는 것은 다음 중 하나라도 참이면 성립한다:

인터페이스와 마찬가지로, 딕셔너리의 IDL도 부분 딕셔너리 정의(partial Dictionary에 일치)를 사용해 여러 부분으로 나눌 수 있다. 부분 딕셔너리 정의의 식별자는 딕셔너리 정의의 식별자와 같아야 한다. 각 부분 딕셔너리 정의에 등장하는 모든 멤버는 딕셔너리 자체의 멤버로 간주된다.

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

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

참고: 부분 인터페이스 정의와 같이, 부분 딕셔너리 정의는 명세 편집을 돕기 위한 것으로, 딕셔너리 정의를 문서의 여러 섹션이나 여러 문서에 걸쳐 분리할 수 있게 해준다.

딕셔너리의 딕셔너리 멤버 순서는, 상속된 멤버가 비상속 멤버보다 앞에 오고, 한 딕셔너리 정의(부분 딕셔너리 포함) 내 멤버들은 식별자의 유니코드 코드포인트 기준으로 사전순 정렬된다.

예를 들어, 아래 정의가 있을 때:

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);
};

그리고 자바스크립트 코드:

var something = getSomething();  // Something 인스턴스 얻기
var x = 0;

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

something.f(dict);

딕셔너리 멤버를 조회하는 순서에 따라 값이 달라진다. A의 순서가 c, d이므로, c 값은 1, d 값은 2가 된다.

딕셔너리 멤버의 식별자는 해당 딕셔너리 또는 상속된 딕셔너리에 정의된 다른 딕셔너리 멤버의 식별자와 같아서는 안 된다.

딕셔너리에는 확장 속성이 적용되지 않는다.

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

딕셔너리 타입의 한 가지 용도는, 옵션 인자를 연산에 여러 개 제공하면서, 호출 시 인자 순서에 구애받지 않게 하는 것이다. 예를 들어, 다음 IDL 프래그먼트를 보자:

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

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

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

IDL의 자바스크립트 구현에서는, 옵션 PaintOptions 딕셔너리에 Object를 넘길 수 있다:

// GraphicsContext 인스턴스 얻기
var ctx = getGraphicsContext();

// 사각형 그리기
ctx.drawRectangle(300, 200, { fillPattern: "red", position: new Point(10, 10) });

PaintOptions의 멤버는 옵션이다. fillPattern을 생략하면, drawRectangle 정의에서 기본값이 있다고 간주하고 따로 생략 처리 문구를 넣지 않아도 된다. strokePatternposition 생략 시는 drawRectangle에서 명시적으로 처리해야 한다.

2.8. 예외

예외란 오류를 나타내는 객체 타입으로, 구현체에서 throw 하거나 값처럼 다룰 수 있다. Web IDL에는 명세에서 연산, 속성 등에 참조 또는 throw할 수 있는 여러 기본 예외가 정의되어 있다. 인터페이스에서 DOMException상속하여 커스텀 예외 타입도 정의할 수 있다.

단순 예외는 다음 타입 중 하나로 식별된다:

이들은 JavaScript의 에러 객체와 대응한다 (단, SyntaxErrorError는 제외됨; 각각 JS 파서와 저자 용도로 예약되어 있음). 각 단순 예외의 의미는 JavaScript 명세의 대응 에러 객체와 같다.

두 번째 예외 종류는 DOMException으로, 발생한 오류에 대해 name으로 프로그래밍적으로 상세 정보를 제공한다. name 값은 아래 DOMException 이름 테이블에서 선정된다.

DOMException인터페이스 타입이므로 IDL에서 타입으로 사용할 수 있다. 예를 들어 연산DOMException 반환 타입으로 선언할 수 있지만, 예외는 반환이 아니라 throw하는 것이므로 이런 패턴은 바람직하지 않다.

세 번째 예외 종류는 DOMException을 상속한 인터페이스이다. 이들은 더 복잡하므로 § 2.8.2 DOMException 파생 인터페이스에서 따로 설명한다.

단순 예외는 타입 이름을 제공해 생성할 수 있다. DOMExceptionname과 함께 제공하여 생성한다. 예외는 throw할 수도 있는데, 이때도 생성할 때와 동일한 정보가 필요하다. 두 경우 모두 예외가 무엇을 의미하는지에 대한 추가 정보를 제공할 수 있으며, 예외 메시지 작성에 유용하다.

예외를 생성하고 throw하는 문구 예시: 단순 예외 TypeError를 throw하려면:

TypeError를 throw한다.

name이 "NotAllowedError"인 DOMException을 throw하려면:

"NotAllowedError" DOMException을 throw한다.

name이 "SyntaxError"인 DOMException을 생성하려면:

object를 새로 생성된 "SyntaxError" DOMException으로 둔다.

name이 "OperationError"인 DOMException으로 promise를 reject하려면:

p를 "OperationError" DOMException으로 reject한다.

예외 메시지에 추가 정보를 포함하는 예시:

"SyntaxError" DOMException을 throw한다. 이 때 주어진 값에 허용되지 않는 후행 공백이 있었다고 명시한다.

이런 추가 컨텍스트는 예외 발생 이유가 명확하지 않을 때(예: 알고리즘 여러 단계에서 "SyntaxError" DOMException을 throw할 때) 구현자에게 도움이 된다. 반면, 예를 들어 사용자가 특정 기능 사용 권한을 제공했는지 검사하고 바로 "NotAllowedError" DOMException을 throw하는 경우에는 메시지 구체화가 필요하지 않다.

예외 생성 및 throw의 실제 동작은 언어 바인딩마다 다르다.

§ 3.14.3 예외 생성 및 throw에서 자바스크립트 바인딩에서 예외 생성 및 throw의 상세 동작을 볼 수 있다.

2.8.1. 기본 DOMException 오류 이름

아래 DOMException 이름 테이블은 기본 DOMException 인터페이스 인스턴스에 허용되는 모든 이름과, 각 이름의 의미 및 레거시 숫자 오류 코드 값을 설명합니다.

DOMException상속한 인터페이스(아래 § 2.8.2 DOMException 파생 인터페이스 참고)는 자체 이름을 가지며, 이 테이블에는 포함되지 않습니다.

DOMException생성하거나 throw할 때, 명세서는 반드시 이 이름 중 하나를 사용해야 합니다. 만약 명세자가 어떤 이름도 적합하지 않다고 생각되면, 이슈를 등록해 새로운 이름 추가를 논의해야 하며, 커뮤니티가 이런 작업을 조율할 수 있습니다. 새로운 케이스별 이름은, 웹 개발자가 단일 API에서 여러 오류 조건을 구분할 필요가 있을 때만 중요합니다.

DOMException 이름 중 "deprecated"로 표시된 것은 레거시를 위해 남아 있지만, 사용은 권장하지 않습니다.

참고: 여기 정의된 "SyntaxError" DOMException과 JavaScript의 SyntaxError를 혼동하지 마세요. "SyntaxError" DOMException은 웹 API에서 파싱 오류(예: 셀렉터 파싱 등)를 보고하는 데 사용되며, JavaScript SyntaxError는 JS 파서 용도로 예약되어 있습니다. 혼동을 피하기 위해, 항상 "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" 연산이 Namespaces in XML에 의해 허용되지 않음. [XML-NAMES] NAMESPACE_ERR (14)
"InvalidAccessError" 사용 중단됨. 잘못된 인자에는 TypeError, 지원되지 않는 연산에는 "NotSupportedError" DOMException, 거부된 요청에는 "NotAllowedError" DOMException 사용. INVALID_ACCESS_ERR (15)
"TypeMismatchError" 사용 중단됨. 대신 TypeError 사용. TYPE_MISMATCH_ERR (17)
"SecurityError" 연산이 안전하지 않음. SECURITY_ERR (18)
"NetworkError" 네트워크 오류가 발생함. NETWORK_ERR (19)
"AbortError" 연산이 중단됨. ABORT_ERR (20)
"URLMismatchError" 사용 중단됨. URL_MISMATCH_ERR (21)
"QuotaExceededError" 사용 중단됨. 대신 QuotaExceededError DOMException 파생 인터페이스 사용. QUOTA_EXCEEDED_ERR (22)
"TimeoutError" 연산이 제한 시간을 초과함. TIMEOUT_ERR (23)
"InvalidNodeTypeError" 제공된 노드가 이 연산에 부적합하거나 상위 노드가 부적합함. [DOM] INVALID_NODE_TYPE_ERR (24)
"DataCloneError" 객체를 복제할 수 없음. DATA_CLONE_ERR (25)
"EncodingError" 인코딩(또는 디코딩) 작업이 실패함.
"NotReadableError" I/O 읽기 작업이 실패함.
"UnknownError" 알 수 없는 일시적 이유(예: 메모리 부족)로 연산이 실패함.
"ConstraintError" 트랜잭션의 변이 작업이 제약 조건을 만족하지 않아 실패함. [INDEXEDDB]
"DataError" 제공된 데이터가 불충분함.
"TransactionInactiveError" 요청이 현재 활성 상태가 아니거나 종료된 트랜잭션에 대해 실행됨. [INDEXEDDB]
"ReadOnlyError" "readonly" 트랜잭션에서 변이 작업 시도함. [INDEXEDDB]
"VersionError" 기존 버전보다 낮은 버전으로 데이터베이스를 열려고 시도함. [INDEXEDDB]
"OperationError" 연산별 이유로 연산이 실패함.
"NotAllowedError" 현재 컨텍스트에서 사용자 에이전트 또는 플랫폼에서 요청이 허용되지 않음(예: 사용자가 권한 거부함).
"OptOutError" 사용자가 해당 프로세스를 거부함.

2.8.2. DOMException 파생 인터페이스

예외가 DOMExceptionname으로 제공되는 정보 외에, 추가로 프로그래밍적으로 조회 가능한 정보를 담아야 할 때, 명세 작성자는 DOMException상속하는 인터페이스를 만들 수 있다. 이런 인터페이스는 개발자가 예측 가능한 형태로 다룰 수 있도록 다음 규칙을 따라야 한다:

이 요구로 인해, 이런 인터페이스의 상속된 code 프로퍼티는 항상 0을 반환한다.

DOMException 파생 인터페이스를 생성하거나 throw하려면, 해당 인터페이스 식별자와 추가 정보가 필요하다.

QuotaExceededError 인스턴스를 throw하려면:

QuotaExceededError를 throw한다. quota는 42, requested는 50으로 설정한다.

2.8.3. 미리 정의된 DOMException 파생 인터페이스

이 표준에서는 현재 미리 정의된 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할 수 있다. 두 개의 속성(quota, requested)을 가지고 있으며, 웹 개발자가 자신의 요청과 할당량 값을 비교할 수 있도록 추가 정보를 제공한다.

이전 버전의 표준에서는 "QuotaExceededError"가 기본 DOMException 오류 이름 중 하나였으나, 이런 정보를 제공할 수 있도록 풀 인터페이스로 승격되었다.

모든 QuotaExceededError 인스턴스는 requestedquota라는 두 개의 숫자 또는 null 값을 가지며, 최초 값은 모두 null이다.

new QuotaExceededError(message, options) 생성자 단계:
  1. thisname을 "QuotaExceededError"로 설정한다.

  2. thismessagemessage로 설정한다.

  3. options["quota"]가 있으면:

    1. options["quota"]가 0보다 작으면 RangeError를 throw한다.

    2. thisquotaoptions["quota"]로 설정한다.

  4. options["requested"]가 있으면:

    1. options["requested"]가 0보다 작으면 RangeError를 throw한다.

    2. thisrequestedoptions["requested"]로 설정한다.

  5. thisquotarequested가 모두 null이 아니고, requestedquota보다 작으면 RangeError를 throw한다.

quota getter는 thisquota를 반환한다.

requested getter는 thisrequested를 반환한다.

QuotaExceededError 인터페이스는 DOMExceptioncode getter를 상속받으며, 항상 22를 반환한다. 하지만 이 값에 의존하는 것은 권장되지 않는다(QuotaExceededErrorDOMException 모두에서). 대신 name getter를 사용하는 것이 더 낫다.


QuotaExceededError 객체는 직렬화 가능한 객체이다.

직렬화 단계(value, serialized):
  1. DOMException직렬화 단계value, serialized에 대해 실행한다.

  2. serialized.[[Quota]]를 valuequota로 설정한다.

  3. serialized.[[Requested]]를 valuerequested로 설정한다.

역직렬화 단계(serialized, value):
  1. DOMException역직렬화 단계serialized, value에 대해 실행한다.

  2. valuequotaserialized.[[Quota]]로 설정한다.

  3. valuerequestedserialized.[[Requested]]로 설정한다.


QuotaExceededError생성하거나 throw할 때, requestedquota가 모두 null이 아니면서 requestedquota보다 작으면 안 된다.

2.9. 열거형

열거형이란, Enum에 일치하는 정의로, 타입의 유효 값이 미리 정해진 문자열 집합인 것을 선언한다. 열거형은 DOMString 값이 속성에 할당되거나 연산에 인자로 전달될 때, 가능한 값을 제한하는 데 사용할 수 있다.

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

열거형 값은 쉼표로 구분된 string 리터럴 목록으로 지정한다. 열거형 값 목록에는 중복이 있으면 안 된다.

열거형 값은 모두 소문자로 하고, 여러 단어는 대시(-)로 구분하거나 아예 구분하지 않는 것이 강력히 권장된다. 특별한 이유가 없으면 다른 명명 규칙을 사용하지 말 것. 예를 들어, 객체 생성 의미의 값은 "createobject" 또는 "create-object"로 할 수 있다. 관련 API에서 일관성을 위해 단어 구분 방식도 신중히 결정할 것.

열거형 타입 속성에 유효하지 않은 문자열 값을 할당하거나, 연산 인자로 전달하는 경우의 동작은 언어 바인딩에 따라 다르다.

참고: 자바스크립트 바인딩에서는 속성에 잘못된 문자열 값을 할당하면 무시되지만, 다른 맥락(예: 연산 인자)에서는 예외가 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;     // g 단위

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

자바스크립트 구현에서는 type 속성이나 initialize 함수 인자에 할당할 수 있는 문자열이 열거형에 명시된 문자열로 제한된다.

var meal = getMeal();                // Meal 인스턴스 얻기

meal.initialize("rice", 200);        // 정상적으로 호출됨

try {
  meal.initialize("sandwich", 100);  // TypeError 발생
} catch (e) {
}

meal.type = "noodles";               // 정상 할당
meal.type = "dumplings";             // 무시됨
meal.type == "noodles";              // true 반환

2.10. 콜백 함수

"Custom DOM Elements" 명세에서는 플랫폼 객체 제공 함수에도 콜백 함수 타입을 사용하고 싶어합니다. 콜백 함수 대신 그냥 "함수"로 이름을 바꿔서 두 가지 용도 모두 명확히 할 수 있을까요?

콜백 함수란, callback CallbackRest에 일치하는 정의로, 함수 타입을 선언하는 데 사용됩니다.

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

참고: 유사 이름의 콜백 인터페이스도 참고하세요.

등호 왼쪽의 식별자가 콜백 함수 이름이며, 오른쪽의 반환 타입과 인자 목록(TypeArgumentList)이 함수 시그니처를 정의합니다.

콜백 함수상수의 타입으로 사용될 수 없습니다.

콜백 함수에 적용 가능한 확장 속성: [LegacyTreatNonObjectAsNull].

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

아래 IDL 프래그먼트는 연산이 완료될 때 사용자 정의 함수를 호출하는 API의 콜백 함수를 정의한 예시입니다.

callback AsyncOperationCallback = undefined (DOMString status);

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

자바스크립트 바인딩에서는 함수 객체가 연산 인자로 전달된다.

var ops = getAsyncOperations();  // AsyncOperations 인스턴스 얻기

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

2.11. 타입 정의(typedef)

타입 정의(typedef)란, Typedef에 일치하는 정의로, 타입에 새 이름을 선언하는 데 사용됩니다. 이 새 이름은 언어 바인딩에 노출되지 않으며, IDL 내에서 타입을 참조할 때만 약칭으로 쓰입니다.

typedef type identifier;

새 이름을 부여받는 타입typedef 키워드 뒤에 지정되며(TypeWithExtendedAttributes에 일치), 그 뒤의 identifier 토큰이 이름이 됩니다.

Type은 동일하거나 다른 typedef의 식별자가 되어서는 안 됩니다.

이 명세에서 정의된 확장 속성타입 정의에 적용되지 않습니다.

Typedef ::
    typedef TypeWithExtendedAttributes identifier ;

아래 IDL 프래그먼트타입 정의(typedef)를 사용해 긴 시퀀스 타입 대신 짧은 식별자를 쓸 수 있게 하는 예를 보여줍니다.

[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 등 인터페이스 구현)은 페이지 내 자바스크립트에서 웹 페이지 내용을 접근할 수 있게 해주는 플랫폼 객체입니다. 이런 객체들은 C++ 등으로 구현된 특수 객체일 수도 있고, 네이티브 자바스크립트 객체일 수도 있습니다. 어쨌든, 하나의 IDL 프래그먼트 집합에 대한 구현에서는, 모든 플랫폼 객체를 인식할 수 있어야 합니다. 이것은 내부적으로 객체가 플랫폼 객체임을 기록하거나, 객체가 특정 C++ 클래스에서 구현된 것을 감지하는 방식 등으로 이뤄질 수 있습니다. 어떤 방식으로 인식할지는 구현체마다 다릅니다.

시스템 내 다른 객체들은 플랫폼 객체로 취급되지 않습니다. 예를 들어, 브라우저에서 웹 페이지가 자바스크립트 라이브러리를 불러와 DOM Core를 구현한다고 해도, 이 라이브러리에서 Node 인터페이스를 구현해 만든 객체는 브라우저 구현체가 Node를 구현한 플랫폼 객체로 취급되지 않습니다.

반면 콜백 인터페이스는 어떤 자바스크립트 객체로도 구현할 수 있습니다. 이를 통해 웹 API가 저자(사용자) 정의 연산을 호출할 수 있습니다. 예를 들어, DOM Events 구현에서는 EventListener 인터페이스를 구현한 객체를 콜백 등록에 사용할 수 있습니다.

2.13. 타입

이 절에서는 Web IDL이 지원하는 타입, 각 타입에 대응하는 값 또는 Infra 타입, 그리고 해당 타입의 상수가 어떻게 표현되는지 설명합니다.

다음 타입들은 정수 타입으로 불립니다: byte, octet, short, unsigned short, long, unsigned long, long long 그리고 unsigned long long.

다음 타입들은 숫자 타입으로 불립니다: 정수 타입, float, unrestricted float, doubleunrestricted double.

원시 타입bigint, boolean숫자 타입입니다.

문자열 타입DOMString, 모든 열거형 타입, ByteStringUSVString입니다.

버퍼 타입ArrayBufferSharedArrayBuffer입니다.

타입 배열 타입Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, Uint32Array, Uint8ClampedArray, BigInt64Array, BigUint64Array, Float16Array, Float32Array, 그리고 Float64Array입니다.

버퍼 뷰 타입DataView타입 배열 타입입니다.

버퍼 소스 타입버퍼 타입버퍼 뷰 타입입니다.

object 타입, 모든 인터페이스 타입, 그리고 모든 콜백 인터페이스 타입객체 타입으로 불립니다.

언어 바인딩별 타입에서 IDL 타입으로 변환하여 연산을 호출하거나 속성에 값을 할당하는 경우, 필요한 모든 변환은 연산 또는 속성 할당의 기능이 실행되기 전에 수행됩니다. 변환이 불가능하면 연산은 실행되지 않거나 속성이 갱신되지 않습니다. 일부 언어 바인딩에서는 타입 변환이 예외를 발생시킬 수 있으며, 이 경우 예외는 연산 실행 또는 속성 할당을 시도한 코드에 전달됩니다.

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

2.13.1. any

any 타입은 모든 다른 non-union 타입의 합집합입니다.

any 타입은 각 값이 특정 non-any 타입과 연결되어 있다는 점에서 discriminated union 타입과 유사합니다. 예를 들어, any 타입의 한 값은 unsigned long 150이고, 또 다른 값은 long 150입니다. 이 둘은 서로 다른 값입니다.

any 값의 특정 타입은 특정 타입이라고 합니다. (union 타입의 값도 특정 타입을 가집니다.)

2.13.2. undefined

undefined 타입은 고유한 값을 하나만 가집니다.

undefined 상수 값은 IDL에서 undefined 토큰으로 표현됩니다.

undefined 타입은 어떤 경우에도(연산, 콜백 함수, 생성자 연산 등) 인자 타입이나, 딕셔너리 멤버 타입(직접 또는 union 내)으로 사용해서는 안 됩니다. 대신 옵션 인자나, non-필수 딕셔너리 멤버를 사용하세요.

참고: 이 값은 이전에는 void로 표기되었으며, 사용 방식이 더 제한적이었습니다.

2.13.3. boolean

boolean 타입은 불리언과 대응됩니다.

boolean 상수 값은 IDL에서 truefalse 토큰으로 표현됩니다.

2.13.4. byte

byte 타입은 8비트 부호 있는 정수와 대응됩니다.

byte 상수 값은 IDL에서 integer 토큰으로 표현됩니다.

2.13.5. octet

octet 타입은 8비트 부호 없는 정수와 대응됩니다.

octet 상수 값은 IDL에서 integer 토큰으로 표현됩니다.

2.13.6. short

short 타입은 16비트 부호 있는 정수와 대응됩니다.

short 상수 값은 IDL에서 integer 토큰으로 표현됩니다.

2.13.7. unsigned short

unsigned short 타입은 16비트 부호 없는 정수와 대응됩니다.

unsigned short 상수 값은 IDL에서 integer 토큰으로 표현됩니다.

2.13.8. long

long 타입은 32비트 부호 있는 정수와 대응됩니다.

long 상수 값은 IDL에서 integer 토큰으로 표현됩니다.

2.13.9. unsigned long

unsigned long 타입은 32비트 부호 없는 정수와 대응됩니다.

unsigned long 상수 값은 IDL에서 integer 토큰으로 표현됩니다.

2.13.10. long long

long long 타입은 64비트 부호 있는 정수와 대응됩니다.

long long 상수 값은 IDL에서 integer 토큰으로 표현됩니다.

2.13.11. unsigned long long

unsigned long long 타입은 64비트 부호 없는 정수와 대응됩니다.

unsigned long long 상수 값은 IDL에서 integer 토큰으로 표현됩니다.

2.13.12. float

float 타입은 부동소수점 숫자 타입으로, 유한한 단정밀도 32비트 IEEE 754 부동소수점 숫자 집합에 대응합니다. [IEEE-754]

float 상수 값은 IDL에서 decimal 토큰으로 표현됩니다.

32비트 부동소수점 타입을 특별히 써야 할 이유가 없다면, doublefloat 대신 사용하는 것이 좋습니다. double이 표현할 수 있는 값 집합이 JavaScript Number와 더 유사하기 때문입니다.

2.13.13. unrestricted float

unrestricted float 타입은 부동소수점 숫자 타입으로, 모든 가능한 단정밀도 32비트 IEEE 754 부동소수점 값(유한, 무한 및 NaN)을 포함합니다. [IEEE-754]

unrestricted float 상수 값은 IDL에서 decimal 토큰으로 표현됩니다.

2.13.14. double

double 타입은 부동소수점 숫자 타입으로, 유한한 배정밀도 64비트 IEEE 754 부동소수점 숫자 집합에 대응합니다. [IEEE-754]

double 상수 값은 IDL에서 decimal 토큰으로 표현됩니다.

2.13.15. unrestricted double

unrestricted double 타입은 부동소수점 숫자 타입으로, 모든 가능한 배정밀도 64비트 IEEE 754 부동소수점 값(유한, 무한 및 NaN)을 포함합니다. [IEEE-754]

unrestricted double 상수 값은 IDL에서 decimal 토큰으로 표현됩니다.

2.13.16. bigint

bigint 타입은 범위가 제한되지 않은 임의의 정수 타입입니다.

bigint 상수 값은 IDL에서 integer 토큰으로 표현됩니다.

2.13.17. DOMString

DOMString 타입은 문자열과 대응됩니다.

참고: nullDOMString 타입의 값이 아닙니다. null을 허용하려면 널 허용 DOMString, 즉 IDL에서 DOMString?을 사용해야 합니다.

참고: DOMString 값에는 매치되지 않는 서로게이트 코드 포인트가 포함될 수 있습니다. 이를 원하지 않는 경우 USVString을 사용하세요.

IDL에서는 DOMString 상수 값을 표현할 방법이 없습니다. 다만 DOMString 딕셔너리 멤버 기본값이나 연산 옵션 인자 기본값에는 문자열 리터럴 토큰의 값을 사용할 수 있습니다.

2.13.18. ByteString

ByteString 타입은 바이트 시퀀스와 대응됩니다.

IDL에서는 ByteString 상수 값을 표현할 방법이 없습니다. 다만 ByteString 딕셔너리 멤버 기본값이나 연산 옵션 인자 기본값에는 문자열 리터럴 토큰의 값을 사용할 수 있습니다.

명세서는 ByteString을 바이트와 문자열이 혼용되는 프로토콜(예: HTTP)과 인터페이스할 때만 사용해야 합니다. 일반적으로 문자열은 DOMString 값으로 표현해야 하며, 값이 항상 ASCII나 8비트 문자 인코딩일 것으로 예상되더라도 DOMString을 사용해야 합니다. 8비트 데이터는 시퀀스불변 배열(octet, byte 요소), Uint8Array 또는 Int8Array를 써야 하며 ByteString을 쓰지 않아야 합니다.

2.13.19. USVString

USVString 타입은 스칼라 값 문자열에 대응합니다. 문맥에 따라 코드 유닛 또는 스칼라 값 시퀀스로 처리될 수 있습니다.

IDL에서는 USVString 상수 값을 표현할 방법이 없습니다. 다만 USVString 딕셔너리 멤버 기본값이나 연산 옵션 인자 기본값에는 문자열 리터럴 토큰의 값을 사용할 수 있습니다.

명세서는 USVString을 텍스트 처리 API에서 스칼라 값 문자열이 필요한 경우에만 써야 합니다. 대부분의 문자열 사용 API에서는 DOMString을 써야 하며, 해당 문자열의 코드 유닛을 해석하지 않습니다. 헷갈릴 경우 DOMString을 사용하세요.

2.13.20. object

object 타입은 가능한 모든 non-null 객체 참조 집합에 대응합니다.

IDL에서는 object 상수 값을 표현할 방법이 없습니다.

모든 객체 참조와 null 값을 포함하는 타입을 지정하려면 널 허용 타입 object?를 사용하세요.

2.13.21. symbol

symbol 타입은 모든 가능한 심볼 값 집합에 대응합니다. 심볼 값은 불투명하며, object 값은 아니지만 고유성(자기 자신과만 같음)을 가집니다.

IDL에서는 symbol 상수 값을 표현할 방법이 없습니다.

2.13.22. 인터페이스 타입

식별자인터페이스를 지정하면, 해당 인터페이스를 구현하는 non-null 객체 참조의 집합을 타입으로 참조합니다.

인터페이스 타입의 IDL 값은 객체 참조로 표현됩니다.

특정 인터페이스 타입에 대한 상수 객체 참조 값을 IDL에서 표현할 방법은 없습니다.

해당 인터페이스를 구현하는 객체 참조와 null을 모두 포함하는 타입을 지정하려면 널 허용 타입을 사용하세요.

2.13.23. 콜백 인터페이스 타입

식별자콜백 인터페이스를 지정하면, 모든 가능한 non-null 객체 참조 집합을 타입으로 참조합니다.

콜백 인터페이스 타입의 IDL 값은 객체 참조와 콜백 컨텍스트의 튜플로 표현됩니다. 콜백 컨텍스트는 언어 바인딩별 값이며, 객체 참조를 IDL 값으로 변환할 때의 실행 컨텍스트 정보를 저장하는 데 사용됩니다.

참고: 자바스크립트 객체에서는 콜백 컨텍스트에 Object 값이 IDL 콜백 인터페이스 타입 값으로 변환될 때의 incumbent settings object 참조가 저장됩니다. § 3.2.16 Callback interface types 참고.

특정 콜백 인터페이스 타입에 대한 상수 객체 참조 값을 IDL에서 표현할 방법은 없습니다.

모든 객체 참조와 null을 포함하는 타입을 지정하려면 널 허용 타입을 사용하세요.

2.13.24. 딕셔너리 타입

식별자딕셔너리를 지정하면, 해당 딕셔너리 정의를 따르는 모든 딕셔너리 집합을 타입으로 참조합니다.

순서 있는 맵의 리터럴 문법도, 맵이 특정 딕셔너리 타입 인스턴스로 간주된다는 게 문맥에서 명확하다면 딕셔너리 표현에 사용할 수 있습니다. 그러나 IDL 프래그먼트 내에 상수 딕셔너리 값을 표현하는 방법은 없습니다.

2.13.25. 열거형 타입

식별자열거형을 지정하면, 값이 해당 열거형 값 집합인 문자열(코드 유닛 시퀀스, DOMString과 동일) 타입을 참조합니다.

DOMString과 마찬가지로, IDL에서는 열거형 상수 값을 표현할 방법이 없습니다. 다만 열거형 타입 딕셔너리 멤버 기본값이나 연산 옵션 인자 기본값에는 문자열 리터럴 토큰의 값을 사용할 수 있습니다.

2.13.26. 콜백 함수 타입

식별자콜백 함수를 지정하면, 해당 시그니처의 함수 객체 참조 집합을 타입으로 참조합니다.

참고: [LegacyTreatNonObjectAsNull] 확장 속성이 콜백 함수 정의에 지정된 경우, 함수가 아닌 객체 참조도 값이 될 수 있습니다.

콜백 함수 타입의 IDL 값은 객체 참조와 콜백 컨텍스트의 튜플로 표현됩니다.

참고: 콜백 인터페이스 타입과 마찬가지로, 콜백 컨텍스트는 자바스크립트 Object 값이 IDL 콜백 함수 타입 값으로 변환될 때의 incumbent settings object 참조를 저장하는 데 쓰입니다. § 3.2.19 Callback function types 참고.

IDL에서는 콜백 함수 상수 값을 표현할 방법이 없습니다.

2.13.27. 널 허용 타입 — T?

널 허용 타입은 기존 타입(이를 내부 타입이라 함)에서 null 값을 추가로 허용하는 IDL 타입입니다. 널 허용 타입은 IDL에서 기존 타입 뒤에 U+003F(?)를 붙여 표기합니다. 내부 타입은 다음 중 하나가 아니어야 합니다:

참고: 딕셔너리 타입은 일반적으로 널 허용이 가능하지만, 연산 인자나 딕셔너리 멤버 타입으로는 허용되지 않습니다.

널 허용 타입 상수 값은 IDL에서 내부 타입 상수 값과 동일하게 표현하거나 null 토큰으로 표현됩니다.

예를 들어, true, false, null 값을 허용하는 타입은 boolean?으로 표기합니다:

[Exposed=Window]
interface NetworkFetcher {
  undefined get(optional boolean? areWeThereYet = false);
};

다음 인터페이스에는 두 개의 속성이 있습니다. 하나는 DOMString 또는 null 값을 가질 수 있고, 다른 하나는 Node 객체 참조 또는 null 값을 가질 수 있습니다:

[Exposed=Window]
interface Node {
  readonly attribute DOMString? namespaceURI;
  readonly attribute Node? parentNode;
  // ...
};

2.13.28. 시퀀스 타입 — sequence<T>

sequence<T> 타입은 (길이가 0일 수도 있는) 리스트로, 각 값이 T 타입인 리스트 타입입니다.

시퀀스는 항상 값으로 전달됩니다. 시퀀스가 어떤 객체로 표현되는 언어 바인딩에서는, 시퀀스를 플랫폼 객체에 전달해도 해당 객체에 시퀀스 참조가 남지 않습니다. 마찬가지로 플랫폼 객체에서 반환된 시퀀스도 복사본이며, 이를 수정해도 플랫폼 객체에는 영향을 미치지 않습니다.

리스트의 리터럴 문법도, 리스트가 시퀀스 타입 인스턴스로 간주된다는 게 문맥에서 명확하다면 시퀀스 표현에 사용할 수 있습니다. 하지만 IDL 프래그먼트 내에 상수 시퀀스 값을 표현하는 방법은 없습니다.

시퀀스는 속성이나 상수 타입으로 사용할 수 없습니다.

참고: 이 제한은 명세 작성자와 API 사용자에게 시퀀스가 참조가 아닌 복사본으로 전달된다는 점을 명확히 하기 위한 것입니다. 시퀀스 타입의 속성 대신, 시퀀스를 get/set하는 연산을 쌍으로 제공하는 것이 좋습니다.

어떤 리스트도, 그 항목이 모두 T 타입이면 암묵적으로 sequence<T>로 간주할 수 있습니다.

2.13.29. 비동기 시퀀스 타입 — async_sequence<T>

async_sequence 타입T 타입 값을 비동기적으로 이터레이션할 수 있는(무한 가능성 포함) 객체 참조 집합을 타입으로 하는 파라미터화 타입입니다.

시퀀스와 달리, 비동기 시퀀스는 고정 길이 리스트가 아니라 모든 값이 미리 알려진 상태가 아닙니다. async_sequence로 생성된 비동기 이터러블 시퀀스는 lazy하며, 값은 이터레이션 중에만 비동기적으로 생성될 수 있으므로, 값이나 길이는 시퀀스 생성 시점에 알 수 없습니다.

언어 바인딩에서 async_sequence가 객체로 표현되는 경우 참조로 전달됩니다. 즉, async_sequence를 플랫폼 객체에 전달하면 해당 객체에 참조가 남습니다. 플랫폼 객체에서 반환된 async_sequence도 동일 객체에 대한 참조이며, 이를 수정하면 플랫폼 객체에 영향을 미칩니다. 이는 항상 값으로 전달되는 시퀀스와는 다릅니다.

참고: async_sequence는 IDL에서 생성할 수 없습니다. 연산에서 반환하거나 딕셔너리 멤버 타입으로 쓸 경우, async_sequence는 호스트 환경에서 생성되어 언어 바인딩을 통해 IDL 타입으로 변환된 것입니다. 연산에서 async_sequence를 반환하는 대신, 인터페이스를 반환하고 그 인터페이스에 비동기 이터러블 선언을 둬야 할 수 있습니다.

async_sequence는 속성이나 상수 타입으로 사용할 수 없습니다.

IDL에서는 async_sequence 값을 표현할 방법이 없습니다.

2.13.30. 레코드 타입 — record<K, V>

레코드 타입은 파라미터화된 타입으로, 값이 순서가 있는 맵이며, K 타입의 인스턴스, V 타입의 인스턴스입니다. KDOMString, USVString, 또는 ByteString 중 하나여야 합니다.

순서가 있는 맵의 리터럴 문법도, 맵이 레코드로 간주된다는 게 문맥에서 명확하다면 레코드 표현에 사용할 수 있습니다. 하지만 IDL 프래그먼트 내에 상수 레코드 값을 표현하는 방법은 없습니다.

레코드는 항상 값으로 전달됩니다. 레코드가 어떤 객체로 표현되는 언어 바인딩에서는, 레코드를 플랫폼 객체에 전달해도 해당 객체에 레코드 참조가 남지 않습니다. 마찬가지로 플랫폼 객체에서 반환된 레코드도 복사본이며, 이를 수정해도 플랫폼 객체에는 영향을 미치지 않습니다.

레코드는 속성이나 상수 타입으로 사용할 수 없습니다.

어떤 순서가 있는 맵도, 모든 엔트리K 타입이고 V 타입이면 암묵적으로 record<K, V>로 간주할 수 있습니다.

2.13.31. 프라미스 타입 — Promise<T>

프라미스 타입은 파라미터화된 타입으로, 값이 비동기 작업의 결과를 나중에 받을 수 있는 “자리 표시자” 객체 참조입니다. 자세한 프라미스 객체 의미는 JavaScript 명세 section 25.4 참고.

프라미스 타입은 널 허용이 아니지만, T는 널 허용일 수 있습니다.

IDL에서는 프라미스 값을 표현할 방법이 없습니다.

2.13.32. 유니온 타입

유니온 타입은 값 집합이 두 개 이상의 타입 값 집합의 합집합이 되는 타입입니다. 유니온 타입(UnionType에 일치)은 타입들을 or로 구분해 괄호로 감싸 표기합니다. 유니온 타입을 구성하는 타입들을 유니온의 멤버 타입이라 합니다.

예를 들어 (Node or DOMString) 또는 (double or sequence<double>)처럼 쓸 수 있습니다. 유니온 타입 전체에 ?를 붙일 때는 닫는 괄호 뒤에 붙여 (Node or DOMString)?처럼 표기합니다.

유니온 타입의 멤버 타입은 중첩된 유니온 타입 안까지 내려가지 않습니다. 예를 들어 (double or (sequence<long> or Event) or (Node or DOMString)?)의 멤버 타입은 double, (sequence<long> or Event), (Node or DOMString)?입니다.

any 타입처럼, 유니온 타입 값도 특정 타입을 가지며, 이는 해당 값과 일치하는 멤버 타입입니다.

평탄화된 멤버 타입은 (어노테이트된 타입 포함) 다음과 같이 결정합니다:

  1. T를 유니온 타입으로 둔다.

  2. S를 ∅로 초기화한다.

  3. T의 각 멤버 타입 U에 대해:

    1. U어노테이트 타입이면 U를 그 내부 타입으로 둔다.

    2. U널 허용 타입이면 U를 그 내부 타입으로 둔다.

    3. U유니온 타입이면 SU평탄화된 멤버 타입들을 추가한다.

    4. 그 외에는 U가 유니온 타입이 아니므로 US에 추가한다.

  4. S를 반환한다.

참고: 예를 들어, 유니온 타입 (Node or (sequence<long> or Event) or (XMLHttpRequest or DOMString)? or sequence<(sequence<double> or NodeList)>)평탄화된 멤버 타입Node, sequence<long>, Event, XMLHttpRequest, DOMString, sequence<(sequence<double> or NodeList)>입니다.

널 허용 멤버 타입 개수는 유니온 타입에서 다음과 같이 결정합니다:

  1. T를 유니온 타입으로 둔다.

  2. n을 0으로 초기화한다.

  3. T의 각 멤버 타입 U에 대해:

    1. U널 허용 타입이면:

      1. nn+1로 한다.

      2. U를 그 내부 타입으로 둔다.

    2. U유니온 타입이면:

      1. mU널 허용 멤버 타입 개수로 둔다.

      2. nn+m로 한다.

  4. n을 반환한다.

any 타입은 유니온 멤버 타입으로 사용해서는 안 됩니다.

널 허용 멤버 타입 개수는 반드시 0 또는 1이어야 하고, 1인 경우 유니온 타입의 평탄화된 멤버 타입딕셔너리 타입이 포함되어 있으면 안 됩니다.

널 허용 타입을 포함한다란 다음 중 하나면 참입니다:

유니온 타입의 모든 평탄화된 멤버 타입 쌍(T, U)은 구분 가능해야 합니다.

bigint숫자 타입의 유니온을 만들 수 있습니다. 하지만 이는 일반적으로 NumberFormat처럼 값을 계산이 아닌 포맷에 사용하는 인터페이스에서만 써야 합니다. 숫자 타입 값을 bigint로 변환해 처리하면 정밀도 문제가 생길 수 있습니다. 이 기능을 쓰기 전에 반드시 이슈를 등록하세요.

undefined를 포함한다란 다음 중 하나면 참입니다:

유니온 타입의 상수 값은 각 멤버 타입의 상수 값과 동일하게 표현됩니다.

UnionType ::
    ( UnionMemberType or UnionMemberType UnionMemberTypes )
UnionMemberType ::
    ExtendedAttributeList DistinguishableType
    UnionType Null
UnionMemberTypes ::
    or UnionMemberType UnionMemberTypes
    ε
DistinguishableType ::
    PrimitiveType Null
    StringType Null
    identifier Null
    sequence < TypeWithExtendedAttributes > Null
    async_sequence < TypeWithExtendedAttributes > Null
    object Null
    symbol Null
    BufferRelatedType Null
    FrozenArray < TypeWithExtendedAttributes > Null
    ObservableArray < TypeWithExtendedAttributes > Null
    RecordType Null
    undefined Null

2.13.33. 주석 타입

특정 확장 속성을 기존 타입에 지정하면 추가 타입을 만들 수 있습니다. 이러한 타입을 주석 타입이라 하며, 이들이 주석을 다는 타입을 내부 타입이라 합니다.

[Clamp] long주석 타입을 정의합니다. 이 타입은 내부 타입 long의 동작을 기반으로 하지만, [Clamp] 확장 속성에 지정된 대로 동작이 수정됩니다.

아래 확장 속성들이 타입에 적용 가능합니다: [AllowResizable], [AllowShared], [Clamp], [EnforceRange], 그리고 [LegacyNullToEmptyString].

타입에 연관된 확장 속성은 IDL 타입 type에 대해 다음과 같이 결정합니다:
  1. extended attributes를 새로운 빈 집합으로 둔다.

  2. typeTypeWithExtendedAttributes 생성식 일부에 등장하면, 그 생성식의 ExtendedAttributeList에 있는 확장 속성을 모두 extended attributes에 추가한다.

    [Exposed=Window]
    interface I {
        attribute [XAttr] long attrib;
        undefined f1(sequence<[XAttr] long> arg);
        undefined f2(optional [XAttr] long arg);
    
        maplike<[XAttr2] DOMString, [XAttr3] long>;
    };
    
    dictionary D {
        required [XAttr] long member;
    };
    
  3. type이 유니온 타입 U멤버 타입이면, U연관된 확장 속성을 모두 extended attributes에 추가한다.

    [Exposed=Window]
    interface I {
        attribute [XAttr] (long or Node) attrib;
    };
    
  4. typeType 생성식에 등장하고, 그 생성식이 Argument 생성식 바로 내부에 있다면, 해당 ExtendedAttributeList에 타입 적용 가능 확장 속성이 있으면 그걸 extended attributes에 추가한다.

    [Exposed=Window]
    interface I {
        undefined f([XAttr] long attrib);
    };
    

    이 예시는 [XAttr]이 타입 적용 가능일 때만 해당 단계 예시입니다. 아니라면 [XAttr]은 인자에 적용되고 타입에는 적용되지 않습니다.

  5. typeType 생성식에 등장하고, 그 생성식이 DictionaryMember 생성식 바로 내부에 있다면, 해당 ExtendedAttributeList에 타입 적용 가능 확장 속성이 있으면 그걸 extended attributes에 추가한다.

    dictionary D {
        [XAttr] long member;
    };
    

    이 예시는 [XAttr]이 타입 적용 가능일 때만 해당 단계 예시입니다. 아니라면 [XAttr]은 딕셔너리 멤버에 적용되고 타입에는 적용되지 않습니다.

  6. typetypedef이면, 그 새 이름을 부여받는 타입연관된 확장 속성을 추가한다.

    typedef [XAttr] long xlong;
    
  7. extended attributes를 반환한다.

어떤 타입이든 그 연관된 확장 속성에는 확장 속성타입 적용 가능만 포함되어야 합니다.

2.13.34. 버퍼 소스 타입

데이터 버퍼나 버퍼 뷰 객체에 대한 모든 non-null 참조 집합에 대응하는 타입들이 있습니다. 아래 표는 각 타입과 해당 타입이 표현하는 버퍼/뷰 종류를 나타냅니다.

타입 버퍼 종류
ArrayBuffer 고정된 바이트 수의 버퍼를 가리키는 포인터(널 가능)를 가진 객체
SharedArrayBuffer 고정된 바이트 수의 공유 버퍼를 가리키는 포인터(널 불가)를 가진 객체
DataView 임의 오프셋에서 정수, 부동소수점 값을 타입별로 접근할 수 있는 버퍼 타입 인스턴스의 뷰
Int8Array 버퍼 타입 인스턴스를 주어진 비트 크기의 2의 보수 부호 있는 정수 배열로 노출하는 뷰
Int16Array
Int32Array
BigInt64Array
Uint8Array 버퍼 타입 인스턴스를 주어진 비트 크기의 부호 없는 정수 배열로 노출하는 뷰
Uint16Array
Uint32Array
BigUint64Array
Uint8ClampedArray 버퍼 타입 인스턴스를 8비트 부호 없는 정수 배열로 노출하며, 값은 클램프 변환됨
Float16Array 버퍼 타입 인스턴스를 지정된 비트 크기의 IEEE 754 부동소수점 숫자 배열로 노출하는 뷰; Float16Array는 ECMAScript 제안 [PROPOSAL-FLOAT16ARRAY]에 해당함.
Float32Array
Float64Array

참고: 이 타입들은 모두 JavaScript에서 정의된 클래스에 해당합니다.

IDL에서는 이러한 타입의 상수 값을 표현할 방법이 없습니다.

명세 산문(prose) 수준에서, IDL 버퍼 소스 타입은 단순히 객체 참조입니다. 버퍼 내부 바이트를 조회/조작하려면 명세 산문에서 § 3.2.26 버퍼 소스 타입 알고리즘을 사용해야 합니다.

BufferRelatedType ::
    ArrayBuffer
    SharedArrayBuffer
    DataView
    Int8Array
    Int16Array
    Int32Array
    Uint8Array
    Uint16Array
    Uint32Array
    Uint8ClampedArray
    BigInt64Array
    BigUint64Array
    Float16Array
    Float32Array
    Float64Array

2.13.35. 불변 배열 타입 — FrozenArray<T>

불변 배열 타입은 파라미터화된 타입으로, 값이 고정 길이의 수정 불가 값 배열을 가진 객체 참조입니다. 배열의 각 값은 T 타입입니다.

불변 배열 타입은 인터페이스에 정의된 일반 속성이나 static 속성 타입으로만 사용해야 합니다.

다음 IDL 프래그먼트는 두 개의 불변 배열 속성이 있는 인터페이스를 정의합니다. 하나는 읽기 전용이고 하나는 읽기 전용이 아닙니다.
[Exposed=Window]
interface PersonalPreferences {
    readonly attribute FrozenArray<DOMString> favoriteColors;
    attribute FrozenArray<DOMString> favoriteFoods;

    undefined randomizeFavoriteColors();
};

이 속성들의 동작 정의 예시:

PersonalPreferencesfavorite colors(FrozenArray<DOMString>)를 갖고, 초기값은 « "purple", "aquamarine" »로 불변 배열 생성 결과입니다.

PersonalPreferencesfavorite foods(FrozenArray<DOMString>)도 갖고, 초기값은 빈 리스트로 불변 배열 생성 결과입니다.

favoriteColors getter 단계this의 favorite colors를 반환합니다.

favoriteFoods getter 단계this의 favorite foods를 반환합니다.

favoriteFoods setter 단계this의 favorite foods를 지정 값으로 설정합니다.

randomizeFavoriteColors() 메서드 단계는:

  1. newFavoriteColors를 임의로 선택한 색상 2개의 문자열 리스트로 둔다.

  2. this의 favorite colors를 불변 배열 생성(newFavoriteColors) 결과로 설정.

FrozenArray<T> 값은 참조이므로, 시퀀스 타입처럼 값으로 전달되는 리스트와는 다릅니다.

IDL에서는 불변 배열 상수 값을 표현할 방법이 없습니다.

2.13.36. 관찰 배열 타입 — ObservableArray<T>

관찰 배열 타입은 파라미터화된 타입으로, 값이 T 타입 객체의 변경 가능한 리스트와, 저자 코드가 리스트를 수정할 때 실행되는 동작을 결합한 객체 참조입니다.

파라미터화 타입 T딕셔너리 타입, 시퀀스 타입, 레코드 타입, 관찰 배열 타입이 될 수 없습니다. 하지만 T는 널 허용일 수 있습니다.

시퀀스 타입불변 배열 타입처럼, 관찰 배열 타입도 자바스크립트 배열 타입을 감싸며 추가 의미를 부여합니다.

관찰 배열 타입은 인터페이스에 정의된 일반 속성 타입으로만 사용해야 합니다.

관찰 배열 속성에는 명세 저자가 다음 알고리즘을 정의할 수 있습니다:

이 두 알고리즘은 모두 선택적이며, 정의되지 않으면 기본 동작은 아무것도 하지 않는 것입니다. 두 알고리즘 모두 예외를 throw할 수 있습니다(예: 값이 잘못된 경우 거부).

자바스크립트 코드가 기존 인덱스에 새 값을 설정하면, 먼저 인덱스 값 삭제 알고리즘이 실행되어 기존 값을 삭제하고, 그 다음 인덱스 값 설정 알고리즘이 새 값을 설정합니다.

관찰 배열 타입인 일반 속성마다 백킹 리스트가 있으며, 이는 리스트로, 초깃값은 빈 리스트입니다. 명세 저자는 백킹 리스트 내용을 수정할 수 있고, 이는 자바스크립트에서 관찰 배열 내용에도 즉시 반영됩니다. 마찬가지로 자바스크립트 코드가 관찰 배열을 수정하면 인덱스 값 설정, 인덱스 값 삭제 알고리즘을 거쳐 백킹 리스트에도 반영됩니다.

IDL에서는 관찰 배열 상수 값을 표현할 방법이 없습니다.

다음 IDL 프래그먼트는 관찰 배열 속성이 있는 인터페이스를 정의합니다:
[Exposed=Window]
interface Building {
  attribute ObservableArray<Employee> employees;
};

이 속성의 동작 정의 예시:

Buildingemployees 속성에 대해 인덱스 값 설정 알고리즘(인자: employee, index):
  1. employee가 오늘 건물 출입 불가이면 "NotAllowedError" DOMException을 throw.

  2. index가 200 이상이면 QuotaExceededError를 throw하고, quota는 200, requestedindex로 설정.

  3. employee를 업무에 투입!

Buildingemployees 속성에 대해 인덱스 값 삭제 알고리즘(인자: employee, index):

  1. employee가 건물을 떠났음을 경비에 알림.

자바스크립트 코드에서 employees 프로퍼티를 아래와 같이 조작할 수 있습니다:

// 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될 수 있습니다. 또한 해당 사이드 이펙트는 인덱스 값 삭제 알고리즘에서 정의된 대로 실행됩니다.

위 JS 예시에서 자바스크립트 배열 메서드가 관찰 배열에 모두 동작하는 점도 주목하세요. 실제로 Array 인스턴스처럼 동작합니다:

const normalArray = [];

// 만약 building.employees가 인덱스 프로퍼티 getter 인터페이스였다면: normalArray에 building.employees 하나만 들어감.
//
// 관찰 배열(및 불변 배열)의 경우: normalArray에는 building.employees의 모든 항목이 들어감.
normalArray.concat(building.employees);

// names는 JS Array임.
const names = building.employees.map(employee => employee.name);

// 브랜드 체크 통과:
console.assert(building.employees instanceof Array);
console.assert(Array.isArray(building.employees));
console.assert(building.employees.constructor === Array);

// JSON.stringify에도 배열로 취급됨! (바깥 [] 참조.)
console.assert(JSON.stringify(building.employees) === `[{}]`);

2.14. 확장 속성

확장 속성은 주석(annotation)으로서 정의, 주석 타입, 인터페이스 멤버, 인터페이스 믹스인 멤버, 콜백 인터페이스 멤버, 네임스페이스 멤버, 딕셔너리 멤버, 연산 인자에 붙을 수 있으며, 언어 바인딩이 해당 구조체를 어떻게 처리할지 제어한다. 확장 속성은 ExtendedAttributeList로 지정하며, 대괄호로 감싼 쉼표 구분 리스트 형식의 ExtendedAttribute들이다.

ExtendedAttribute 문법 기호는 거의 모든 토큰 시퀀스와 일치하지만, 이 문서에서 정의하는 확장 속성은 더 제한된 문법만 허용한다. IDL 프래그먼트에서 만난 확장 속성은 아래 문법 기호들과 일치하는지 따져서 어떤 형태인지 결정한다:

문법 기호 형태 예시
ExtendedAttributeNoArgs 인자 없음 [Replaceable]
ExtendedAttributeArgList 인자 리스트 있음 현재 사용되지 않음; 과거에는 [Constructor(double x, double y)]처럼 사용됨
ExtendedAttributeNamedArgList 이름 있는 인자 리스트 있음 [LegacyFactoryFunction=Image(DOMString src)]
ExtendedAttributeIdent 식별자 있음 [PutForwards=name]
ExtendedAttributeString 문자열 있음 [Reflect="popover"]
ExtendedAttributeInteger 정수 있음 [ReflectDefault=2]
ExtendedAttributeDecimal 실수 있음 [ReflectDefault=2.0]
ExtendedAttributeIntegerList 정수 리스트 있음 [ReflectRange=(2, 600)]
ExtendedAttributeIdentList 식별자 리스트 있음 [Exposed=(Window,Worker)]
ExtendedAttributeWildcard 와일드카드 있음 [Exposed=*]

이 현행 표준에서는 JavaScript 바인딩에 적용되는 여러 확장 속성을 정의하며, § 3.3 확장 속성에서 설명한다. 각 확장 속성 정의에는 위 다섯 가지 중 어떤 형태를 허용하는지 명시된다.

ExtendedAttributeList ::
    [ ExtendedAttribute ExtendedAttributes ]
    ε
ExtendedAttributes ::
    , ExtendedAttribute ExtendedAttributes
    ε
ExtendedAttribute ::
    ( ExtendedAttributeInner ) ExtendedAttributeRest
    [ ExtendedAttributeInner ] ExtendedAttributeRest
    { ExtendedAttributeInner } ExtendedAttributeRest
    Other ExtendedAttributeRest
ExtendedAttributeRest ::
    ExtendedAttribute
    ε
ExtendedAttributeInner ::
    ( ExtendedAttributeInner ) ExtendedAttributeInner
    [ ExtendedAttributeInner ] ExtendedAttributeInner
    { ExtendedAttributeInner } ExtendedAttributeInner
    OtherOrComma ExtendedAttributeInner
    ε
Other ::
    integer
    decimal
    identifier
    string
    other
    -
    -Infinity
    .
    ...
    :
    ;
    <
    =
    >
    ?
    *
    ByteString
    DOMString
    FrozenArray
    Infinity
    NaN
    ObservableArray
    Promise
    USVString
    any
    bigint
    boolean
    byte
    double
    false
    float
    long
    null
    object
    octet
    or
    optional
    record
    sequence
    short
    symbol
    true
    unsigned
    undefined
    ArgumentNameKeyword
    BufferRelatedType
OtherOrComma ::
    Other
    ,
IdentifierList ::
    identifier Identifiers
Identifiers ::
    , identifier Identifiers
    ε
IntegerList ::
    integer Integers
Integers ::
    , integer Integers
    ε
ExtendedAttributeNoArgs ::
    identifier
ExtendedAttributeArgList ::
    identifier ( ArgumentList )
ExtendedAttributeIdent ::
    identifier = identifier
ExtendedAttributeString ::
    identifier = string
ExtendedAttributeInteger ::
    identifier = integer
ExtendedAttributeDecimal ::
    identifier = decimal
ExtendedAttributeWildcard ::
    identifier = *
ExtendedAttributeIdentList ::
    identifier = ( IdentifierList )
ExtendedAttributeIntegerList ::
    identifier = ( IntegerList )
ExtendedAttributeNamedArgList ::
    identifier = identifier ( ArgumentList )

3. 자바스크립트 바인딩

이 절에서는 § 2 인터페이스 정의 언어에 정의된 IDL로 작성된 정의들이 ECMAScript 언어 명세 [ECMA-262]에 규정된 자바스크립트의 특정 구조와 어떻게 대응되는지 설명한다.

별도 명시 없으면, 이 절에서 정의된 객체는 ECMAScript § 10.1 일반 객체 내부 메서드와 내부 슬롯에 기술된 일반 객체이며, 객체가 함수 객체라면 ECMAScript § 10.3 내장 함수 객체에 따른다.

이 절에서는 객체의 내부 메서드와 내부 슬롯 일부를 재정의할 수 있다. 다른 현행 표준 또한 인터페이스의 인스턴스인 플랫폼 객체의 내부 메서드나 내부 슬롯 정의를 재정의할 수 있다. 이렇게 의미가 변경된 객체는 특이 객체 규칙에 따라 다뤄져야 한다.

자바스크립트 객체의 내부 메서드를 재정의하는 것은 저수준 작업이며, 일반 객체와 다르게 동작할 수 있으므로, 보안이나 호환성 등 꼭 필요한 경우에만 써야 한다. 현재 HTMLAllCollectionLocation 인터페이스 정의에 사용됨. [HTML]

별도 명시 없으면, 이 절 및 다른 현행 표준에서 정의된 특이 객체(Exotic Object)는 일반 객체와 동일한 내부 슬롯을 가지며, 별도 정의가 없는 모든 내부 메서드는 일반 객체와 동일하다.

별도 명시 없으면, 이 절에서 정의된 객체의 [[Extensible]] 내부 슬롯 값은 true이다.

별도 명시 없으면, 이 절에서 정의된 객체의 [[Prototype]] 내부 슬롯 값은 %Object.prototype%이다.

이 절에서 설명하는 일부 객체는 클래스 문자열을 가진다. 클래스 문자열은 Object.prototype.toString의 반환 문자열에 포함되는 값이다.

객체가 클래스 문자열 classString을 가지면, 생성 시점에 해당 객체는 %Symbol.toStringTag% 심볼 이름의 프로퍼티를 가져야 하며, PropertyDescriptor{[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true, [[Value]]: classString}로 설정한다.

이 절의 알고리즘은 ECMAScript § 5.2 알고리즘 규칙(단계와 하위 단계, 수학 연산 등) 및 ECMA-262의 다른 부분에서 정의된 추상 연산·표기법을 따른다.

알고리즘에서 throw SomethingError 라고 하면, 이는 현재 realm에서 새로운 자바스크립트 SomethingError 객체를 생성해 throw하는 것을 의미하며, ECMA-262 알고리즘과 동일하다.

알고리즘 단계에서 다른 알고리즘이나 추상 연산을 호출하고, 그 과정에서 예외가 명시적으로 처리되지 않는 경우, 예외가 발생하면 알고리즘 실행은 중단되고 예외가 호출자에게 전달된다.

다음 알고리즘을 보자:

  1. x를 이 알고리즘에 전달된 자바스크립트 값으로 둔다.

  2. y? ToString(x) 호출 결과로 둔다.

  3. y를 반환한다.

ToString은 예외를 throw할 수 있다(예: ({ toString: function() { throw 1 } }) 전달 시). 위 알고리즘에서 예외가 처리되지 않으므로, 예외가 발생하면 알고리즘 실행은 중단되고 예외가 호출자에게 전달된다.

3.1. 자바스크립트 환경

주어진 IDL 프래그먼트 집합의 자바스크립트 구현에서는, 해당 IDL 프래그먼트에 정의된 객체에 대응되는 여러 자바스크립트 객체가 존재한다. 이 객체들을 초기 객체라 하며, 다음을 포함한다:

realm에는 고유한 초기 객체 집합이 있어야 하며, 해당 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;                        // false 반환 (ECMA-262 준수)
Node == w.Node;                            // false 반환
iframe instanceof w.Node;                  // false 반환
iframe instanceof w.Object;                // false 반환
iframe.appendChild instanceof Function;    // true 반환
iframe.appendChild instanceof w.Function;  // false 반환
</script>

참고: 모든 인터페이스는 어떤 realm노출되는지 정의한다. 예를 들어, Web Worker용 realm은 웹 페이지 realm과 노출되는 인터페이스 집합이 다를 수 있다.

작성 시점에서 자바스크립트 명세에는 반영되지 않았으나, 모든 자바스크립트 객체는 연결된 realm을 가져야 한다. 객체와 realm을 연결하는 메커니즘은 아직 명확히 규정되지 않았으나, 플랫폼 객체의 경우 연결된 realm은 객체의 관련 realm과 동일하며, 특이하지 않은 함수 객체(즉, 호출 가능 프록시나 bound 함수가 아닌 경우)는 [[Realm]] 내부 슬롯의 값이 연결된 realm이다.

3.2. 자바스크립트 타입 매핑

이 절에서는 IDL의 타입이 자바스크립트 타입에 어떻게 매핑되는지 설명한다.

아래 각 하위 절에서는 특정 IDL 타입 값이 자바스크립트에서 어떻게 표현되는지 설명한다. 각 IDL 타입마다, 자바스크립트 값이 해당 타입을 기대하는 플랫폼 객체에 전달될 때 어떻게 IDL 값으로 변환되는지와, 해당 타입의 IDL 값이 플랫폼 객체에서 반환될 때 어떻게 자바스크립트 값으로 변환되는지를 설명한다.

아래 하위 절과 알고리즘은, 타입 헤더에 명시된 타입에 확장 속성을 적용해 만든 주석 타입에도 동일하게 적용된다.

3.2.1. any

IDL any 타입은 모든 다른 IDL 타입의 합집합이므로, 모든 자바스크립트 값 타입에 대응될 수 있다.

자바스크립트 값 VIDL 값으로 변환해 IDL any 값으로 만드는 알고리즘:

  1. Vundefined이면, 고유한 undefined IDL 값을 반환한다.

  2. Vnull이면, null object? 참조를 반환한다.

  3. V불리언이면, 동일한 진릿값을 나타내는 boolean 값을 반환한다.

  4. V숫자이면, V를 unrestricted double로 변환한 결과를 반환한다.

  5. VBigInt이면, V를 bigint로 변환한 결과를 반환한다.

  6. V문자열이면, V를 DOMString으로 변환한 결과를 반환한다.

  7. V심볼이면, V를 symbol로 변환한 결과를 반환한다.

  8. V객체이면, V를 참조하는 IDL object 값을 반환한다.

IDL any 값은 자바스크립트 값으로 변환될 때, 해당 IDL any 값의 특정 타입에 대해 아래 절에서 설명한 변환 규칙을 따른다.

3.2.2. undefined

자바스크립트 값 VIDL 값으로 변환undefined 값으로 만들 때는, V를 무시하고 고유한 undefined 값을 반환한다.

고유한 IDL undefined 값은 자바스크립트 값으로 변환될 때 자바스크립트 undefined 값이 된다.

3.2.3. boolean

자바스크립트 값 VIDL 값으로 변환boolean 값으로 만드는 알고리즘:

  1. xToBoolean(V) 결과로 둔다.

  2. 자바스크립트 불리언 값 x와 동일한 진릿값을 나타내는 IDL boolean 값을 반환한다.

IDL booleantrue자바스크립트 값으로 변환될 때 자바스크립트 true 값이 되고, false는 자바스크립트 false 값이 된다.

3.2.4. 정수 타입

이 절에서 사용하는 수학 연산은, ECMAScript § 5.2 알고리즘 규칙에 정의된 것 포함, 수학적 실수에 대한 정확한 수학적 결과를 의미한다.

즉, x가 Number 값일 때, “x에 대해 연산한다”는 것은 “x와 동일한 수치 값을 가진 수학적 실수에 대해 연산한다”의 약어이다.

3.2.4.1. byte

자바스크립트 값 VIDL 값으로 변환byte 값으로 만드는 알고리즘:

  1. xConvertToInt(V, 8, "signed") 결과로 둔다.

  2. x와 동일한 수치 값을 나타내는 IDL byte 값을 반환한다.

IDL byte 값을 자바스크립트 값으로 변환한 결과는, 해당 IDL byte 값과 동일한 수치 값을 가진 Number이다. Number 값은 [−128, 127] 범위의 정수다.

3.2.4.2. octet

자바스크립트 값 VIDL 값으로 변환octet 값으로 만드는 알고리즘:

  1. xConvertToInt(V, 8, "unsigned") 결과로 둔다.

  2. x와 동일한 수치 값을 나타내는 IDL octet 값을 반환한다.

IDL octet 값을 자바스크립트 값으로 변환한 결과는, 해당 IDL octet 값과 동일한 수치 값을 가진 Number이다. Number 값은 [0, 255] 범위의 정수다.

3.2.4.3. short

자바스크립트 값 VIDL 값으로 변환short 값으로 만드는 알고리즘:

  1. xConvertToInt(V, 16, "signed") 결과로 둔다.

  2. x와 동일한 수치 값을 나타내는 IDL short 값을 반환한다.

IDL short 값을 자바스크립트 값으로 변환한 결과는, 해당 IDL short 값과 동일한 수치 값을 가진 Number이다. Number 값은 [−32768, 32767] 범위의 정수다.

3.2.4.4. unsigned short

자바스크립트 값 VIDL 값으로 변환unsigned short 값으로 만드는 알고리즘:

  1. xConvertToInt(V, 16, "unsigned") 결과로 둔다.

  2. x와 동일한 수치 값을 나타내는 IDL unsigned short 값을 반환한다.

IDL unsigned short 값을 자바스크립트 값으로 변환한 결과는, 해당 IDL unsigned short 값과 동일한 수치 값을 가진 Number이다. Number 값은 [0, 65535] 범위의 정수다.

3.2.4.5. long

자바스크립트 값 VIDL 값으로 변환long 값으로 만드는 알고리즘:

  1. xConvertToInt(V, 32, "signed") 결과로 둔다.

  2. x와 동일한 수치 값을 나타내는 IDL long 값을 반환한다.

IDL long 값을 자바스크립트 값으로 변환한 결과는, 해당 IDL long 값과 동일한 수치 값을 가진 Number이다. Number 값은 [−2147483648, 2147483647] 범위의 정수다.

3.2.4.6. unsigned long

자바스크립트 값 VIDL 값으로 변환unsigned long 값으로 만드는 알고리즘:

  1. xConvertToInt(V, 32, "unsigned") 결과로 둔다.

  2. x와 동일한 수치 값을 나타내는 IDL unsigned long 값을 반환한다.

IDL unsigned long 값을 자바스크립트 값으로 변환한 결과는, 해당 IDL unsigned long 값과 동일한 수치 값을 가진 Number이다. Number 값은 [0, 4294967295] 범위의 정수다.

3.2.4.7. long long

자바스크립트 값 VIDL 값으로 변환long long 값으로 만드는 알고리즘:

  1. xConvertToInt(V, 64, "signed") 결과로 둔다.

  2. x와 동일한 수치 값을 나타내는 IDL long long 값을 반환한다.

IDL long long 값을 자바스크립트 값으로 변환한 결과는, 해당 long long 값에 가장 가까운 Number 값이다. 두 값이 동일하게 가까울 경우 유효숫자가 짝수인 값을 선택한다. long long이 [−253 + 1, 253 − 1] 범위에 있으면 Number가 동일한 값을 정확히 표현할 수 있다.

3.2.4.8. unsigned long long

자바스크립트 값 VIDL 값으로 변환unsigned long long 값으로 만드는 알고리즘:

  1. xConvertToInt(V, 64, "unsigned") 결과로 둔다.

  2. x와 동일한 수치 값을 나타내는 IDL unsigned long long 값을 반환한다.

IDL unsigned long long 값을 자바스크립트 값으로 변환한 결과는, 해당 unsigned long long 값에 가장 가까운 Number 값이다. 두 값이 동일하게 가까울 경우 유효숫자가 짝수인 값을 선택한다. unsigned long long이 253 − 1 이하이면 Number가 동일한 값을 정확히 표현할 수 있다.

3.2.4.9. 추상 연산

IntegerPart(n):

  1. rfloor(abs(n))로 둔다.

  2. n < 0이면 -1 × r을 반환한다.

  3. 그 외에는 r을 반환한다.

ConvertToInt(V, bitLength, signedness):

  1. bitLength가 64이면:

    1. upperBound를 253 − 1로 둔다.

    2. signedness가 "unsigned"면 lowerBound를 0으로 둔다.

    3. 그 외에는 lowerBound를 −253 + 1로 둔다.

      참고: 이렇게 하면 [EnforceRange] 또는 [Clamp] 확장 속성이 연관된 long long 타입이 자바스크립트 Number 타입에서 모호하지 않은 정수로 표현될 수 있다.

  2. 그 외에 signedness가 "unsigned"면:

    1. lowerBound를 0으로 둔다.

    2. upperBound를 2bitLength − 1로 둔다.

  3. 그 외에는:

    1. lowerBound를 -2bitLength − 1로 둔다.

    2. upperBound를 2bitLength − 1 − 1로 둔다.

  4. xToNumber(V) 결과로 둔다.

  5. x가 −0이면 x를 +0으로 설정한다.

  6. 변환 대상 IDL 타입이 [EnforceRange] 확장 속성과 연관되어 있으면:

    1. xNaN, +∞, −∞이면 throw TypeError.

    2. xIntegerPart(x)로 설정.

    3. x < lowerBound 또는 x > upperBoundthrow TypeError.

    4. x를 반환.

  7. xNaN이 아니고 변환 대상 IDL 타입이 [Clamp] 확장 속성과 연관되어 있으면:

    1. xmin(max(x, lowerBound), upperBound)로 설정.

    2. 가장 가까운 정수로 반올림, 두 정수 사이면 짝수 정수 선택. +0이 −0보다 우선.

    3. x를 반환.

  8. xNaN, +0, +∞, −∞이면 +0을 반환.

  9. xIntegerPart(x)로 설정.

  10. xx modulo 2bitLength로 설정.

  11. signedness가 "signed"이고 x ≥ 2bitLength − 1이면 x − 2bitLength를 반환.

  12. 그 외에는 x를 반환.

3.2.5. float

자바스크립트 값 VIDL 값으로 변환float 값으로 만드는 알고리즘:

  1. xToNumber(V) 결과로 둔다.

  2. xNaN, +∞, −∞이면 throw TypeError.

  3. S를 유한 IEEE 754 단정밀도 부동소수점 값 집합(−0 제외)에 2128, −2128 두 특수값을 추가한 집합으로 둔다.

  4. yx에 가장 가까운 S 내 값으로 두고, 동일하게 가까울 경우 유효숫자가 짝수인 값을 선택한다. (2128, −2128도 짝수 유효숫자로 간주.)

  5. y가 2128 또는 −2128이면 throw TypeError.

  6. y가 +0이고 x가 음수면 −0을 반환.

  7. y를 반환.

IDL float 값을 자바스크립트 값으로 변환한 결과는, 해당 IDL float 값과 동일한 수치 값을 가진 Number이다.

3.2.6. unrestricted float

자바스크립트 값 VIDL 값으로 변환unrestricted float 값으로 만드는 알고리즘:

  1. xToNumber(V) 결과로 둔다.

  2. xNaN이면 IEEE 754 NaN 값(bit 패턴 0x7fc00000)과 대응되는 IDL unrestricted float 값을 반환.

  3. S를 유한 IEEE 754 단정밀도 부동소수점 값 집합(−0 제외)에 2128, −2128 두 특수값을 추가한 집합으로 둔다.

  4. yx에 가장 가까운 S 내 값으로 두고, 동일하게 가까울 경우 유효숫자가 짝수인 값을 선택한다. (2128, −2128도 짝수 유효숫자로 간주.)

  5. y가 2128이면 +∞를 반환.

  6. y가 −2128이면 −∞를 반환.

  7. y가 +0이고 x가 음수면 −0을 반환.

  8. y를 반환.

참고: 자바스크립트 NaN 값이 하나뿐이므로, 단정밀도 IEEE 754 NaN 값 중 하나로 정규화해야 한다. 위에서 언급한 NaN 값(bit 패턴 0x7fc00000)은 32비트 부호 없는 정수로 해석할 때 값이 가장 작은 조용한 NaN이다.

IDL unrestricted float 값을 자바스크립트 값으로 변환한 결과는 Number:

  1. 해당 값이 NaN이면 Number 값도 NaN이다.

  2. 그 외에는 해당 IDL unrestricted float 값과 동일한 수치 값을 가진 Number이다.

3.2.7. double

자바스크립트 값 VIDL 값으로 변환double 값으로 만드는 알고리즘:

  1. xToNumber(V) 결과로 둔다.

  2. xNaN, +∞, −∞이면 throw TypeError.

  3. x와 동일한 수치 값을 나타내는 IDL double 값을 반환.

IDL double 값을 자바스크립트 값으로 변환한 결과는, 해당 double 값과 동일한 수치 값을 가진 Number이다.

3.2.8. unrestricted double

자바스크립트 값 VIDL 값으로 변환unrestricted double 값으로 만드는 알고리즘:

  1. xToNumber(V) 결과로 둔다.

  2. xNaN이면 IEEE 754 NaN 값(bit 패턴 0x7ff8000000000000)과 대응되는 IDL unrestricted double 값을 반환.

  3. x와 동일한 수치 값을 나타내는 IDL unrestricted double 값을 반환.

참고: 자바스크립트 NaN 값이 하나뿐이므로, 배정밀도 IEEE 754 NaN 값 중 하나로 정규화해야 한다. 위에서 언급한 NaN 값(bit 패턴 0x7ff8000000000000)은 64비트 부호 없는 정수로 해석할 때 값이 가장 작은 조용한 NaN이다.

IDL unrestricted double 값을 자바스크립트 값으로 변환한 결과는 Number:

  1. 해당 값이 NaN이면 Number 값도 NaN이다.

  2. 그 외에는 해당 IDL unrestricted double 값과 동일한 수치 값을 가진 Number이다.

3.2.9. bigint

자바스크립트 값 VIDL 값으로 변환bigint 값으로 만드는 알고리즘:

  1. xToBigInt(V) 결과로 둔다.

  2. x와 동일한 수치 값을 나타내는 IDL bigint 값을 반환.

IDL bigint 값을 자바스크립트 값으로 변환한 결과는 BigInt:

  1. 해당 IDL bigint 값과 동일한 수치 값을 가진 BigInt 값을 반환.

자바스크립트 값 V변환해서 IDL 숫자 타입 T 또는 bigint 값으로 만드는 알고리즘:

  1. xToNumeric(V) 결과로 둔다.

  2. xBigInt

    1. x와 동일한 수치 값을 나타내는 IDL bigint 값을 반환.

  3. 단언: xNumber이다.

  4. xT변환한 결과를 반환.

3.2.10. DOMString

자바스크립트 값 VIDL 값으로 변환DOMString 값으로 만드는 알고리즘:

  1. Vnull이고, 변환 대상 IDL 타입이 [LegacyNullToEmptyString] 확장 속성과 연관되어 있으면, 빈 문자열을 나타내는 DOMString 값을 반환한다.

  2. xToString(V) 결과로 둔다.

  3. x와 동일한 코드 유닛 시퀀스를 나타내는 IDL DOMString 값을 반환한다.

IDL DOMString 값을 자바스크립트 값으로 변환한 결과는, 해당 DOMString과 동일한 코드 유닛 시퀀스를 나타내는 String 값이다.

3.2.11. ByteString

자바스크립트 값 VIDL 값으로 변환ByteString 값으로 만드는 알고리즘:

  1. xToString(V) 결과로 둔다.

  2. x의 어떤 요소 값이 255를 초과하면 throw TypeError.

  3. x와 길이가 같고 각 요소 값이 x의 해당 요소와 동일한 IDL ByteString 값을 반환.

IDL ByteString 값을 자바스크립트 값으로 변환한 결과는, 해당 ByteString과 길이가 같고 각 요소 값이 ByteString의 해당 요소와 동일한 String 값이다.

3.2.12. USVString

자바스크립트 값 VIDL 값으로 변환USVString 값으로 만드는 알고리즘:

  1. stringVDOMString으로 변환한 결과로 둔다.

  2. string자바스크립트 문자열 변환을 통해 스칼라 값 시퀀스로 변환한 결과인 IDL USVString 값을 반환.

IDL USVStringS자바스크립트 값으로 변환한 결과는 S 자체다.

3.2.13. object

IDL object 값은 자바스크립트 Object 값으로 표현된다.

자바스크립트 값 VIDL 값으로 변환object 값으로 만드는 알고리즘:

  1. V객체가 아니면 throw TypeError.

  2. V와 동일 객체를 참조하는 IDL object 값을 반환.

IDL object 값을 자바스크립트 값으로 변환한 결과는, 해당 object가 참조하는 동일 객체를 나타내는 Object 값이다.

3.2.14. symbol

IDL symbol 값은 자바스크립트 Symbol 값으로 표현된다.

자바스크립트 값 VIDL 값으로 변환symbol 값으로 만드는 알고리즘:
  1. VSymbol이 아니면 throw TypeError.

  2. V와 동일 심볼을 참조하는 IDL symbol 값을 반환.

IDL symbol 값을 자바스크립트 값으로 변환한 결과는, 해당 symbol과 동일 심볼을 참조하는 Symbol 값이다.

3.2.15. 인터페이스 타입

IDL 인터페이스 타입 값은 자바스크립트 Object 값(함수 객체 포함)으로 표현된다.

자바스크립트 값 VIDL 값으로 변환인터페이스 타입 값으로 만드는 알고리즘(I는 해당 인터페이스):

  1. VI구현하면, 해당 플랫폼 객체를 참조하는 IDL 인터페이스 타입 값을 반환.

  2. throw TypeError.

IDL 인터페이스 타입 값을 자바스크립트 값으로 변환한 결과는, 해당 인터페이스 타입 값이 참조하는 동일 객체를 나타내는 Object 값이다.

3.2.16. 콜백 인터페이스 타입

IDL 콜백 인터페이스 타입 값은 자바스크립트 Object 값(함수 객체 포함)으로 표현된다.

자바스크립트 값 VIDL 값으로 변환콜백 인터페이스 타입 값으로 만드는 알고리즘:

  1. V객체가 아니면 throw TypeError.

  2. V를 참조하고, incumbent settings object콜백 컨텍스트로 하는 IDL 콜백 인터페이스 타입 값을 반환.

IDL 콜백 인터페이스 타입 값을 자바스크립트 값으로 변환한 결과는, 해당 콜백 인터페이스 타입 값이 참조하는 동일 객체를 나타내는 Object 값이다.

3.2.17. 딕셔너리 타입

IDL 딕셔너리 타입 값은 자바스크립트 Object 값으로 표현된다. 객체(또는 프로토타입 체인)상의 프로퍼티가 딕셔너리 멤버에 대응한다.

자바스크립트 값 jsDictIDL 값으로 변환딕셔너리 타입 값으로 만드는 알고리즘(D는 해당 딕셔너리 타입):

  1. jsDict객체가 아니고 undefinednull도 아니면 throw TypeError.

  2. idlDict순서가 있는 맵의 빈 맵으로 둔다(타입 D의 딕셔너리).

  3. dictionariesDD의 모든 상속 딕셔너리를 가장 덜 파생된 것부터 가장 많이 파생된 것까지 포함하는 리스트로 둔다.

  4. dictionaries의 각 dictionary에 대해, 순서대로:

    1. dictionary에 선언된 각 딕셔너리 멤버 member에 대해, 사전순으로:

      1. keymember식별자로 둔다.

      2. jsDictundefinednull이면:

        1. jsMemberValueundefined로 둔다.

      3. 그 외에는,

        1. jsMemberValueGet(jsDict, key) 결과로 둔다.

      4. jsMemberValueundefined가 아니면:

        1. idlMemberValuejsMemberValuemember가 선언된 타입으로 변환한 결과로 둔다.

        2. Set idlDict[key] = idlMemberValue로 한다.

      5. 그 외에 jsMemberValueundefined이고 member기본값이 있으면:

        1. idlMemberValuemember의 기본값으로 둔다.

        2. Set idlDict[key] = idlMemberValue로 한다.

      6. 그 외에 jsMemberValueundefined이고 member필수TypeError를 throw.

  5. idlDict를 반환.

참고: 자바스크립트 객체에서 딕셔너리 멤버 조회 순서는 객체의 프로퍼티 열거 순서와 반드시 같지 않다.

IDL 딕셔너리 값 V자바스크립트 값으로 변환해 Object 값으로 만드는 알고리즘(D는 해당 딕셔너리):

  1. OOrdinaryObjectCreate(%Object.prototype%)로 둔다.

  2. dictionariesDD의 모든 상속 딕셔너리를 가장 덜 파생된 것부터 가장 많이 파생된 것까지 포함하는 리스트로 둔다.

  3. dictionaries의 각 dictionary에 대해, 순서대로:

    1. dictionary에 선언된 각 딕셔너리 멤버 member에 대해, 사전순으로:

      1. keymember식별자로 둔다.

      2. V[key]가 존재하면:

        1. idlValueV[key]로 둔다.

        2. valueidlValue를 자바스크립트 값으로 변환한 결과로 둔다.

        3. CreateDataPropertyOrThrow(O, key, value)를 실행한다.

        만약 member기본값이 있다면, keyV에 항상 존재한다.

  4. O를 반환.

3.2.18. 열거형 타입

IDL 열거형 타입은 자바스크립트 String 값으로 표현된다.

자바스크립트 값 VIDL 값으로 변환열거형 타입 값으로 만드는 방법(E는 해당 열거형):

  1. SToString(V) 결과로 둔다.

  2. SE열거형 값에 포함되지 않으면 throw TypeError.

  3. S와 동일한 E 타입의 열거형 값을 반환.

IDL 열거형 타입 값을 자바스크립트 값으로 변환한 결과는, 해당 열거형 값과 동일한 코드 유닛 시퀀스를 나타내는 String 값이다.

3.2.19. 콜백 함수 타입

IDL 콜백 함수 타입은 자바스크립트 함수 객체로 표현된다. 단, [LegacyTreatNonObjectAsNull]이 붙은 경우에는 아무 객체나 될 수 있다.

자바스크립트 값 VIDL 값으로 변환콜백 함수 타입 값으로 만드는 알고리즘:

  1. IsCallable(V)이 false이고, 변환 대상이 [LegacyTreatNonObjectAsNull]이 붙은 nullable 콜백 함수 타입 속성에 할당되는 경우가 아니면 throw TypeError.

  2. V가 참조하는 동일 객체를 참조하고, incumbent settings object콜백 컨텍스트로 하는 IDL 콜백 함수 타입 값을 반환.

IDL 콜백 함수 타입 값을 자바스크립트 값으로 변환한 결과는, 해당 콜백 함수 타입 값이 참조하는 동일 객체를 나타내는 값이다.

3.2.20. 널 허용 타입 — T?

IDL 널 허용 타입 값은 내부 IDL 타입에 대응되는 자바스크립트 타입 값 또는 자바스크립트 null 값으로 표현된다.

자바스크립트 값 VIDL 값으로 변환널 허용 타입 T? 값으로 만드는 방법(T내부 타입):

  1. V객체가 아니고 변환 대상이 [LegacyTreatNonObjectAsNull]이 붙은 널 허용 콜백 함수 타입 속성에 할당되는 경우면, null을 반환.

  2. 그 외에 Vundefined이고, Tundefined 포함이면, 고유한 undefined 값을 반환.

  3. 그 외에 Vnull 또는 undefined이면 null을 반환.

  4. 그 외에는 T 타입의 변환 규칙으로 V를 변환한 결과를 반환.

IDL 널 허용 타입 값을 자바스크립트 값으로 변환한 결과는:

  1. 값이 null이면 자바스크립트 값도 null이다.

  2. 그 외에는 내부 타입 변환 규칙에 따라 변환한 결과이다.

3.2.21. 시퀀스 — sequence<T>

IDL sequence<T> 값은 자바스크립트 Array 값으로 표현된다.

자바스크립트 값 VIDL 값으로 변환sequence<T> 값으로 만드는 방법:

  1. V객체가 아니면 throw TypeError.

  2. methodGetMethod(V, %Symbol.iterator%) 결과로 둔다.

  3. methodundefinedthrow TypeError.

  4. Vmethod시퀀스 생성 결과를 반환.

sequence<T> 타입의 IDL 시퀀스 값 S자바스크립트 Array 객체로 변환하는 방법:

  1. nS의 길이로 둔다.

  2. A[] 식으로 생성한 새 Array 객체로 둔다.

  3. i를 0으로 초기화.

  4. i < n 동안:

    1. VS의 인덱스 i의 값으로 둔다.

    2. EV를 자바스크립트 값으로 변환한 결과로 둔다.

    3. PToString(i) 결과로 둔다.

    4. CreateDataPropertyOrThrow(A, P, E)을 수행.

    5. ii + 1로 설정.

  5. A를 반환.

3.2.21.1. 이터러블에서 시퀀스 생성하기

이터러블 iterable과 이터레이터 getter method가 주어졌을 때, sequence<T> 타입의 IDL 값을 생성하려면 다음 단계를 수행한다:

  1. iteratorRecord? GetIteratorFromMethod(iterable, method)로 설정한다.

  2. i를 0으로 초기화한다.

  3. 반복한다

    1. next? IteratorStepValue(iteratorRecord)로 설정한다.

    2. nextdone이면, i 길이의 sequence<T> 타입의 IDL 시퀀스 값을 반환한다. 이때 인덱스 j의 요소 값은 Sj이다.

    3. SinextT 타입의 IDL 값으로 변환한 결과로 초기화한다.

    4. ii + 1로 설정한다.

다음 interface는 시퀀스 타입의 attribute와 시퀀스 타입의 인자를 갖는 operation을 정의한다.

[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()가 "image/png"와 "image/svg+xml" 두 개의 DOMString 값을 갖는 시퀀스를 반환한다고 가정.
// 길이가 2인 Array 객체.
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. 비동기 시퀀스 — async_sequence<T>

JavaScript 바인딩에서, IDL async sequence 값은 다음 structitems로 표현된다:

JavaScript 값 V는 다음과 같이 IDL async_sequence<T> 값으로 변환된다:
  1. VObject가 아니면, TypeErrorthrow한다.

  2. method? GetMethod(obj, %Symbol.asyncIterator%)로 설정한다.

  3. methodundefined일 경우:

    1. syncMethod? GetMethod(obj, %Symbol.iterator%)로 설정한다.

    2. syncMethod가 undefined이면, TypeErrorthrow한다.

    3. IDL async sequence 값을 반환한다. objectV, methodsyncMethod, type은 "sync"로 설정된다.

  4. IDL async sequence 값을 반환한다. objectV, methodmethod, type 은 "async"로 설정된다.

IDL async_sequence<T>V는 다음과 같이 JavaScript 객체로 변환됩니다:
  1. Vobject를 반환한다.

3.2.22.1. 비동기 시퀀스 반복

비동기 시퀀스는 직접적으로 반복되지 않는다. 대신 먼저 열어서 비동기 이터레이터를 생성한다. 비동기 이터레이터는 비동기적으로 반복하여 값을 생성할 수 있다.

비동기 이터레이터들구조체이며, 다음 항목들을 가진다:

비동기 시퀀스 열기를 위해 async_sequence<T> sequence에 대해:

  1. iterator? GetIteratorFromMethod(sequenceobject, sequencemethod)로 설정한다.

  2. sequencetype이 "sync"이면, iteratorCreateAsyncFromSyncIterator(iterator)로 설정한다.

  3. 비동기 이터레이터 값을 반환하는데, underlying recorditerator로, type parameterT로 설정한다.

비동기 이터레이터의 다음 값 구하기를 위해 비동기 이터레이터 iterator에 대해:

  1. nextResultIteratorNext(iteratorunderlying record)로 설정한다.

  2. nextResultabrupt completion이면, 거부된 프라미스 nextResult.[[Value]]를 반환한다.

  3. nextPromise해결된 프라미스 nextResult.[[Value]]로 설정한다.

  4. nextPromise에 대해 반응한 결과를 반환하는데, 이때 iterResult를 인자로 한다:

    1. iterResult객체가 아니면, throw 한다. TypeError.

    2. done? IteratorComplete(iterResult)로 설정한다.

    3. done이 true이면:

      1. 반복 종료를 반환한다.

    4. 그 외의 경우:

      1. V? IteratorValue(iterResult)로 설정한다.

      2. value변환 Viteratortype parameter 타입의 IDL 값으로 변환한 결과로 설정한다.

      3. value를 반환한다.

비동기 이터레이터 닫기를 위해 async iterator<T> iterator, ECMAScript 값 reason과 함께:

  1. iteratorRecorditeratorunderlying record로 설정한다.

  2. iteratorObjiteratorRecord.[[Iterator]]로 설정한다.

  3. returnMethodGetMethod(iteratorObj, "return")로 설정한다.

  4. returnMethodabrupt completion이면, 거부된 프라미스 returnMethod.[[Value]]를 반환한다.

  5. returnMethodundefined이면, 해결된 프라미스 undefined를 반환한다.

  6. returnResultCall(returnMethod.[[Value]], iteratorObj, « reason »)로 설정한다.

  7. returnResultabrupt completion이면, 거부된 프라미스 returnResult.[[Value]]를 반환한다.

  8. returnPromise해결된 프라미스 returnResult.[[Value]]로 설정한다.

  9. returnPromise에 대해 반응한 결과를 반환하는데, returnPromiseResult를 인자로 한다:

    1. returnPromiseResult객체가 아니면, throw 한다. TypeError.

    2. undefined를 반환한다.

concatNoperation이며, 비동기 시퀀스에서 생성된 모든 문자열을 연결한 값을 프라미스로 반환한다. 이 연결은 비동기 시퀀스가 maxN개의 문자열을 생성하면 중단되고 이터레이터를 닫는다.

interface I {
  Promise<DOMString> concatN(async_sequence<DOMString> strings, unsigned long maxN);
};

concatN(sequence, maxN) 메서드 단계:

  1. promise새로운 프라미스로 설정한다.

  2. result를 빈 문자열로 설정한다.

  3. n을 0으로 설정한다.

  4. iterator비동기 시퀀스 열기의 결과로 sequence에 대해 생성한다.

  5. step을 비동기 시퀀스를 처리할 단계들의 시퀀스로 설정한다:

    1. next비동기 이터레이터의 다음 값 구하기의 결과로 iterator에 대해 얻는다.

    2. 반응하여 next를 처리한다:

      • next가 값 v로 이행되었다면:

        1. v반복 종료라면, resolve하여 promiseresult로 이행한다.

        2. resultresultv를 연결한 값으로 설정한다.

        3. nn + 1로 설정한다.

        4. nmaxN라면:

          1. finish비동기 이터레이터 닫기 결과로 iterator와 reason undefined로 얻는다.

          2. 반응하여 finish를 처리한다:

            • finish가 이행되었다면, resolve하여 promiseresult로 이행한다.

            • finishr로 거부되었다면, reject하여 promiser로 거부한다.

        5. 그 외의 경우:

          1. step을 호출한다.

      • nextr로 거부되었다면, reject하여 promiser로 거부한다.

  6. step을 호출한다.

  7. promise를 반환한다.

3.2.23. 레코드 — record<K, V>

IDL record<K, V> 값은 자바스크립트 객체 값으로 표현됩니다.

자바스크립트 값 O변환되어 IDL record<K, V> 값으로 처리됩니다. 다음과 같은 절차를 따릅니다:

  1. O객체가 아니면, throw를 발생시킵니다. TypeError.

  2. resultrecord<K, V> 의 새로운 빈 인스턴스로 설정합니다.

  3. keys? O.[[OwnPropertyKeys]]()로 설정합니다.

  4. keyskey에 대해:

    1. desc? O.[[GetOwnProperty]](key)로 설정합니다.

    2. descundefined가 아니고, desc.[[Enumerable]]가 true일 경우:

      1. typedKeykey IDL 값으로 변환 하여 타입 K로 처리합니다.

      2. value? Get(O, key)의 결과로 설정합니다.

      3. typedValuevalue IDL 값으로 변환 하여 타입 V로 처리합니다.

      4. result[typedKey]typedValue를 설정합니다.

        참고: KUSVString 이고 key에 짝이 없는 대리문자가 포함된 경우, typedKey가 이미 result에 있을 수 있습니다.

  5. result를 반환합니다.

IDL record<…>D변환되어 자바스크립트 값으로 다음과 같이 처리됩니다:

  1. resultOrdinaryObjectCreate(%Object.prototype%)의 결과로 설정합니다.

  2. Dkeyvalue 쌍에 대해:

    1. jsKeykey 자바스크립트 값으로 변환합니다.

    2. jsValuevalue 자바스크립트 값으로 변환합니다.

    3. created! CreateDataProperty(result, jsKey, jsValue)의 결과로 설정합니다.

    4. Assert: createdtrue입니다.

  3. result를 반환합니다.

자바스크립트 값 {b: 3, a: 4}record<DOMString, double> 인자로 전달하면, IDL 값 «[ "b" → 3, "a" → 4 ]»가 됩니다.

레코드는 자신의 열거 가능한 프로퍼티만 고려하므로, 다음과 같은 IDL 연산 record<DOMString, double> identity(record<DOMString, double> arg)이 인자를 반환할 때, 아래 코드는 assertion을 만족합니다:

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);

레코드의 키와 값은 제약될 수 있으며, 키는 세 문자열 타입 중에서만 제약될 수 있습니다. 아래 변환은 다음과 같은 결과를 가집니다:

타입에 전달 결과
{"😞": 1} record<ByteString, double> TypeError
{"\uD83D": 1} record<USVString, double> «[ "\uFFFD" → 1 ]»
{"\uD83D": {hello: "world"}} record<DOMString, double> «[ "\uD83D" → 0 ]»

3.2.24. Promise 타입 — Promise<T>

IDL promise 타입 값은 JavaScript PromiseCapability 레코드로 표현됩니다.

JavaScript 값 V변환되어 IDL의 Promise<T> 값으로 처리됩니다. 절차는 다음과 같습니다:

  1. promiseCapability? NewPromiseCapability(%Promise%)로 설정합니다.

  2. ? Call(promiseCapability.[[Resolve]], undefined, « V »)를 수행합니다.

  3. promiseCapability를 반환합니다.

IDL promise 타입 값을 자바스크립트 값으로 변환한 결과는, 해당 레코드가 표현하는 [[Promise]] 필드의 값입니다.

3.2.24.1. Promise 생성 및 조작

새로운 promise 생성Promise<T> 타입으로 realm realm에서 생성하려면, 다음 단계를 수행합니다:

  1. constructorrealm.[[Intrinsics]].[[%Promise%]]로 설정합니다.

  2. ? NewPromiseCapability(constructor)를 반환합니다.

해결된 promise 생성Promise<T> 타입으로 x (타입 T의 값)와 함께 realm realm에서 생성하려면, 다음 단계를 수행합니다:

  1. value자바스크립트 값으로 변환x의 결과로 설정합니다.

  2. constructorrealm.[[Intrinsics]].[[%Promise%]]로 설정합니다.

  3. promiseCapability? NewPromiseCapability(constructor)로 설정합니다.

  4. ! Call(promiseCapability.[[Resolve]], undefined, « value »)를 수행합니다.

  5. promiseCapability를 반환합니다.

거부된 promise 생성Promise<T> 타입으로 reason r (자바스크립트 값)과 함께 realm realm에서 생성하려면, 다음 단계를 수행합니다:

  1. constructorrealm.[[Intrinsics]].[[%Promise%]]로 설정합니다.

  2. promiseCapability? NewPromiseCapability(constructor)로 설정합니다.

  3. ! Call(promiseCapability.[[Reject]], undefined, « r »)를 수행합니다.

  4. promiseCapability를 반환합니다.

resolvePromise<T> px (타입 T의 값)로 하려면, 다음 단계를 수행합니다:

  1. x가 주어지지 않았다면, undefined 값으로 설정합니다.

  2. value자바스크립트 값으로 변환x의 결과로 설정합니다.

  3. ! Call(p.[[Resolve]], undefined, « value »)를 수행합니다.

Tundefined 인 경우, x 인자는 생략할 수 있으므로 더 간단한 "resolve p" 사용이 가능합니다.

rejectPromise<T> p에 reason r (자바스크립트 값)으로 하려면, 다음 단계를 수행합니다:

  1. ! Call(p.[[Reject]], undefined, « r »)를 수행합니다.

reactPromise<T> promise에 대해, promise가 이행되거나 거부되었을 때 수행할 1~2개의 단계 집합을 받아, 다음 단계를 수행합니다:

  1. onFulfilledSteps를 다음 단계로 설정합니다. 인자로 V를 받습니다:

    1. valueIDL 값으로 변환V (타입 T)로 설정합니다.

    2. promise가 이행되었을 때 실행할 단계가 있다면, result를 해당 단계를 수행한 결과로 설정합니다. Tundefined가 아니면 value를 인자로 전달합니다. 그렇지 않으면 resultvalue로 설정합니다.

    3. result자바스크립트 값으로 변환하여 반환합니다.

  2. onFulfilledCreateBuiltinFunction(onFulfilledSteps, « »)로 설정합니다:

  3. onRejectedSteps를 다음 단계로 설정합니다. 인자로 R를 받습니다:

    1. reasonIDL 값으로 변환R (타입 any)로 설정합니다.

    2. promise가 거부되었을 때 실행할 단계가 있다면, result를 해당 단계를 수행한 결과로 설정합니다. 그렇지 않으면 result거부된 promise 생성 reason으로 설정합니다.

    3. result자바스크립트 값으로 변환하여 반환합니다.

  4. onRejectedCreateBuiltinFunction(onRejectedSteps, « »)로 설정합니다:

  5. constructorpromise.[[Promise]].[[Realm]].[[Intrinsics]].[[%Promise%]]로 설정합니다.

  6. newCapability? NewPromiseCapability(constructor)로 설정합니다.

    참고: 모든 호출자가 반환된 Promise를 사용할 필요는 없습니다. 구현체는 newCapability 생성 생략을 고려할 수 있습니다.

  7. PerformPromiseThen(promise.[[Promise]], onFulfilled, onRejected, newCapability)를 수행합니다.

  8. newCapability를 반환합니다.

참고: 이 알고리즘은 promise.then() 메서드와 매우 유사하게 동작합니다. 특히, 단계에서 U 타입이나 Promise<U> 값을 반환하는 경우, 이 알고리즘 역시 Promise<U> 를 반환합니다.

어떤 단계 이행 시 수행Promise<T> promise가 이행될 때, 타입 T 값을 받는 단계 steps로 다음을 수행합니다:

  1. reactpromise에 대해 호출한 결과를 반환합니다:

    • promise가 값 v로 이행되었다면:

      1. stepsv로 수행합니다.

어떤 단계 거부 시 수행Promise<T> promise가 거부될 때, 자바스크립트 값을 받는 단계 steps로 다음을 수행합니다:

  1. reactpromise에 대해 호출한 결과를 반환합니다:

    • promise가 reason r로 거부되었다면:

      1. stepsr로 수행합니다.

모두 대기(wait for all)list 타입인 Promise<T>promises에 대해, list 타입 T 값을 받는 성공 단계 successSteps와 거부 reason any 값을 받는 실패 단계 failureSteps로 다음을 수행합니다:

  1. fullfilledCount를 0으로 설정합니다.

  2. rejected를 false로 설정합니다.

  3. rejectionHandlerSteps를 다음 단계로 설정합니다. 인자로 arg를 받습니다:

    1. rejected가 true이면 이 단계들을 중단합니다.

    2. rejected를 true로 설정합니다.

    3. failureStepsarg로 수행합니다.

  4. rejectionHandlerCreateBuiltinFunction(rejectionHandlerSteps, « »)로 설정합니다:

  5. totalpromisessize로 설정합니다.

  6. total이 0이면:

    1. 마이크로태스크 큐successSteps를 « »로 수행하도록 추가합니다.

    2. 반환합니다.

  7. index를 0으로 설정합니다.

  8. resultlist 타입으로, total 개의 null 값으로 초기화합니다.

  9. promisespromise에 대해:

    1. promiseIndexindex로 설정합니다.

    2. fulfillmentHandler를 다음 단계로 설정합니다. 인자로 arg를 받습니다:

      1. result[promiseIndex]에 arg를 설정합니다.

      2. fullfilledCountfullfilledCount+1로 설정합니다.

      3. fullfilledCounttotal과 같으면, successStepsresult로 수행합니다.

    3. fulfillmentHandlerCreateBuiltinFunction(fulfillmentHandler, « »)로 설정합니다:

    4. PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler)를 수행합니다.

    5. indexindex+1로 설정합니다.

모두 기다리는 promise 얻기list 타입 Promise<T>promisesrealm realm에 대해 얻으려면, 다음 단계를 수행합니다:

  1. promise새로운 promise 생성으로 Promise<sequence<T>> 타입으로 realm에서 생성합니다.

  2. successSteps를 다음 단계로 설정합니다. 인자로 results를 받습니다:

    1. resolve promiseresults로 수행합니다.

  3. failureSteps를 다음 단계로 설정합니다. 인자로 reason을 받습니다:

    1. reject promisereason으로 수행합니다.

  4. 모두 대기(wait for all)promisessuccessSteps, failureSteps로 수행합니다.

  5. promise를 반환합니다.

이 정의는 여러 promise의 결과를 집계한 뒤, 그 결과로 또 다른 promise를 생성하고 싶을 때 유용합니다. JavaScript의 Promise.all() 과 같은 방식입니다. 또 다른 promise를 생성할 필요가 없다면 모두 대기(waiting for all)가 더 적합할 수 있습니다.

handled로 표시하려면 Promise<T> promisepromise.[[Promise]].[[PromiseIsHandled]]를 true로 설정합니다.

이 정의는 거부가 자주 무시될 것으로 예상되는 promise에 유용하며, 이러한 promise가 unhandledrejection 이벤트를 발생시키지 않게 합니다. 가장 흔한 사용 사례는 웹 개발자가 확인할 수도, 하지 않을 수도 있는 promise 속성입니다. 예를 들어 writableStreamWriter.closed promise가 있습니다.

3.2.24.2. 예시

delay연산이며, 지정한 밀리초 후에 이행되는 promise를 반환합니다. 한 줄의 설명으로 promise를 어떻게 간단하게 resolve할 수 있는지 보여줍니다.

interface I {
  Promise<undefined> delay(unrestricted double ms);
};

delay(ms) 메서드 단계:

  1. realmthis관련 렐름으로 설정한다.

  2. taskSource를 적절한 태스크 소스로 설정한다.

  3. ms가 NaN이면 ms를 +0으로, 아니면 ms와 +0 중 더 큰 값으로 ms를 설정한다.

  4. p새로운 promiserealm에서 생성한다.

  5. 다음 단계를 병렬로 실행한다:

    1. ms 밀리초 대기한다.

    2. 태스크 큐에 등록하여 taskSourceresolve p를 수행한다.

  6. p를 반환한다.

validatedDelay 연산delay 함수와 유사하지만, 인자를 검증합니다. 이 예시는 비동기 작업을 시작하기 전에 즉시 실패를 알릴 때 rejected promise를 어떻게 사용하는지 보여줍니다.

interface I {
  Promise<undefined> validatedDelay(unrestricted double ms);
};

validatedDelay(ms) 메서드 단계:

  1. realmthis관련 렐름으로 설정한다.

  2. taskSource를 적절한 태스크 소스로 설정한다.

  3. ms가 NaN이면 거부된 promise TypeErrorrealm에서 반환한다.

  4. ms < 0이면 거부된 promise RangeErrorrealm에서 반환한다.

  5. p새로운 promiserealm에서 생성한다.

  6. 다음 단계를 병렬로 실행한다:

    1. ms 밀리초 대기한다.

    2. 태스크 큐에 등록하여 taskSourceresolve p를 수행한다.

  7. p를 반환한다.

addDelay연산이며, promise가 settle된 후 반환 promise가 settle되기까지 추가 밀리초 지연을 제공합니다.

interface I {
  Promise<any> addDelay(Promise<any> promise, unrestricted double ms);
};

addDelay(ms, promise) 메서드 단계:

  1. realmthis관련 렐름으로 설정한다.

  2. taskSource를 적절한 태스크 소스로 설정한다.

  3. ms가 NaN이면 ms를 +0으로, 아니면 ms와 +0 중 더 큰 값으로 ms를 설정한다.

  4. p새로운 promiserealm에서 생성한다.

  5. Reactpromise에 대해 수행한다:

  6. p를 반환한다.

environment.ready특성(attribute)이며, 환경(예: DOM 문서)의 일부가 "준비됨" 상태가 되었음을 알립니다. 환경 비동기성을 표현하는 방법을 보여줍니다.

interface Environment {
  readonly attribute Promise<undefined> ready;
};

모든 Environment 객체는 ready promise를 가져야 하며, 이 값은 Promise<undefined>이다.

ready 특성 getter 단계:

  1. thisready promise를 반환한다.

Environment 객체를 realm realm에서 생성하려면, 다음 단계를 수행합니다:

  1. taskSource를 적절한 태스크 소스로 설정한다.

  2. environment새로운 Environment 객체로 realm에서 생성한다.

  3. environmentready promise새로운 promiserealm에서 설정한다.

  4. 다음 단계를 병렬로 실행한다:

    1. 비동기 작업 수행.

    2. environment가 정상적으로 ready가 되면, 태스크 큐에 등록하여 taskSourceresolve environmentready promise를 수행한다.

    3. environment가 ready가 되지 못하면, 태스크 큐에 등록하여 taskSourcereject environmentready promise를 "NetworkError" DOMException으로 거부한다.

  5. environment를 반환한다.

addBookmark연산이며, 사용자에게 현재 웹페이지를 북마크에 추가해달라고 요청합니다. 실제 디자인 작업에서 파생된 예시로, 환경 비동기성과 즉시 거부를 다루는 현실적인 시나리오를 보여줍니다.

interface I {
  Promise<undefined> addBookmark();
};

addBookmark() 메서드 단계:

  1. taskSource를 적절한 태스크 소스로 설정한다.

  2. 이 메서드가 명시적 사용자 동작의 결과로 호출되지 않았다면, 거부된 promise를 "SecurityError" DOMException으로 반환한다.

  3. 문서의 동작 모드가 standalone이면 거부된 promise를 "NotSupportedError" DOMException으로 반환한다.

  4. promise새로운 promise로 생성한다.

  5. info를 웹 애플리케이션의 메타데이터를 얻은 결과로 설정한다.

  6. 다음 단계를 병렬로 실행한다:

    1. info를 활용하여, 사용자 에이전트별 방식으로 최종 사용자가 북마크 추가 여부를 선택하도록 한다.

      1. 최종 사용자가 북마크 추가 요청을 중단(예: ESC 키, 취소 버튼 등)하면, 태스크 큐에 등록하여 taskSourcereject promise를 "AbortError" DOMException으로 수행한다.

      2. 그 외의 경우, 태스크 큐에 등록하여 taskSourceresolve promise를 수행한다.

  7. promise를 반환한다.

[SERVICE-WORKERS]의 여러 곳에서 모두 기다리는 promise 얻기(get a promise to wait for all)를 사용합니다. batchRequest는 그 용례 중 하나를 단순화한 예시입니다. 입력값으로 sequence 타입의 URL 목록을 받고, 각 URL을 fetch하여 생성된 sequence 타입의 Response 객체의 promise를 반환합니다. fetch 중 하나라도 실패하면, 해당 실패로 거부된 promise를 반환합니다.

interface I {
  Promise<sequence<Response>> batchRequest(sequence<USVString> urls);
};

batchRequest(urls) 메서드 단계:

  1. responsePromises를 « »로 설정한다.

  2. urlsurl에 대해:

    1. pfetch() 함수에 url을 넣어 호출한 결과로 설정한다.

    2. 추가하여 presponsePromises에 넣는다.

  3. p모두 기다리는 promise 얻기responsePromises에 대해 호출한 결과로 설정한다.

  4. p를 반환한다.

3.2.25. Union 타입

IDL union 타입 값은 해당 union의 멤버 타입에 해당하는 자바스크립트 값으로 표현됩니다.

자바스크립트 값 V를 IDL union 타입 값으로 변환하려면 다음과 같이 합니다:

  1. union 타입undefined를 포함하고 Vundefined라면, 고유한 undefined 값을 반환합니다.

  2. union 타입nullable 타입을 포함하고 Vnull 또는 undefined라면, IDL 값 null을 반환합니다.

  3. typesunion 타입평탄화된 멤버 타입으로 설정합니다.

  4. Vnull 또는 undefined라면:

    1. typesdictionary 타입이 포함되어 있다면, V를 해당 dictionary 타입으로 변환한 결과를 반환합니다.

  5. V플랫폼 객체라면:

    1. typesinterface 타입이 포함되어 있고 V가 이를 구현한다면, V 객체를 참조하는 IDL 값을 반환합니다.

    2. typesobject가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.

  6. VObject이며, [[ArrayBufferData]] 내부 슬롯이 있고, IsSharedArrayBuffer(V)가 false라면:

    1. typesArrayBuffer가 포함되어 있다면, VArrayBuffer변환한 결과를 반환합니다.

    2. typesobject가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.

  7. VObject이며, [[ArrayBufferData]] 내부 슬롯이 있고, IsSharedArrayBuffer(V)가 true라면:

    1. typesSharedArrayBuffer가 포함되어 있다면, VSharedArrayBuffer변환한 결과를 반환합니다.

    2. typesobject가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.

  8. VObject이며, [[DataView]] 내부 슬롯이 있다면:

    1. typesDataView가 포함되어 있다면, VDataView변환한 결과를 반환합니다.

    2. typesobject가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.

  9. VObject이며, [[TypedArrayName]] 내부 슬롯이 있다면:

    1. typestyped array 타입이 포함되어 있고, 해당 타입 이름이 V의 [[TypedArrayName]] 내부 슬롯의 값과 같다면, V를 해당 타입으로 변환한 결과를 반환합니다.

    2. typesobject가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.

  10. IsCallable(V)가 true라면:

    1. typescallback function 타입이 포함되어 있다면, V를 해당 callback function 타입으로 변환한 결과를 반환합니다.

    2. typesobject가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.

  11. VObject라면:

    1. typesasync sequence 타입이 포함되어 있다면

      1. typesstring 타입이 포함되어 있지 않거나, V에 [[StringData]] 내부 슬롯이 없다면,

        1. asyncMethod? GetMethod(V, %Symbol.asyncIterator%)로 설정합니다.

        2. asyncMethodundefined가 아니면, IDL async sequence 값을 반환합니다. objectV, methodsyncMethod, type은 "async"로 설정합니다.

        3. syncMethod? GetMethod(V, %Symbol.iterator%)로 설정합니다.

        4. syncMethodundefined가 아니면, IDL async sequence 값을 반환합니다. objectV, methodsyncMethod, type은 "sync"로 설정합니다.

    2. typessequence 타입이 포함되어 있다면

      1. method? GetMethod(V, %Symbol.iterator%)로 설정합니다.

      2. methodundefined가 아니면, 해당 타입의 시퀀스 생성 결과를 Vmethod로 반환합니다.

    3. typesfrozen array 타입이 포함되어 있다면

      1. method? GetMethod(V, %Symbol.iterator%)로 설정합니다.

      2. methodundefined가 아니면, 해당 타입의 frozen array 생성 결과를 Vmethod로 반환합니다.

    4. typesdictionary 타입이 포함되어 있다면, V를 해당 dictionary 타입으로 변환한 결과를 반환합니다.

    5. typesrecord 타입이 포함되어 있다면, V를 해당 record 타입으로 변환한 결과를 반환합니다.

    6. typescallback interface 타입이 포함되어 있다면, V를 해당 callback interface 타입으로 변환한 결과를 반환합니다.

    7. typesobject가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.

  12. VBoolean 타입이라면:

    1. typesboolean이 포함되어 있다면, Vboolean으로 변환한 결과를 반환합니다.

  13. VNumber 타입이라면:

    1. typesnumeric 타입이 포함되어 있다면, V를 해당 numeric 타입으로 변환한 결과를 반환합니다.

  14. VBigInt 타입이라면:

    1. typesbigint가 포함되어 있다면, Vbigint변환한 결과를 반환합니다.

  15. typesstring 타입이 포함되어 있다면, V를 해당 타입으로 변환한 결과를 반환합니다.

  16. typesnumeric 타입bigint가 포함되어 있다면, V를 해당 numeric 타입 또는 bigint변환한 결과를 반환합니다.

  17. typesnumeric 타입이 포함되어 있다면, V를 해당 numeric 타입으로 변환한 결과를 반환합니다.

  18. typesboolean이 포함되어 있다면, Vboolean으로 변환한 결과를 반환합니다.

  19. typesbigint가 포함되어 있다면, Vbigint변환한 결과를 반환합니다.

  20. TypeError를 throw합니다. TypeError.

IDL union 타입 값은 해당 union 값의 구체 타입(specific type)에 대한 변환 규칙에 따라 자바스크립트 값으로 변환됩니다. (자세한 내용은 § 3.2 JavaScript 타입 매핑 참조)

3.2.26. 버퍼 소스 타입

IDL ArrayBuffer 값은 해당하는 자바스크립트 클래스의 객체로 표현됩니다. [AllowResizable] 확장 어트리뷰트연관되지 않은 경우, 자바스크립트 ArrayBuffer 객체 V에서만 지원되며, IsResizableArrayBuffer(V)가 false여야 합니다.

IDL SharedArrayBuffer 값은 해당하는 자바스크립트 클래스의 객체로 표현됩니다. [AllowResizable] 확장 어트리뷰트연관되지 않은 경우, 자바스크립트 SharedArrayBuffer 객체 V에서만 지원되며, IsResizableArrayBuffer(V)가 false여야 합니다.

IDL buffer view 타입 값은 해당하는 자바스크립트 클래스의 객체로 표현되며, 다음의 추가적인 제약이 있습니다.

자바스크립트 값 V를 IDL ArrayBuffer 값으로 변환하려면 다음 알고리즘을 실행합니다:

  1. V객체가 아니거나, [[ArrayBufferData]] 내부 슬롯이 없으면 TypeError를 throw합니다.

  2. IsSharedArrayBuffer(V)가 true이면 TypeError를 throw합니다.

  3. 변환 대상이 [AllowResizable] 확장 어트리뷰트와 연관된 타입이 아니고, IsResizableArrayBuffer(V)가 true이면 TypeError를 throw합니다.

  4. V와 같은 객체를 참조하는 IDL ArrayBuffer 값을 반환합니다.

자바스크립트 값 V를 IDL SharedArrayBuffer 값으로 변환하려면 다음 알고리즘을 실행합니다:

  1. V객체가 아니거나, [[ArrayBufferData]] 내부 슬롯이 없으면 TypeError를 throw합니다.

  2. IsSharedArrayBuffer(V)가 false이면 TypeError를 throw합니다.

  3. 변환 대상이 [AllowResizable] 확장 어트리뷰트와 연관된 타입이 아니고, IsResizableArrayBuffer(V)가 true이면 TypeError를 throw합니다.

  4. V와 같은 객체를 참조하는 IDL SharedArrayBuffer 값을 반환합니다.

자바스크립트 값 V를 IDL DataView 값으로 변환하려면 다음 알고리즘을 실행합니다:

  1. V객체가 아니거나, [[DataView]] 내부 슬롯이 없으면 TypeError를 throw합니다.

  2. 변환 대상이 [AllowShared] 확장 어트리뷰트와 연관된 타입이 아니고, IsSharedArrayBuffer(V.[[ViewedArrayBuffer]])가 true이면 TypeError를 throw합니다.

  3. 변환 대상이 [AllowResizable] 확장 어트리뷰트와 연관된 타입이 아니고, IsResizableArrayBuffer(V.[[ViewedArrayBuffer]])가 true이면 TypeError를 throw합니다.

  4. V와 같은 객체를 참조하는 IDL DataView 값을 반환합니다.

자바스크립트 값 V변환하여 IDL Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, Uint32Array, Uint8ClampedArray, BigInt64Array, BigUint64Array, Float16Array, Float32Array, Float64Array 값으로 변환하려면 다음 알고리즘을 실행합니다:

  1. T를 변환 대상 IDL 타입으로 설정합니다.

  2. V객체가 아니거나, [[TypedArrayName]] 내부 슬롯T의 이름과 같지 않으면 TypeError를 throw합니다.

  3. 변환 대상이 [AllowShared] 확장 어트리뷰트와 연관된 타입이 아니고, IsSharedArrayBuffer(V.[[ViewedArrayBuffer]])가 true이면 TypeError를 throw합니다.

  4. 변환 대상이 [AllowResizable] 확장 어트리뷰트와 연관된 타입이 아니고, IsResizableArrayBuffer(V.[[ViewedArrayBuffer]])가 true이면 TypeError를 throw합니다.

  5. V와 같은 객체를 참조하는 타입 T의 IDL 값을 반환합니다.

IDL buffer source 타입의 값을 자바스크립트 값으로 변환한 결과는 해당 IDL 값이 참조하는 객체와 동일한 객체를 참조하는 Object 값입니다.

생성을 하려면 ArrayBuffer바이트 시퀀스 bytesrealm realm에서 생성합니다:
  1. jsArrayBuffer? AllocateArrayBuffer(realm.[[Intrinsics]].[[%ArrayBuffer%]], bytes길이)로 설정합니다.

  2. arrayBuffer변환을 통해 jsArrayBufferArrayBuffer 타입의 IDL 값으로 변환합니다.

  3. bytes를 arrayBuffer에 작성합니다.

  4. arrayBuffer를 반환합니다.

생성을 하려면 SharedArrayBuffer바이트 시퀀스 bytesrealm realm에서 생성합니다:
  1. jsSharedArrayBuffer? AllocateSharedArrayBuffer(realm.[[Intrinsics]].[[%SharedArrayBuffer%]], bytes길이)로 설정합니다.

  2. sharedArrayBuffer변환을 통해 jsSharedArrayBufferSharedArrayBuffer 타입의 IDL 값으로 변환합니다.

  3. bytes를 sharedArrayBuffer에 작성합니다.

  4. sharedArrayBuffer를 반환합니다.

생성을 하려면 ArrayBufferView 타입 중 하나를 바이트 시퀀스 bytesrealm realm에서 생성합니다:
  1. 단, 타입이 DataView가 아니라면, bytes길이를 해당 타입의 요소 크기로 나눈 나머지가 0이어야 합니다.

  2. arrayBuffer생성을 통해 ArrayBufferbytesrealm에서 생성합니다.

  3. jsArrayBuffer변환을 통해 arrayBuffer를 자바스크립트 값으로 변환합니다.

  4. constructorrealm.[[Intrinsics]]에서 생성할 ArrayBufferView 타입에 맞는 생성자로 설정합니다.

  5. jsView! Construct(constructor, « jsArrayBuffer »)로 생성합니다.

  6. 변환을 통해 jsView를 해당 타입으로 변환한 결과를 반환합니다.

버퍼 소스의 바이트 복사 얻기buffer source 타입 인스턴스 bufferSource에 대해 다음 단계를 수행합니다:
  1. jsBufferSource변환을 통해 bufferSource를 자바스크립트 값으로 변환합니다.

  2. jsArrayBufferjsBufferSource로 설정합니다.

  3. offset을 0으로 설정합니다.

  4. length을 0으로 설정합니다.

  5. jsBufferSource가 [[ViewedArrayBuffer]] 내부 슬롯을 가지면:

    1. jsArrayBufferjsBufferSource.[[ViewedArrayBuffer]]로 설정합니다.

    2. offsetjsBufferSource.[[ByteOffset]]로 설정합니다.

    3. lengthjsBufferSource.[[ByteLength]]로 설정합니다.

  6. 그 외의 경우:

    1. jsBufferSource는 ArrayBuffer 또는 SharedArrayBuffer 객체여야 합니다.

    2. lengthjsBufferSource.[[ArrayBufferByteLength]]로 설정합니다.

  7. IsDetachedBuffer(jsArrayBuffer)가 true면 빈 바이트 시퀀스를 반환합니다.

  8. bytes바이트 시퀀스로 생성하며, 길이length로 설정합니다.

  9. i범위 offset에서 offset + length − 1까지 반복하며, bytes[ioffset]에 GetValueFromBuffer(jsArrayBuffer, i, Uint8, true, Unordered)의 결과를 넣습니다.

  10. bytes를 반환합니다.

바이트 길이buffer source 타입 인스턴스 bufferSource에 대해 다음 단계의 결과입니다:
  1. jsBufferSource변환을 통해 bufferSource를 자바스크립트 값으로 변환합니다.

  2. jsBufferSource가 [[ViewedArrayBuffer]] 내부 슬롯을 가지면, jsBufferSource.[[ByteLength]]를 반환합니다.

  3. jsBufferSource.[[ArrayBufferByteLength]]를 반환합니다.

기저 버퍼(underlying buffer)버퍼 소스 타입 인스턴스 bufferSource에 대해 다음 단계로 반환되는 값을 의미합니다:
  1. bufferSource버퍼 타입 인스턴스라면 bufferSource를 반환합니다.

  2. jsBufferViewIDL에서 자바스크립트 값으로 변환bufferSource의 결과로 설정합니다.

  3. jsBufferjsBufferView.[[ViewedArrayBuffer]]로 설정합니다.

  4. IsSharedArrayBuffer(jsBuffer)가 false라면, 자바스크립트 값을 IDL 값으로 변환하여 jsBufferArrayBuffer 타입으로 반환합니다.

  5. 자바스크립트 값을 IDL 값으로 변환하여 jsBufferSharedArrayBuffer 타입으로 반환합니다.

쓰기(write)바이트 시퀀스(byte sequence) bytes버퍼 타입 인스턴스 arrayBuffer에 쓸 때, 옵셔널로 startingOffset (기본값 0)을 받을 수 있습니다:
  1. jsArrayBufferIDL에서 자바스크립트 값으로 변환arrayBuffer의 결과로 설정합니다.

  2. 단언: bytes길이(length)jsArrayBuffer.[[ArrayBufferByteLength]] − startingOffset.

  3. 범위(the range) startingOffset에서 startingOffset + bytes길이 − 1까지 i에 대해 SetValueInBuffer(jsArrayBuffer, i, Uint8, bytes[i - startingOffset], true, Unordered)를 수행합니다.

쓰기(write)바이트 시퀀스(byte sequence) bytesArrayBufferView view에 쓸 때, 옵셔널로 startingOffset (기본값 0)을 받을 수 있습니다:
  1. jsViewIDL에서 자바스크립트 값으로 변환view의 결과로 설정합니다.

  2. 단언: bytes길이jsView.[[ByteLength]] − startingOffset.

  3. 단언: viewDataView가 아닐 경우, bytes길이modulo view의 타입의 요소 크기(element size)로 나눈 나머지가 0임을 보장합니다.

  4. arrayBuffer자바스크립트 값을 IDL 값으로 변환하여 jsView.[[ViewedArrayBuffer]]를 ArrayBuffer 타입으로 설정합니다.

  5. 쓰기(write)bytesarrayBuffer로, startingOffsetjsView.[[ByteOffset]] + startingOffset으로 하여 수행합니다.

버퍼 소스 타입 인스턴스에 데이터를 쓸 때는, 아래 데이터가 예상치 못한 시점에 스크립트 작성자나 다른 API에 의해 쉽게 변경될 수 있으므로 명세 작성 시 각별히 주의해야 합니다. 특히 SharedArrayBuffer 객체가 관련된 경우 더욱 그렇습니다.

공유되지 않은 경우, 보다 권장되는 패턴은 transfer(이전)를 먼저 수행하여 ArrayBuffer 인스턴스의 쓰기가 다른 수정과 겹치지 않도록 보장한 뒤, 필요에 따라 새 ArrayBuffer 인스턴스를 작성자 코드에 제공하는 것입니다. 또는 버퍼 소스가 가진 바이트의 복사본을 얻어 해당 바이트를 수정한 뒤, 이를 사용해 새로운 ArrayBufferArrayBufferView 를 작성자 코드에 제공할 수 있습니다.

detach(분리)ArrayBuffer arrayBuffer에 대해 다음을 수행합니다:
  1. jsArrayBufferIDL에서 자바스크립트 값으로 변환arrayBuffer의 결과로 설정합니다.

  2. ? DetachArrayBuffer(jsArrayBuffer)를 수행합니다.

만약 jsArrayBuffer가 [[ArrayBufferDetachKey]]가 undefined가 아닌 경우, (예: WebAssembly.Memorybuffer 속성값 등) 예외가 발생합니다. [WASM-JS-API-1]

이미 detached(분리됨)된 버퍼를 detach하는 것은 아무 효과가 없습니다.

버퍼 소스 타입 인스턴스 bufferSourcedetached(분리됨)인지 여부는 다음 단계가 true를 반환하는지로 결정합니다:
  1. jsArrayBufferIDL에서 자바스크립트 값으로 변환bufferSource의 결과로 설정합니다.

  2. jsArrayBuffer가 [[ViewedArrayBuffer]] 내부 슬롯을 가진 경우, jsArrayBufferjsArrayBuffer.[[ViewedArrayBuffer]]로 설정합니다.

  3. IsDetachedBuffer(jsArrayBuffer)를 반환합니다.

버퍼 소스 타입 인스턴스 bufferSourcetransferable(이전 가능)인지 여부는 다음 단계가 true를 반환하는지로 결정합니다:
  1. jsArrayBufferIDL에서 자바스크립트 값으로 변환bufferSource의 결과로 설정합니다.

  2. jsArrayBuffer가 [[ViewedArrayBuffer]] 내부 슬롯을 가진 경우, jsArrayBufferjsArrayBuffer.[[ViewedArrayBuffer]]로 설정합니다.

  3. IsSharedArrayBuffer(jsArrayBuffer)가 true이면 false 반환.

  4. IsDetachedBuffer(jsArrayBuffer)가 true이면 false 반환.

  5. jsArrayBuffer.[[ArrayBufferDetachKey]]가 undefined가 아니면 false 반환.

  6. true 반환.

transfer(이전)ArrayBuffer arrayBuffer를, 옵셔널하게 realm targetRealm에 이전할 때:
  1. jsArrayBufferIDL에서 자바스크립트 값으로 변환arrayBuffer의 결과로 설정합니다.

  2. IsDetachedBuffer(jsArrayBuffer)가 false면, TypeError를 throw합니다. TypeError.

  3. arrayBufferDatajsArrayBuffer.[[ArrayBufferData]]로 설정합니다.

  4. arrayBufferByteLengthjsArrayBuffer.[[ArrayBufferByteLength]]로 설정합니다.

  5. ? DetachArrayBuffer(jsArrayBuffer)를 수행합니다.

  6. targetRealm이 없으면 targetRealm현재 realm으로 설정합니다.

  7. jsTransferred? AllocateArrayBuffer(targetRealm.[[Intrinsics]].[[%ArrayBuffer%]], 0)로 설정합니다.

  8. jsTransferred.[[ArrayBufferData]]를 arrayBufferData로 설정합니다.

  9. jsTransferred.[[ArrayBufferByteLength]]를 arrayBufferByteLength로 설정합니다.

  10. 자바스크립트 값을 IDL 값으로 변환하여 jsTransferredArrayBuffer 타입으로 반환합니다.

다음과 같은 상황에서는 예외가 발생합니다:
  • arrayBufferdetached(분리됨)될 수 없는 경우, 해당 알고리즘 설명 (참고)에 명시된 이유 때문입니다;

  • arrayBuffer가 이미 detached(분리됨)인 경우;

  • realm에 충분한 메모리를 할당할 수 없을 때. 일반적으로 이는 realmarrayBuffer가 할당된 에이전트 클러스터(agent cluster)와 다를 때만 발생합니다. 동일한 에이전트 클러스터인 경우에는 구현체가 백킹 포인터만 변경하여 더 나은 성능과 할당 없이 동일한 관찰 가능한 결과를 얻을 수 있습니다.

3.2.27. 불변 배열 — FrozenArray<T>

불변 배열 타입의 값은 불변(frozen) JavaScript Array 객체 참조로 표현됩니다.

JavaScript 값 V변환하여 IDL FrozenArray<T> 값으로 만드는 알고리즘:

  1. values변환하여 V를 IDL 타입 sequence<T>으로 변환한 결과로 설정한다.

  2. 불변 배열 생성 알고리즘에 values를 넣어 반환한다.

불변 배열 생성 알고리즘: 타입 T의 값 시퀀스에 대해 아래 단계를 실행한다:

  1. arrayIDL → JavaScript 값 변환 알고리즘으로 타입 T 값 시퀀스를 변환한 결과로 설정한다.

  2. ! SetIntegrityLevel(array, "frozen")을 수행한다.

  3. array를 반환한다.

IDL → JavaScript 값 변환 알고리즘 결과로 IDL FrozenArray<T> 값을 JavaScript 값으로 변환하면, 해당 IDL FrozenArray<T>이 참조하는 같은 객체를 참조하는 Object 값이 된다.

3.2.27.1. 이터러블로부터 불변 배열 생성

이터러블 iterable과 이터레이터 getter method가 주어졌을 때, IDL 타입 FrozenArray<T>를 생성하는 알고리즘:

  1. values이터러블로부터 시퀀스 생성 알고리즘에 iterablemethod를 넣어 타입 sequence<T>로 변환한 결과로 설정한다.

  2. 불변 배열 생성 알고리즘에 values를 넣어 반환한다.

3.2.28. 관측 배열 — ObservableArray<T>

관측 배열 타입의 값은 observable array exotic object로 표현됩니다.

일반적인 변환 알고리즘 대신, 관측 배열 타입은 attribute getterattribute setter 알고리즘의 일부로 특별하게 처리됩니다.

JavaScript 바인딩에서 플랫폼 객체를 나타내는 JavaScript 객체는 backing observable array exotic object를 각 정규 attribute에 대해 관측 배열 타입에 대해 가집니다. 이는 attribute 정의 알고리즘의 일부로 생성 및 관리됩니다.

JavaScript 바인딩에서 관측 배열 attribute의 backing list는, 플랫폼 객체 obj와 attribute attribute가 주어졌을 때 다음 알고리즘에 의해 반환되는 list입니다:
  1. 단언: obj구현interface정규 attribute attribute가 있다.

  2. oaobjbacking observable array exotic objectattribute에 대해 설정한다.

  3. oa.[[ProxyHandler]].[[BackingList]]를 반환한다.

3.3. 확장 어트리뷰트

이 절에서는 JavaScript 바인딩에 영향을 주는 여러 확장 어트리뷰트를 정의합니다.

3.3.1. [AllowResizable]

[AllowResizable] 확장 어트리뷰트버퍼 타입에 나타나면, 해당하는 JavaScript ArrayBuffer 또는 SharedArrayBuffer 객체가 리사이즈 가능하도록 하는 새로운 IDL 타입을 생성합니다.

[AllowResizable] 확장 어트리뷰트버퍼 뷰 타입에 나타나고, [AllowShared] 확장 어트리뷰트가 없으면, 해당 버퍼 뷰 타입이 고정 길이 ArrayBuffer 대신 리사이즈 가능한 ArrayBuffer에 의해 지원되는 새로운 IDL 타입을 생성합니다.

[AllowResizable] 확장 어트리뷰트와 [AllowShared] 확장 어트리뷰트가 모두 버퍼 뷰 타입에 나타나면, 해당 버퍼 뷰 타입이 growable SharedArrayBuffer에 의해 지원될 수 있는 새로운 IDL 타입을 생성합니다.

[AllowResizable] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

버퍼 소스 타입이 아닌 타입은 [AllowResizable] 확장 어트리뷰트와 연관될 수 없습니다.

JavaScript 값을 IDL 버퍼 소스 타입으로 변환하는 규칙은 § 3.2.26 버퍼 소스 타입에서, [AllowResizable] 사용에 따른 구체적인 요구 사항을 확인할 수 있습니다.

두 확장 어트리뷰트 [AllowResizable]와 [AllowShared]의 사용 예시는 예제§ 3.3.2 [AllowShared]를 참고하세요.

3.3.2. [AllowShared]

[AllowShared] 확장 어트리뷰트버퍼 뷰 타입에 나타나면, 해당 객체가 ArrayBuffer뿐만 아니라 SharedArrayBuffer에 의해 지원될 수 있는 새로운 IDL 타입을 생성합니다.

[AllowShared] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

버퍼 뷰 타입이 아닌 타입은 [AllowShared] 확장 어트리뷰트와 연관될 수 없습니다.

JavaScript 값을 IDL 버퍼 뷰 타입으로 변환하는 규칙은 § 3.2.26 버퍼 소스 타입에서, [AllowShared] 사용에 따른 구체적인 요구 사항을 확인할 수 있습니다.

다음 IDL 프래그먼트는 [AllowResizable]와 [AllowShared] 확장 어트리뷰트의 조합을 보여줍니다:
[Exposed=Window]
interface ExampleBufferFeature {
  undefined writeInto(ArrayBufferView dest);
  undefined writeIntoResizable([AllowResizable] ArrayBufferView dest);
  undefined writeIntoShared([AllowShared] ArrayBufferView dest);
  undefined writeIntoSharedResizable([AllowResizable, AllowShared] ArrayBufferView dest);
};

이 정의에서,

3.3.3. [Clamp]

[Clamp] 확장 어트리뷰트정수 타입에 나타나면, JavaScript Number가 해당 IDL 타입으로 변환될 때 범위를 벗어난 값이 유효 값의 범위로 클램프(clamp)되도록 하는 새로운 IDL 타입을 생성합니다. 이는 모듈로 연산자를 사용하는 기존 방식(ToInt32, ToUint32 등)과 다릅니다.

[Clamp] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

[Clamp] 확장 어트리뷰트가 달린 타입은 읽기 전용 attribute에 나타나면 안 됩니다. 또한, 한 타입이 [Clamp]와 [EnforceRange] 확장 어트리뷰트 모두와 연관될 수 없습니다. 정수 타입이 아닌 타입은 [Clamp] 확장 어트리뷰트와 연관될 수 없습니다.

JavaScript 값을 다양한 IDL 정수 타입으로 변환하는 규칙은 § 3.2.4 정수 타입에서 [Clamp] 사용에 따른 구체적인 요구 사항을 확인할 수 있습니다.

다음 IDL 프래그먼트에서는 세 개의 octet 인자를 받는 두 개의 operation이 선언되어 있습니다. 하나는 세 인자 모두에 [Clamp] 확장 어트리뷰트를 사용하고, 다른 하나는 사용하지 않습니다:

[Exposed=Window]
interface GraphicsContext {
  undefined setColor(octet red, octet green, octet blue);
  undefined setColorClamped([Clamp] octet red, [Clamp] octet green, [Clamp] octet blue);
};

setColorClamped를 범위를 벗어난 Number 값과 함께 호출하면, octet 타입의 범위 [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] 확장 어트리뷰트interface, partial interface, interface mixin, partial interface mixin, callback interface, namespace, partial namespace, interface member, interface mixin member, 또는 namespace member에 나타나면, 해당 구성 요소가 노출되는 환경이 cross-origin isolated capability 가 true일 때만 노출됨을 나타냅니다. [CrossOriginIsolated] 확장 어트리뷰트는 다른 구성 요소에 사용하면 안 됩니다.

[CrossOriginIsolated] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

[CrossOriginIsolated] 가 오버로드된 operation에 나타나면, 모든 오버로드에 반드시 나타나야 합니다.

[CrossOriginIsolated] 확장 어트리뷰트는 다음 경우 모두에 명시될 수 없습니다:

참고: 이는 [CrossOriginIsolated] 확장 어트리뷰트를 멤버에 추가해도 정의 전체에 이미 해당 어트리뷰트가 있으면 멤버의 노출 범위가 추가로 제한되지 않기 때문입니다.

[CrossOriginIsolated] 확장 어트리뷰트가 없는 interface는 해당 어트리뷰트를 명시한 다른 interface를 상속하면 안 됩니다.

다음 IDL 프래그먼트는 모든 컨텍스트에서 실행 가능한 operation 1개와, cross-origin isolated 컨텍스트에서만 실행 가능한 operation 2개를 가진 interface를 정의합니다.

[Exposed=Window]
interface ExampleFeature {
  // 모든 컨텍스트에서 성공
  Promise <Result> calculateNotSoSecretResult();

  // 이 operation은 비격리 컨텍스트에 노출되지 않습니다. 해당 컨텍스트에서 ExampleFeature.prototype에 "calculateSecretResult" 속성이 없습니다.
  [CrossOriginIsolated] Promise<Result> calculateSecretResult();

  // 마찬가지로 이 attribute도 비격리 컨텍스트에 노출되지 않으며,
  // ExampleFeature.prototype에 "secretBoolean" 속성이 없습니다.
  [CrossOriginIsolated] readonly attribute boolean secretBoolean;
};

// HighResolutionTimer는 비격리 컨텍스트에 노출되지 않으며, 멤버도 노출되지 않습니다.
// 해당 컨텍스트에서 Window에 "HighResolutionTimer" 속성이 없습니다.
[Exposed=Window, CrossOriginIsolated]
interface HighResolutionTimer {
  DOMHighResTimeStamp getHighResolutionTime();
};

// 아래 interface mixin 멤버는 비격리 컨텍스트에서는 노출되지 않습니다. 즉, 비격리 컨텍스트에서는 ExampleFeature.prototype에 "snap" 속성이 없습니다.
[CrossOriginIsolated]
interface mixin Snapshotable {
  Promise<boolean> snap();
};
ExampleFeature includes Snapshotable;

// 반면, 아래 interface mixin 멤버는 호스트 interface에 [CrossOriginIsolated] 확장 어트리뷰트가 없으면 비격리 컨텍스트에서도 노출됩니다.
// 즉, 비격리 컨텍스트에서는 ExampleFeature.prototype에 "log" 속성이 있습니다.
interface mixin Loggable {
  Promise<boolean> log();
};
ExampleFeature includes Loggable;

3.3.5. [Default]

[Default] 확장 어트리뷰트정규 operation에 나타나면, 해당 operation이 호출될 때 적절한 기본 메서드 단계를 수행해야 함을 나타냅니다.

[Default] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

[Default] 확장 어트리뷰트는 정규 operation 외에는 사용할 수 없으며, 해당 operation에 기본 메서드 단계가 정의되어 있어야 합니다.

예시로, [Default] 확장 어트리뷰트는 toJSON 정규 operation에 사용할 수 있습니다:

[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();

// 아래와 같은 객체로 평가됨 ("breed"는 Dog 인터페이스가 기본 toJSON 단계를 사용하지 않으므로 없음):
//
// {
//   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 타입으로 변환될 때 범위를 벗어난 값이 예외를 발생시키도록 하는 새로운 IDL 타입을 생성합니다. 기존의 모듈로 연산자(ToInt32, ToUint32 등)를 사용하여 유효 값으로 변환하는 대신, 값이 범위를 벗어나면 예외가 발생합니다. Number는 먼저 0 방향으로 반올림된 후 범위 검사를 합니다.

[EnforceRange] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

[EnforceRange] 확장 어트리뷰트가 달린 타입은 읽기 전용 attribute에 나타나면 안 됩니다. 또한 한 타입이 [Clamp]와 [EnforceRange] 확장 어트리뷰트 모두와 연관될 수 없습니다. 정수 타입이 아닌 타입은 [EnforceRange] 확장 어트리뷰트와 연관될 수 없습니다.

JavaScript 값을 다양한 IDL 정수 타입으로 변환하는 규칙은 § 3.2 JavaScript 타입 매핑에서 [EnforceRange] 사용에 따른 구체적인 요구 사항을 확인할 수 있습니다.

다음 IDL 프래그먼트에서는 세 개의 octet 인자를 받는 두 개의 operation이 선언되어 있습니다. 하나는 세 인자 모두에 [EnforceRange] 확장 어트리뷰트를 사용하고, 다른 하나는 사용하지 않습니다:

[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를 범위를 벗어난 Number 값과 함께 호출하면, octet 타입의 범위를 벗어나므로 예외가 발생합니다.

// GraphicsContext 인스턴스를 얻음.
var context = getGraphicsContext();

// [EnforceRange]가 없는 버전은 ToUint8을 사용하여 Number를 octet으로 변환합니다.
// 이는 setColor(255, 255, 1)을 호출한 것과 같습니다.
context.setColor(-1, 255, 257);

// setColorEnforcedRange를 호출하면 Number가 0 방향으로 반올림됩니다.
// 이는 setColor(0, 255, 255)를 호출한 것과 같습니다.
context.setColorEnforcedRange(-0.9, 255, 255.2);

// 아래는 예외(TypeError)를 발생시킵니다. 반올림 후에도 첫 번째와 세 번째 인자가 범위 밖에 있기 때문입니다.
context.setColorEnforcedRange(-1, 255, 256);

3.3.7. [Exposed]

[Exposed] 확장 어트리뷰트interface, partial interface, interface mixin, partial interface mixin, callback interface, namespace, partial namespace, 또는 개별 interface member, interface mixin member, 또는 namespace member에 나타나면, 해당 구성요소가 특정 글로벌 인터페이스 집합에 노출됨을 의미합니다.

[Exposed] 확장 어트리뷰트식별자, 식별자 리스트 또는 와일드카드를 가져야 합니다. 명시된 각 식별자는 어떤 interface글로벌 이름이어야 하며, 중복되면 안 됩니다.

자신의 노출 집합(own exposure set) 은 식별자들의 집합이거나, 특수 값 *입니다. 정의는 다음과 같습니다:

[Exposed] 확장 어트리뷰트식별자 I를 가질 때

자신의 노출 집합집합 « I » 입니다.

[Exposed] 확장 어트리뷰트식별자 리스트 I를 가질 때

자신의 노출 집합집합 I 입니다.

[Exposed] 확장 어트리뷰트와일드카드를 가질 때

자신의 노출 집합* 입니다.

[Exposed=*]는 신중하게 사용해야 합니다. API가 새로운 기능을 노출하지 않을 때만 적합합니다. API가 일부 환경에서 제한되거나 비활성화될 수 있다면, 글로벌을 명시적으로 리스트하는 것이 더 바람직합니다.

노출 집합 교집합은 구성 요소 C와 interface-or-null H에 대해 다음과 같이 정의됩니다:

  1. 단언: Cinterface member, interface mixin member, namespace member, partial interface, partial interface mixin, partial namespace, 또는 interface mixin이다.

  2. 단언: Hinterface 또는 null이다.

  3. H가 null이면, C자신의 노출 집합을 반환한다.

  4. C자신의 노출 집합*이면, H노출 집합을 반환한다.

  5. H노출 집합*이면, C자신의 노출 집합을 반환한다.

  6. C자신의 노출 집합H노출 집합교집합을 반환한다.

구성 요소 C노출 집합(exposure set)을 얻으려면, 다음 단계를 수행합니다:
  1. 단언: Cinterface, callback interface, namespace, interface member, interface mixin member, 또는 namespace member이다.

  2. HCinterface mixin member일 경우 호스트 인터페이스로, 그렇지 않으면 null로 설정한다.

  3. Cinterface member, interface mixin member, 또는 namespace member라면:

    1. [Exposed] 확장 어트리뷰트C에 명시되어 있으면, 노출 집합 교집합CH로 반환한다.

    2. Cinterface, partial interface, interface mixin, partial interface mixin, namespace, 또는 partial namespaceC로 설정한다.

  4. Cpartial interface, partial interface mixin, 또는 partial namespace일 경우:

    1. [Exposed] 확장 어트리뷰트C에 명시되어 있으면, 노출 집합 교집합CH로 반환한다.

    2. C를 원래 interface, interface mixin, 또는 namespace 정의의 C로 설정한다.

  5. Cinterface mixin일 경우:

    1. 단언: H는 null이 아니다.

    2. [Exposed] 확장 어트리뷰트C에 명시되어 있으면, 노출 집합 교집합CH로 반환한다.

    3. CH로 설정한다.

  6. 단언: Cinterface, callback interface, 또는 namespace이다.

  7. 단언: [Exposed] 확장 어트리뷰트C에 명시되어 있다.

  8. C자신의 노출 집합을 반환한다.

[Exposed] 가 오버로드된 operation에 나타나면, 모든 오버로드에 동일하게 나타나야 합니다.

[Exposed] 확장 어트리뷰트는 interface member, interface mixin member, 또는 namespace member에, 그리고 partial interface, partial interface mixin, 또는 partial namespace 정의 모두에 명시될 수 없습니다.

참고: [Exposed] 확장 어트리뷰트partial interface, partial interface mixin, 또는 partial namespace에 추가하는 것은 해당 정의의 각 멤버에 어노테이션하는 약식 표현입니다.

[Exposed] 가 partial interface 또는 partial namespace에 나타나면, partial의 자신의 노출 집합은 partial의 원래 interface 또는 namespace노출 집합의 부분집합이어야 합니다.

[Exposed] 가 interface member 또는 namespace member에 나타나면, member노출 집합은 해당 interface 또는 namespace노출 집합의 부분집합이어야 합니다.

[Exposed] 가 partial interface mixin과 그 원래 interface mixin 모두에 나타나면, partial interface mixin자신의 노출 집합interface mixin자신의 노출 집합의 부분집합이어야 합니다.

[Exposed] 가 interface mixin memberinterface mixin 모두에 나타나면, interface mixin member자신의 노출 집합interface mixin자신의 노출 집합의 부분집합이어야 합니다.

interface X가 다른 interface Y상속하면, X노출 집합Y노출 집합의 부분집합이어야 합니다.

참고: interface mixin은 여러 interface포함될 수 있으므로, 그 멤버노출 집합은 그것을 포함하는 interface에 따라 결정된다. interface mixin member, partial interface mixin, 또는 interface mixin에 [Exposed] 확장 어트리뷰트가 있으면, 해당 interface mixin member노출 집합은 해당 구성 요소의 자신의 노출 집합호스트 인터페이스노출 집합교집합이 된다. 그렇지 않으면 호스트 인터페이스노출 집합이 된다.

interface, callback interface, namespace, 또는 member construct는 주어진 realm realm에서 다음 단계가 true를 반환할 때 노출됨(exposed) 상태입니다:
  1. construct노출 집합*가 아니고, realm.[[GlobalObject]]가 construct노출 집합에 포함된 interface를 구현하지 않는다면, false를 반환한다.

  2. realm설정 객체보안 컨텍스트가 아니고, construct가 [SecureContext]에서 조건부 노출됨 상태라면, false를 반환한다.

  3. realm설정 객체cross-origin isolated capability가 false이고, construct가 [CrossOriginIsolated]에서 조건부 노출됨 상태라면, false를 반환한다.

  4. true를 반환한다.

interface, callback interface, namespace, 또는 member construct가 주어진 확장 어트리뷰트 exposure condition에서 조건부 노출됨(conditionally exposed) 상태인지 판단하는 단계:
  1. 단언: constructinterface, callback interface, namespace, interface member, interface mixin member, 또는 namespace member이다.

  2. Hconstructinterface mixin member일 경우 호스트 인터페이스로, 그렇지 않으면 null로 설정한다.

  3. constructinterface member, interface mixin member, 또는 namespace member라면:

    1. exposure condition 확장 어트리뷰트construct에 명시되어 있으면, true를 반환한다.

    2. 그렇지 않으면 constructinterface, partial interface, interface mixin, partial interface mixin, namespace, 또는 partial namespaceconstruct로 설정한다.

  4. constructpartial interface, partial interface mixin, 또는 partial namespace일 경우:

    1. exposure condition 확장 어트리뷰트construct에 명시되어 있으면, true를 반환한다.

    2. 그렇지 않으면 construct를 원래 interface, interface mixin, 또는 namespace 정의의 construct로 설정한다.

  5. constructinterface mixin일 경우:

    1. exposure condition 확장 어트리뷰트construct에 명시되어 있으면, true를 반환한다.

    2. 그렇지 않으면 constructH로 설정한다.

  6. 단언: constructinterface, callback interface, 또는 namespace이다.

  7. exposure condition 확장 어트리뷰트construct에 명시되어 있으면, true를 반환한다.

  8. 그렇지 않으면 false를 반환한다.

참고: JavaScript 글로벌 객체의 관련 설정 객체가 시간이 지나도 보안 컨텍스트 또는 cross-origin isolated capability 여부가 바뀔 수 없으므로, 인터페이스 또는 인터페이스 멤버의 프로퍼티를 생성할지 결정하는 것은 초기 객체가 생성될 때 한 번만 이루어지면 됩니다.

자세한 요구사항은 § 3.7 인터페이스, § 3.7.5 상수, § 3.7.6 속성, § 3.7.7 연산 및 [Exposed] 사용 규칙을 참조하세요.

[Exposed]는 interface, callback interface, namespace, 또는 개별 interface member, mixin, namespace member가 워커, 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] 확장 어트리뷰트interface에 나타나면, 해당 interface를 구현하는 객체가 realm의 글로벌 객체로 사용됨을 의미합니다.

[Global] 확장 어트리뷰트는 또한 해당 interface글로벌 이름(global names)을 정의합니다:

[Global] 확장 어트리뷰트식별자(identifier)를 가지는 경우

« 주어진 식별자 »

[Global] 확장 어트리뷰트식별자 리스트(identifier list)를 가지는 경우

식별자 리스트

[Global] 확장 어트리뷰트는 위의 형태 중 하나여야 합니다.

참고: 해당 interface글로벌 이름(global names)은 [Exposed] 확장 어트리뷰트에서 참조할 수 있는 식별자입니다. 하나의 이름이 여러 글로벌 인터페이스에서 공유될 수 있으므로, 하나의 인터페이스가 [Exposed]를 사용해서 여러 글로벌에 쉽게 노출될 수 있습니다. 예를 들어 "Worker"는 여러 스레드 관련 글로벌 인터페이스를 참조합니다.

이러한 글로벌 interface의 경우 프로토타입 체인 구조와 interface member에 해당하는 프로퍼티가 프로토타입 객체에 어떻게 반영되는지가 다른 인터페이스와 다릅니다. 구체적으로:

  1. 모든 이름있는 프로퍼티(named properties)는 프로토타입 체인 상의 객체(즉, named properties object)에 노출되며, 객체 자체에는 노출되지 않습니다.

  2. interface member들은 interface에서 객체 자체의 프로퍼티로 대응되며, interface prototype objects에는 대응되지 않습니다.

모든 realm글로벌 프로토타입 체인 변경 가능(is global prototype chain mutable) 불리언을 가지며, realm이 생성될 때 설정할 수 있습니다. 해당 값은 realm의 수명 동안 변경될 수 없습니다. 기본값은 false입니다.

이는 ShadowRealm 글로벌이 mutable 프로토타입을 가질 수 있게 합니다.

이름있는 프로퍼티(named properties)를 프로토타입 체인 객체에 배치하는 이유는 변수 선언 및 bareword 할당이 글로벌 객체의 프로퍼티로 이름있는 프로퍼티를 shadow하도록 하기 위함입니다.

interface member에 대응하는 프로퍼티를 객체 자체에 배치하면, 아래와 같은 feature detection 코드가 동작하게 됩니다:

var indexedDB = window.indexedDB || window.webkitIndexedDB ||
                window.mozIndexedDB || window.msIndexedDB;

var requestAnimationFrame = window.requestAnimationFrame ||
                            window.mozRequestAnimationFrame || ...;

JavaScript에서 변수 선언이 처리되는 방식 때문에, 위 코드는 window.indexedDBwindow.requestAnimationFrameundefined로 평가됨을 의미합니다. 이는 shadowing 변수 프로퍼티가 할당 이전에 이미 생성되었기 때문입니다.

[Global] 확장 어트리뷰트interface에 사용된 경우:

[Global]이 partial interface 정의에 지정된 경우, 해당 partial interface 정의는 named property getter를 정의하는 부분이어야 합니다.

[Global] 확장 속성은 동일한 realm에서 하나 이상의 객체가 구현할 수 있는 인터페이스에 사용해서는 안 됩니다.

참고: 이는 named properties object가 프로토타입 체인에 위치하며, 여러 객체의 named properties가 해당 객체에서 모두 노출되는 것은 의미가 없기 때문입니다.

interface에 [Global] 확장 어트리뷰트가 선언된 경우, 해당 interface 전체에 걸쳐 동일한 식별자를 가진 member가 둘 이상 존재할 수 없습니다. 또한, 하나의 stringifier나 하나의 iterable 선언, async iterable 선언, maplike 선언, setlike 선언도 둘 이상 존재할 수 없습니다.

참고: interface의 모든 member는 해당 interface를 구현하는 객체에 모두 평탄화되어 할당되기 때문입니다.

자세한 요구사항은 § 3.7.4 이름있는 프로퍼티 객체(named properties object)에서 [Global] 사용 시 이름있는 프로퍼티 관련 규칙, § 3.7.5 상수, § 3.7.6 속성, § 3.7.7 연산을 참고하세요.

Window interface는 frame을 Window 객체의 프로퍼티로 노출합니다. Window 객체는 JavaScript 글로벌 객체 역할도 하므로, 변수 선언이나 이름있는 프로퍼티에 대한 할당은 해당 값으로 대체됩니다. attribute에 대해 변수를 선언하면 기존 프로퍼티가 대체되지 않습니다.

[Exposed=Window, Global=Window]
interface Window {
  getter any (DOMString name);
  attribute DOMString name;
  // ...
};

아래 HTML 문서는 Window 객체의 이름있는 프로퍼티가 shadow되는 방법과, attribute와 같은 이름의 변수 선언이 기존 프로퍼티를 대체하지 않는 방법을 보여줍니다:

<!DOCTYPE html>
<title>Variable declarations and assignments on Window</title>
<iframe name=abc></iframe>
<!-- Shadowing named properties -->
<script>
  window.abc;    // iframe의 Window 객체를 반환.
  abc = 1;       // 이름있는 프로퍼티를 shadow함.
  window.abc;    // 1을 반환.
</script>

<!-- IDL attribute 프로퍼티 보존 -->
<script>
  Window.prototype.def = 2;         // 프로토타입에 프로퍼티 추가.
  window.hasOwnProperty("length");  // true 반환.
  length;                           // 1 반환.
  def;                              // 2 반환.
</script>
<script>
  var length;                       // 변수 선언은 기존 프로퍼티를 대체하지 않음.
  length;                           // 1 반환.
  var def;                          // 변수 선언은 shadow 프로퍼티를 생성.
  def;                              // undefined 반환.
</script>

3.3.9. [NewObject]

[NewObject] 확장 어트리뷰트정규 또는 static operation에 나타나면, 해당 operation을 호출할 때 항상 새로 생성된 객체의 참조를 반환해야 함을 나타냅니다.

[NewObject] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

[NewObject] 확장 어트리뷰트는 정규 또는 static operation 중, 반환 타입interface 타입 또는 promise 타입인 것에만 사용할 수 있습니다.

예를 들어, 이 확장 어트리뷰트는 createElement() operation(Document interface의 메서드)에 적합합니다. 호출 시 항상 새 객체가 반환되기 때문입니다. [DOM]

[Exposed=Window]
interface Document : Node {
  [NewObject] Element createElement(DOMString localName);
  // ...
};

3.3.10. [PutForwards]

[PutForwards] 확장 어트리뷰트읽기 전용 정규 attribute 선언에, 해당 타입이 interface 타입일 때 나타나면, 해당 attribute에 값을 할당할 때 특정 동작을 하도록 합니다. 즉, 할당이 그 attribute가 참조하는 객체의 특정 attribute(확장 어트리뷰트 인자에 명시된)에 "전달"됩니다.

[PutForwards] 확장 어트리뷰트는 식별자를 가져야 합니다. 다음을 가정합니다:

이 경우, Jattribute B가 존재해야 하며, 해당 식별자N 입니다. I를 구현하는 객체의 A에 값을 할당하면, 대신 A가 참조하는 객체의 B attribute에 값이 할당됩니다.

[PutForwards]-가 붙은 attribute는 체인(chained)이 가능합니다. 즉, [PutForwards] 확장 어트리뷰트가 붙은 attribute가 다시 같은 확장 어트리뷰트를 가진 attribute를 참조할 수 있습니다. 단, 전달된 할당 체인에 사이클이 있으면 안 됩니다. 사이클은 전달된 할당을 따라가다 특정 attribute가 다시 나타나면 발생한 것입니다.

[PutForwards] 확장 어트리뷰트가 붙은 attribute는 [LegacyLenientSetter] 또는 [Replaceable] 확장 어트리뷰트와 함께 선언할 수 없습니다.

[PutForwards] 확장 어트리뷰트는 읽기 전용 attribute가 아닌 곳에 사용할 수 없습니다.

[PutForwards] 확장 어트리뷰트는 static attribute에 사용할 수 없습니다.

[PutForwards] 확장 어트리뷰트는 namespace에 선언된 attribute에 사용할 수 없습니다.

구현 방법은 속성(Attributes) 절을 참고하세요.

다음 IDL 프래그먼트는 이름(Name)과 사람(Person) interface를 정의합니다. Person interface의 name attribute에 [PutForwards] 확장 어트리뷰트를 사용하여, 해당 attribute에 값을 할당하면 Person 객체의 full attribute에 값이 할당됨을 나타냅니다:

[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] 확장 어트리뷰트읽기 전용 정규 attribute에 나타나면, 해당 플랫폼 객체에서 해당 프로퍼티를 할당하면 할당된 값으로 동일한 이름의 own property가 객체에 생성됩니다. 이 프로퍼티는 interface prototype object에 있는 accessor property를 shadow하게 됩니다.

[Replaceable] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

[Replaceable] 확장 어트리뷰트가 붙은 attribute는 [LegacyLenientSetter] 또는 [PutForwards] 확장 어트리뷰트와 함께 선언할 수 없습니다.

[Replaceable] 확장 어트리뷰트는 읽기 전용이 아닌 attribute에 사용할 수 없습니다.

[Replaceable] 확장 어트리뷰트는 static attribute에 사용할 수 없습니다.

[Replaceable] 확장 어트리뷰트는 namespace에 선언된 attribute에 사용할 수 없습니다.

구체적 요구사항은 § 3.7.6 속성에서 [Replaceable] 사용 규칙을 참고하세요.

다음 IDL 프래그먼트는 카운터를 증가시키는 operation과 0으로 초기화되는 카운터의 값을 노출하는 attribute를 가진 interface를 정의합니다:

[Exposed=Window]
interface Counter {
  [Replaceable] readonly attribute unsigned long value;
  undefined increment();
};

플랫폼 객체에서 value 프로퍼티에 값을 할당하면, 해당 attribute에 대응하는 프로퍼티를 shadow합니다:

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와는 무관한 값으로 shadow.
                                                         // 

counter.hasOwnProperty("value");                         // true 반환.

counter.increment();
counter.value;                                           // 'a' 반환.

delete counter.value;                                    // 원래 프로퍼티 복원.
counter.value;                                           // 3 반환.

3.3.12. [SameObject]

[SameObject] 확장 어트리뷰트읽기 전용 attribute에 나타나면, 해당 객체의 attribute 값을 얻을 때 항상 동일한 값을 반환해야 함을 나타냅니다.

[SameObject] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

[SameObject] 확장 어트리뷰트는 읽기 전용 attribute 중, 타입이 interface 타입 또는 object일 때만 사용할 수 있습니다.

예시로, 이 확장 어트리뷰트는 implementation attribute(Document interface의 속성)에 적합합니다. 해당 Document 객체에 대해 항상 동일한 객체가 반환되기 때문입니다. [DOM]

[Exposed=Window]
interface Document : Node {
  [SameObject] readonly attribute DOMImplementation implementation;
  // ...
};

3.3.13. [SecureContext]

[SecureContext] 확장 어트리뷰트interface, partial interface, interface mixin, partial interface mixin, callback interface, namespace, partial namespace, interface member, interface mixin member, 또는 namespace member에 나타나면, 해당 구성 요소가 노출되는 환경이 보안 컨텍스트(secure context)일 때만 노출됨을 나타냅니다. [SecureContext] 확장 어트리뷰트는 다른 구성 요소에 사용하면 안 됩니다.

[SecureContext] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

[SecureContext] 가 오버로드된 operation에 나타나면, 모든 오버로드에 반드시 나타나야 합니다.

[SecureContext] 확장 어트리뷰트는 다음 경우 모두에 명시될 수 없습니다:

참고: [SecureContext] 확장 어트리뷰트를 멤버에 추가해도 정의 전체에 이미 해당 어트리뷰트가 있으면 멤버의 노출 범위가 추가로 제한되지 않기 때문입니다.

[SecureContext] 확장 어트리뷰트가 없는 interface는 해당 어트리뷰트를 명시한 다른 interface를 상속하면 안 됩니다.

[SecureContext] 는 [CrossOriginIsolated]에서 조건부 노출됨 상태인 구성 요소에는 명시할 수 없습니다. (모든 cross-origin isolated 환경은 항상 보안 컨텍스트이므로 중복입니다.)

다음 IDL 프래그먼트는 모든 컨텍스트에서 실행 가능한 operation 1개와, 보안 컨텍스트에서만 실행 가능한 operation 2개를 가진 interface를 정의합니다.

[Exposed=Window]
interface ExampleFeature {
  // 모든 컨텍스트에서 성공
  Promise <Result> calculateNotSoSecretResult();

  // 이 operation은 비보안 컨텍스트에 노출되지 않습니다. 해당 컨텍스트에서 ExampleFeature.prototype에 "calculateSecretResult" 속성이 없습니다.
  [SecureContext] Promise<Result> calculateSecretResult();

  // 마찬가지로 이 attribute도 비보안 컨텍스트에 노출되지 않으며,
  // ExampleFeature.prototype에 "secretBoolean" 속성이 없습니다.
  [SecureContext] readonly attribute boolean secretBoolean;
};

// HeartbeatSensor는 비보안 컨텍스트에 노출되지 않으며, 멤버도 노출되지 않습니다.
// 해당 컨텍스트에서 Window에 "HeartbeatSensor" 속성이 없습니다.
[Exposed=Window, SecureContext]
interface HeartbeatSensor {
  Promise<float> getHeartbeatsPerMinute();
};

// 아래 interface mixin 멤버는 비보안 컨텍스트에서는 노출되지 않습니다. 즉, 비보안 컨텍스트에서는 ExampleFeature.prototype에 "snap" 속성이 없습니다.
[SecureContext]
interface mixin Snapshotable {
  Promise<boolean> snap();
};
ExampleFeature includes Snapshotable;

// 반면, 아래 interface mixin 멤버는 호스트 interface에 [SecureContext] 확장 어트리뷰트가 없으면 비보안 컨텍스트에서도 노출됩니다.
// 즉, 비보안 컨텍스트에서는 ExampleFeature.prototype에 "log" 속성이 있습니다.
interface mixin Loggable {
  Promise<boolean> log();
};
ExampleFeature includes Loggable;

3.3.14. [Unscopable]

[Unscopable] 확장 어트리뷰트정규 attribute 또는 정규 operation에 나타나면, 해당 인터페이스의 멤버를 가진 객체가 해당 멤버의 프로퍼티명을 객체 환경 레코드의 base object에 포함하지 않게 됨을 의미합니다. 결과적으로 프로퍼티명과 동일한 식별자를 사용하는 경우 with 문에서 해당 프로퍼티가 해석되지 않습니다. 이는 프로퍼티명을 interface prototype object%Symbol.unscopables% 프로퍼티 값에 포함시켜 구현됩니다.

[Unscopable] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

[Unscopable] 확장 어트리뷰트는 정규 attribute 또는 정규 operation 외의 곳에 사용하면 안 됩니다.

[Unscopable] 확장 어트리뷰트는 namespace에 선언된 attribute에는 사용할 수 없습니다.

구체적인 요구사항은 § 3.7.3 인터페이스 프로토타입 객체에서 [Unscopable] 관련 규칙을 참고하세요.

예를 들어, 다음과 같이 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의 동작을 명시할 필요가 있을 때만 사용해야 합니다.

이러한 확장 어트리뷰트 사용을 고려하는 편집자는 이슈를 등록 하여 논의하는 것이 권장됩니다.

3.4.1. [LegacyFactoryFunction]

이 기능 대신 인터페이스에 생성자 operation을 정의하세요.

[LegacyFactoryFunction] 확장 어트리뷰트interface에 나타나면, JavaScript 글로벌 객체에 지정된 이름의 프로퍼티가 생성되고, 그 값은 해당 인터페이스를 구현하는 객체를 생성할 수 있는 함수가 됩니다. 하나의 interface에 여러 [LegacyFactoryFunction] 확장 어트리뷰트가 나타날 수 있습니다.

[LegacyFactoryFunction] 확장 어트리뷰트는 named argument list를 가져야 합니다. "=" 뒤에 오는 identifier가 [LegacyFactoryFunction]의 식별자(identifier)입니다. interface에 나타난 각 [LegacyFactoryFunction] 확장 어트리뷰트마다, 해당 프로퍼티의 값인 생성자 함수에 인자를 전달하여 interface 구현 객체를 생성할 수 있는 방법이 제공됩니다.

식별자는 다른 interface의 [LegacyFactoryFunction] 확장 어트리뷰트에 사용된 것과 같으면 안 되며, 이 interface 또는 다른 interface의 [LegacyWindowAlias] 확장 어트리뷰트에 사용된 식별자와 같아도 안 됩니다. 또한 interface object가 있는 interface의 식별자와 같아도 안 되고, reserved identifier도 사용할 수 없습니다.

[LegacyFactoryFunction] 와 [Global] 확장 어트리뷰트는 같은 interface에 동시에 명시할 수 없습니다.

레거시 factory 함수의 구현 방법은 § 3.7.2 Legacy factory functions에서 자세히 설명합니다.

다음 IDL은 [LegacyFactoryFunction] 확장 어트리뷰트를 사용하는 interface를 정의합니다.

[Exposed=Window,
 LegacyFactoryFunction=Audio(DOMString src)]
interface HTMLAudioElement : HTMLMediaElement {
  // ...
};

이 interface를 지원하는 JavaScript 구현에서는 HTMLAudioElement 객체를 Audio 함수로 생성할 수 있습니다.

typeof Audio;                   // 'function' 반환.

var a2 = new Audio('a.flac');   // 인자 1개 생성자를 사용해 HTMLAudioElement 생성.
                                // 

레거시 동작으로, 이러한 factory 함수는 prototype 프로퍼티가 원래 interface의 prototype과 같습니다:

console.assert(Audio.prototype === HTMLAudioElement.prototype);

3.4.2. [LegacyLenientSetter]

[LegacyLenientSetter] 확장 어트리뷰트읽기 전용 정규 attribute에 나타나면, 해당 attribute의 accessor property에 no-op setter가 생성됩니다. 이로 인해 strict mode에서 잘못된 프로퍼티 할당이 예외 없이 무시됩니다.

실제 페이지에서는 저자가 IDL attribute를 polyfill하려고 프로퍼티에 할당하는 경우가 종종 있으나, 실제로는 해당 프로퍼티가 이미 존재하는 경우도 있습니다. strict mode에서는 예외가 발생하여 페이지가 깨질 수 있지만, [LegacyLenientSetter] 가 없으면 브라우저에서 해당 기능을 ship할 수 없게 될 수도 있습니다.

[LegacyLenientSetter] 확장 어트리뷰트는 인자를 가지지 않아야 합니다. 읽기 전용 정규 attribute 외의 곳에는 사용할 수 없습니다.

[LegacyLenientSetter] 확장 어트리뷰트가 붙은 attribute는 [PutForwards] 또는 [Replaceable] 확장 어트리뷰트와 함께 선언할 수 없습니다.

[LegacyLenientSetter] 확장 어트리뷰트는 namespace에 선언된 attribute에는 사용할 수 없습니다.

구현 방법은 속성(Attributes) 절을 참고하세요.

다음 IDL은 [LegacyLenientSetter] 확장 어트리뷰트를 사용하는 interface를 정의합니다.

[Exposed=Window]
interface Example {
  [LegacyLenientSetter] readonly attribute DOMString x;
  readonly attribute DOMString y;
};

이 인터페이스를 지원하는 JavaScript 구현에서는 x에 대응하는 accessor property에 setter가 존재하며, strict mode에서도 아무 동작을 하지 않습니다.

"use strict";

var example = getExample();  // Example 인스턴스 획득.

// strict mode에서도 setter는 no-op이므로 예외 없음.
example.x = 1;

// strict mode에서 setter 없으므로 TypeError 발생.
example.y = 1;

3.4.3. [LegacyLenientThis]

[LegacyLenientThis] 확장 어트리뷰트정규 attribute에 나타나면, 해당 attribute의 getter나 setter를 this 값이 해당 attribute가 선언된 interface구현하지 않는 객체로 호출하면, 아무 동작도 하지 않게 됩니다.

[LegacyLenientThis] 확장 어트리뷰트는 인자를 가지지 않아야 합니다. static attribute에는 사용할 수 없습니다.

[LegacyLenientThis] 확장 어트리뷰트는 namespace에 선언된 attribute에는 사용할 수 없습니다.

구현 방법은 속성(Attributes) 절을 참고하세요.

다음 IDL은 [LegacyLenientThis] 확장 어트리뷰트를 사용하는 interface를 정의합니다.

[Exposed=Window]
interface Example {
  [LegacyLenientThis] attribute DOMString x;
  attribute DOMString y;
};

이 인터페이스를 지원하는 JavaScript 구현에서는 x에 대응하는 accessor property의 getter와 setter를 Example 객체가 아닌 객체로도 호출할 수 있습니다.

var example = getExample();  // Example 인스턴스 획득.
var obj = { };

// 정상 동작.
example.x;

// this 값이 Example 객체가 아니고 [LegacyLenientThis]가 사용되었으므로 무시됨.
Object.getOwnPropertyDescriptor(Example.prototype, "x").get.call(obj);

// Example.prototype도 Example 객체가 아니므로 무시됨.
Example.prototype.x;

// Example.prototype이 Example 객체가 아니므로 TypeError 발생.
Example.prototype.y;

3.4.4. [LegacyNamespace]

이 기능 대신, 인터페이스 이름을 특정 접두사로 시작하는 네이밍 컨벤션을 사용하여 식별자에 점 없이 작성하세요.

[LegacyNamespace] 확장 어트리뷰트interface에 나타나면, 해당 인터페이스 객체가 글로벌 객체의 프로퍼티로 생성되지 않고, 확장 어트리뷰트 인자로 지정된 namespace의 프로퍼티로 생성됨을 의미합니다.

[LegacyNamespace] 확장 어트리뷰트는 식별자를 가져야 하며, 해당 식별자는 namespace 정의의 식별자여야 합니다.

[LegacyNamespace] 와 [LegacyNoInterfaceObject] 확장 어트리뷰트는 같은 interface에 동시에 명시할 수 없습니다.

interface가 namespace에 어떻게 노출되는지에 대한 자세한 내용은 § 3.13.1 네임스페이스 객체를 참고하세요.

다음 IDL 프래그먼트namespace와 [LegacyNamespace]으로 정의된 interface를 보여줍니다.
namespace Foo { };

[LegacyNamespace=Foo]
interface Bar {
  constructor();
};

위 네임스페이스와 인터페이스를 지원하는 JavaScript 구현에서는, Bar 생성자를 다음과 같이 접근할 수 있습니다:

var instance = new Foo.Bar();

3.4.5. [LegacyNoInterfaceObject]

[LegacyNoInterfaceObject] 확장 어트리뷰트interface에 나타나면, 해당 인터페이스의 JavaScript 바인딩에서 interface object가 존재하지 않음을 의미합니다.

[LegacyNoInterfaceObject] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

[LegacyNoInterfaceObject] 확장 어트리뷰트는 해당 interface에 생성자static operation이 정의되어 있으면 사용할 수 없습니다.

이 확장 어트리뷰트가 명시되지 않은 interface는, 이 확장 어트리뷰트가 명시된 interface를 상속하면 안 됩니다.

구체적 요구사항은 § 3.7 인터페이스에서 [LegacyNoInterfaceObject] 사용 규칙을 참고하세요.

다음 IDL 프래그먼트는 하나는 JavaScript 글로벌 객체에 인터페이스 객체가 노출되는 interface, 하나는 인터페이스 객체가 노출되지 않는 interface를 정의합니다:

[Exposed=Window]
interface Storage {
  undefined addEntry(unsigned long key, any value);
};

[Exposed=Window,
 LegacyNoInterfaceObject]
interface Query {
  any lookupEntry(unsigned long key);
};

위 IDL의 JavaScript 구현에서는 Storage의 프로토타입을 조작할 수 있지만, Query의 프로토타입은 조작할 수 없습니다.

typeof Storage;                        // "object" 반환

// Storage.addEntry에 alert() 트레이싱 추가
var fn = Storage.prototype.addEntry;
Storage.prototype.addEntry = function(key, value) {
  alert('Calling addEntry()');
  return fn.call(this, key, value);
};

typeof Query;                          // "undefined" 반환

var fn = Query.prototype.lookupEntry;  // 예외 발생, Query는 정의되지 않음

3.4.6. [LegacyNullToEmptyString]

[LegacyNullToEmptyString] 확장 어트리뷰트DOMString 또는 USVString 타입에 나타나면, JavaScript null을 해당 IDL 타입으로 변환할 때 기본 동작과 다르게 처리합니다. 기본적으로는 "null"로 문자열화되지만, 이 확장 어트리뷰트가 있으면 빈 문자열로 변환됩니다.

[LegacyNullToEmptyString] 확장 어트리뷰트는 DOMString 또는 USVString이 아닌 타입에 연관될 수 없습니다.

참고: DOMString?에도 [LegacyNullToEmptyString]을 사용하면 안 됩니다. null이 해당 타입의 유효 값이기 때문입니다.

구체적 요구사항은 § 3.2.10 DOMString에서 [LegacyNullToEmptyString] 사용 규칙을 참고하세요.

다음 IDL 프래그먼트는 한 attribute의 타입과 한 operation의 인자 타입에 확장 어트리뷰트가 붙은 예시입니다:
[Exposed=Window]
interface Dog {
  attribute DOMString name;
  attribute [LegacyNullToEmptyString] DOMString owner;

  boolean isMemberOfBreed([LegacyNullToEmptyString] DOMString breedName);
};

Dog interface를 구현하는 JavaScript에서는, owner 프로퍼티에 null을 할당하거나, isMemberOfBreed 함수의 인자로 null을 전달하면 "null" 대신 빈 문자열로 처리됩니다:

var d = getDog();         // Dog 인터페이스를 구현하는 플랫폼 객체 d

d.name = null;            // .name 프로퍼티에 "null"이 할당됨.

d.owner = null;           // .owner 프로퍼티에 ""이 할당됨.

d.isMemberOfBreed(null);  // isMemberOfBreed 함수에 ""이 전달됨.

3.4.7. [LegacyOverrideBuiltIns]

[LegacyOverrideBuiltIns] 확장 어트리뷰트interface에 나타나면, 해당 interface를 구현하는 레거시 플랫폼 객체에서 객체의 지원되는 프로퍼티명에 대응하는 모든 프로퍼티가 객체에 직접 존재하는 것처럼 보이게 됩니다. 이는 객체 자체나 프로토타입 체인에 어떤 프로퍼티가 있든 관계없이 항상 이름있는 프로퍼티가 shadow됨을 의미합니다. 기본 동작과는 다르며, 기본 동작에서는 이름있는 프로퍼티가 객체 자체나 프로토타입 체인에 동일한 이름의 프로퍼티가 없을 때에만 노출됩니다.

[LegacyOverrideBuiltIns] 확장 어트리뷰트는 인자를 가지지 않아야 하며, named property getter를 정의하지 않은 interface나 [Global] 확장 어트리뷰트가 선언된 interface에는 사용하면 안 됩니다. 이 확장 어트리뷰트가 partial interface 정의에 명시된 경우, 해당 partial interface 정의가 named property getter를 정의하는 부분이어야 합니다.

[LegacyOverrideBuiltIns] 확장 어트리뷰트가 partial interface 정의에 명시되면, 해당 partial interface가 아닌 interface 전체에 명시된 것으로 간주합니다.

구체적 요구사항은 § 3.9 레거시 플랫폼 객체§ 3.9.3 [[DefineOwnProperty]]에서 [LegacyOverrideBuiltIns] 사용 규칙을 참고하세요.

다음 IDL 프래그먼트는 하나는 named property getter가 있는 interface, 하나는 없는 interface를 정의합니다:

[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();

// named property getter를 호출합니다.
map1.abc;

// 객체의 "length" 프로퍼티를 가져오며, length attribute에 대응합니다.
map1.length;

// 객체의 프로토타입 체인에서 "toString" 프로퍼티를 가져옵니다.
map1.toString;

// StringMap2 인스턴스를 획득합니다. 역시 "abc", "length", "toString"이 지원됩니다.
var map2 = getStringMap2();

// named property getter를 호출합니다.
map2.abc;

// "length" 프로퍼티가 length attribute에 대응함에도 불구하고, 역시 named property getter를 호출합니다.
map2.length;

// "toString"이 map2의 프로토타입 체인에 있음에도 불구하고, 역시 named property getter를 호출합니다.
map2.toString;

3.4.8. [LegacyTreatNonObjectAsNull]

[LegacyTreatNonObjectAsNull] 확장 어트리뷰트콜백 함수(callback function)에 나타나면, 해당 타입이 nullable 콜백 함수attribute에 값을 할당할 때, 값이 객체가 아니면 null로 변환되고, 값이 호출 가능(callable)이 아니면, 호출 시 아무 동작도 하지 않는 콜백 함수 값으로 변환됨을 의미합니다.

자세한 요구사항은 § 3.2.20 Nullable 타입 — T?, § 3.2.19 Callback function 타입, § 3.12 Callback 함수 호출에서 [LegacyTreatNonObjectAsNull] 사용 규칙을 참고하세요.

다음 IDL 프래그먼트는 하나는 [LegacyTreatNonObjectAsNull]이 붙은 콜백 함수 타입 attribute, 하나는 확장 어트리뷰트가 없는 콜백 함수 타입 attribute를 가진 interface를 정의합니다:

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] 확장 어트리뷰트interface에 나타나고, 해당 interface가 이름있는 프로퍼티를 지원한다면, 인터페이스의 모든 이름있는 프로퍼티가 unenumerable(열거되지 않음)로 처리됩니다.

[LegacyUnenumerableNamedProperties] 확장 어트리뷰트는 인자를 가지지 않아야 하며, named property getter를 정의하지 않은 interface에는 사용하면 안 됩니다.

[LegacyUnenumerableNamedProperties] 확장 어트리뷰트가 interface에 명시되면, 그 파생 interface에도 적용되며, 파생 interface에는 별도로 명시할 수 없습니다.

구체적 요구사항은 § 3.9.1 [[GetOwnProperty]]에서 [LegacyUnenumerableNamedProperties] 사용 규칙을 참고하세요.

3.4.10. [LegacyUnforgeable]

[LegacyUnforgeable] 확장 어트리뷰트정규 attribute 또는 static이 아닌 operation에 나타나면, 해당 attribute나 operation이 JavaScript 프로퍼티로 반영될 때 동작을 변경할 수 없으며, 객체에서 해당 프로퍼티를 조회하면 항상 attribute의 프로퍼티 값을 반환하게 됩니다. 즉, 해당 프로퍼티는 non-configurable이며, 프로퍼티가 객체 자체의 own property로 존재하게 되고 프로토타입에는 존재하지 않습니다.

어떤 attribute나 operation이 인터페이스 A에서 [LegacyUnforgeable] 확장 어트리뷰트로 어노테이트되어 있으면, 해당 attribute나 operation은 A에서 unforgeable(위조 불가)이라고 합니다.

[LegacyUnforgeable] 확장 어트리뷰트는 인자를 가지지 않아야 합니다.

[LegacyUnforgeable] 확장 어트리뷰트는 정규 attribute 또는 static이 아닌 operation 외의 곳에 명시할 수 없습니다. 만약 operation에 명시된다면, 해당 인터페이스의 동일한 식별자(identifier)를 가진 모든 operation에도 명시되어야 합니다.

[LegacyUnforgeable] 확장 어트리뷰트는 namespace에 선언된 attribute에는 사용할 수 없습니다.

attribute 또는 operation X가 인터페이스 A에서 unforgeable이고, A가 다른 인터페이스 B상속 인터페이스라면, B에는 X와 동일한 식별자를 가진 정규 attribute나 static이 아닌 operation이 있으면 안 됩니다.

예를 들어, 아래와 같은 코드는 허용되지 않습니다:

[Exposed=Window]
interface A1 {
  [LegacyUnforgeable] readonly attribute DOMString x;
};
[Exposed=Window]
interface B1 : A1 {
  undefined x();  // 허용되지 않음; A1의 x에 의해 shadow됨.
};

[Exposed=Window]
interface B2 : A1 { };
B2 includes M1;
interface mixin M1 {
  undefined x();  // 허용되지 않음; B2의 x가 A1의 x에 의해 shadow됨.
};

구체적 요구사항은 § 3.7.6 속성, § 3.7.7 연산, § 3.8 인터페이스를 구현하는 플랫폼 객체, § 3.9 레거시 플랫폼 객체, § 3.9.3 [[DefineOwnProperty]]에서 [LegacyUnforgeable] 사용 규칙을 참고하세요.

다음 IDL 프래그먼트는 두 개의 attribute를 가진 interface를 정의하며, 그 중 하나는 [LegacyUnforgeable]로 지정되어 있습니다:

[Exposed=Window]
interface System {
  [LegacyUnforgeable] readonly attribute DOMString username;
  readonly attribute long long loginTime;
};

해당 interface를 지원하는 JavaScript 구현에서는 username attribute가 객체 자체의 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) { }

// 아래 defineProperty는 성공 (System.prototype.loginTime은 configurable)
var forgedLoginTime = 5;
Object.defineProperty(System.prototype, "loginTime", { value: forgedLoginTime });

system.loginTime;  // forgedLoginTime 반환

3.4.11. [LegacyWindowAlias]

[LegacyWindowAlias] 확장 어트리뷰트interface에 나타나면, Window interface가 해당 확장 어트리뷰트에 명시된 각 식별자에 대한 프로퍼티를 가지게 되며, 그 값은 해당 interface의 interface 객체가 됩니다.

[LegacyWindowAlias] 확장 어트리뷰트는 식별자 또는 식별자 리스트를 가져야 합니다. “=” 이후에 나오는 식별자들은 [LegacyWindowAlias]의 식별자(identifier)입니다.

[LegacyWindowAlias]의 식별자들은 이 interface 또는 다른 interface의 [LegacyWindowAlias]에서 사용된 것과 같으면 안 되며, 이 interface 또는 다른 interface의 [LegacyFactoryFunction]에서 사용된 식별자와 같아도 안 되고, interface 객체가 있는 interface의 식별자와 같아도 안 되며, 예약된 식별자도 사용할 수 없습니다.

[LegacyWindowAlias]와 [LegacyNoInterfaceObject] 확장 어트리뷰트는 같은 interface에 동시에 명시할 수 없습니다.

[LegacyWindowAlias]와 [LegacyNamespace] 확장 어트리뷰트도 같은 interface에 명시할 수 없습니다.

[LegacyWindowAlias] 확장 어트리뷰트는 Window interface노출 집합에 포함되지 않은 interface에는 명시할 수 없습니다.

한 interface에 하나 이상의 [LegacyWindowAlias] 확장 어트리뷰트를 명시할 수 없습니다.

레거시 window alias의 구현 방법은 § 3.7 인터페이스에서 자세히 설명합니다.

다음 IDL은 [LegacyWindowAlias] 확장 어트리뷰트를 사용하는 interface를 정의합니다.

[Exposed=Window,
 LegacyWindowAlias=WebKitCSSMatrix]
interface DOMMatrix : DOMMatrixReadOnly {
  // ...
};

이 interface를 지원하는 JavaScript 구현에서는 Window 객체에 동일한 값을 가지는 두 개의 프로퍼티가 노출됩니다. 하나는 보통대로 interface 객체를 노출하고, 하나는 레거시 이름으로 노출합니다.

WebKitCSSMatrix === DOMMatrix;     // true 반환

var m = new WebKitCSSMatrix();     // DOMMatrix를 구현하는 새 객체 생성
                                   // 

m.constructor === DOMMatrix;       // true 반환
m.constructor === WebKitCSSMatrix; // true 반환
{}.toString.call(m);               // '[object DOMMatrix]' 반환

3.5. 보안(Security)

아래 절들에 정의된 특정 알고리즘은 주어진 객체에 보안 검사를 수행한다고 정의되어 있습니다. 이 검사는 주어진 operation 호출이나 attribute 접근이 허용되어야 하는지를 결정하는 데 사용됩니다. 보안 검사는 다음 세 입력값을 사용합니다:

  1. operation 호출이나 attribute 접근이 수행되는 플랫폼 객체

  2. 해당 operation 또는 attribute의 식별자

  3. 함수 객체(function object)의 타입 — "method"(IDL operation에 해당하는 경우), "getter"/"setter"(IDL attribute의 getter/setter 함수에 해당하는 경우)

참고: HTML 표준에서는 보안 검사 수행 방법을 정의합니다. [HTML]

3.6. 오버로드 해석 알고리즘

함수 호출이 어떻게 해석되는지 정의하기 위해 오버로드 해석 알고리즘 을 정의한다. 입력은 효과적 오버로드 집합(effective overload set) S와 JavaScript 값의 리스트 args이다. 출력은 S의 엔트리 중 하나의 operation 또는 확장 어트리뷰트와, IDL 값 리스트 또는 특수값 “missing”의 쌍이다. 알고리즘은 다음과 같이 동작한다:

  1. maxargS의 엔트리 중 가장 긴 타입 리스트의 길이로 한다.

  2. nargs크기로 한다.

  3. argcount를 min(maxarg, n)로 초기화한다.

  4. S에서 타입 리스트의 길이가 argcount가 아닌 엔트리를 모두 제거한다.

  5. S가 비어 있다면 throw TypeError를 발생시킨다.

  6. d를 −1로 초기화한다.

  7. methodundefined로 초기화한다.

  8. S에 엔트리가 둘 이상 있으면, dS 엔트리의 구분 인자 인덱스로 설정한다.

  9. values를 빈 리스트로 초기화한다. 각 엔트리는 IDL 값 또는 특수값 “missing”이 된다.

  10. i를 0으로 초기화한다.

  11. i < d 동안:

    1. Vargs[i]로 한다.

    2. typeS의 엔트리 중 아무거나의 타입 리스트 i번째로 한다.

      참고: 이 시점에서 S의 모든 엔트리는 i번째 타입 및 옵셔널 값이 동일하다.

    3. optionalityS의 엔트리 중 아무거나의 옵션 값 리스트 i번째로 한다.

    4. optionality가 “optional”이고 Vundefined라면:

      1. i번째 인자가 기본값을 가진 경우, values에 그 기본값을 추가한다.

      2. 그렇지 않으면 values에 특수값 “missing”을 추가한다.

    5. 그 외의 경우 valuesV를 IDL 타입 type으로 변환한 결과를 추가한다.

    6. ii+1로 한다.

  12. i = d이면:

    1. Vargs[i]로 한다.

      참고: 이 인자가 어떤 오버로드가 선택되는지 결정하는 인자이다.

    2. Vundefined이고 S에 옵션 값 리스트 i번째가 “optional”인 엔트리가 있으면, S의 다른 엔트리를 모두 제거한다.

    3. 그 외의 경우 Vnull 또는 undefined이고, S에 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,

      그럼 S의 다른 엔트리를 모두 제거한다.

    4. 그 외의 경우 V플랫폼 객체이고, S에 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,

      • V구현interface 타입

      • object

      • 위 타입의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    5. 그 외의 경우 V가 Object이고 [[ArrayBufferData]] internal slot이 있고, S의 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,

      • ArrayBuffer

      • SharedArrayBuffer

      • object

      • 위 타입의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    6. 그 외의 경우 V가 Object이고 [[DataView]] internal slot이 있고, S의 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,

      • DataView

      • object

      • 위 타입의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    7. 그 외의 경우 V가 Object이고 [[TypedArrayName]] internal slot이 있고, S의 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,

      • TypedArray 타입이며 이름이 V의 [[TypedArrayName]] 값과 같음

      • object

      • 위 타입의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    8. 그 외의 경우 IsCallable(V)가 true이고, S에 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,

      • callback function 타입

      • object

      • 위 타입의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    9. 그 외의 경우 V가 Object이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,

      • async sequence 타입

      • 위 타입의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그리고 아래가 모두 true가 아니면,

      • V가 [[StringData]] internal slot을 가짐

      • S가 타입 리스트 i번째에 아래 중 하나의 타입을 가짐

        • string 타입

        • string 타입의 nullable 버전

        • 내부 타입이 string 타입인 어노테이트된 타입

        • flattened member types에 string 타입이 있는 union/nullable union/어노테이트된 union 타입

      그리고 다음 단계를 수행 후,

      1. methodGetMethod(V, %Symbol.asyncIterator%)로 한다.

      2. methodundefined라면, methodGetMethod(V, %Symbol.iterator%)로 한다.

      methodundefined가 아니면 S의 다른 엔트리를 모두 제거한다.

    10. 그 외의 경우 V가 Object이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,

      • sequence 타입

      • 위 타입의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그리고 다음 단계를 수행 후,

      1. methodGetMethod(V, %Symbol.iterator%)로 한다.

      methodundefined가 아니면 S의 다른 엔트리를 모두 제거한다.

    11. 그 외의 경우 V가 Object이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,

      그럼 S의 다른 엔트리를 모두 제거한다.

    12. 그 외의 경우 V가 Boolean이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,

      • boolean

      • boolean의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    13. 그 외의 경우 V가 Number이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,

      • numeric 타입

      • numeric 타입의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    14. 그 외의 경우 V가 BigInt이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,

      • bigint

      • bigint의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    15. 그 외의 경우 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,

      • string 타입

      • string 타입의 nullable 버전

      • 내부 타입이 string 타입인 어노테이트된 타입

      • flattened member types에 string 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    16. 그 외의 경우 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,

      • numeric 타입

      • numeric 타입의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    17. 그 외의 경우 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,

      • boolean

      • boolean 타입의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    18. 그 외의 경우 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,

      • bigint

      • bigint 타입의 nullable 버전

      • 내부 타입이 위 타입 중 하나인 어노테이트된 타입

      • flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입

      그럼 S의 다른 엔트리를 모두 제거한다.

    19. 그 외의 경우 S에 타입 리스트 i번째가 any이면 S의 다른 엔트리를 모두 제거한다.

    20. 그 외의 경우 throw TypeError를 발생시킨다.

  13. callableS의 단일 엔트리의 operation 또는 확장 어트리뷰트로 한다.

  14. i = d이고 methodundefined가 아니면,

    1. Vargs[i]로 한다.

    2. TS의 남은 엔트리의 타입 리스트 i번째로 한다.

    3. 단언: Tsequence 타입이다.

    4. valuesVmethod시퀀스 생성 결과를 추가한다.

    5. ii+1로 한다.

  15. i < argcount 동안:

    1. Vargs[i]로 한다.

    2. typeS의 남은 엔트리의 타입 리스트 i번째로 한다.

    3. optionalityS의 남은 엔트리의 옵션 값 리스트 i번째로 한다.

    4. optionality가 “optional”이고 Vundefined라면:

      1. i번째 인자가 기본값을 가진 경우, values에 그 기본값을 추가한다.

      2. 그렇지 않으면 values에 특수값 “missing”을 추가한다.

    5. 그 외의 경우 valuesV를 IDL 타입 type으로 변환한 결과를 추가한다.

    6. ii+1로 한다.

  16. icallable이 선언된 인자 수보다 작을 동안:

    1. callablei번째 인자가 기본값을 가진 경우, values에 그 기본값을 추가한다.

    2. 그 외, callablei번째 인자가 가변 인자가 아니면, values에 특수값 “missing”을 추가한다.

    3. ii+1로 한다.

  17. <callable, values> 쌍을 반환한다.

오버로드 해석 알고리즘은 어떤 오버로드된 operation, 생성자 등이 호출되는지 식별하는 것과, JavaScript 인자 값을 해당하는 IDL 값으로 변환하는 두 작업을 수행합니다. 비공식적으로 작동 방식은 다음과 같습니다.

먼저, 유효한 오버로드를 선택하는 과정은 함수에 전달된 JavaScript 인자 개수를 고려하여 진행됩니다:

올바른 인자 개수의 오버로드 집합을 얻은 후에는, JavaScript 값들을 왼쪽부터 오른쪽으로 변환합니다. 오버로드 제약의 성질 덕분에, 이 시점에 오버로드가 여러 개 남아 있다면, 인자 리스트 중 한 위치에서 최종적으로 어떤 오버로드를 선택할지 구분하게 됩니다. 이 위치가 구분 인자 인덱스(distinguishing argument index)입니다.

먼저 구분 인자 왼쪽의 인자들을 변환합니다.(구분 인자 인덱스 왼쪽에 위치한 인자는 모든 오버로드에서 같은 타입이어야 합니다.) 그 다음, 구분 인자 인덱스에 전달된 JavaScript 값의 타입을 검사하여 어떤 IDL 타입에 대응될 수 있는지 결정합니다. 이를 통해 최종적으로 호출할 오버로드를 선택합니다. 만약 전달된 값이 undefined이고 해당 위치가 optional 인자라면, 해당 오버로드를 선택합니다. 전달된 값 타입에 맞는 유효한 오버로드가 없다면 TypeError가 발생합니다. 일반적으로, 구분 인자 인덱스의 값 검사에는 부작용이 없으며, 오버로드 해석 알고리즘에서 발생하는 유일한 부작용은 JavaScript 값을 IDL 값으로 변환하는 과정에만 있습니다. (예외적으로, 어떤 오버로드가 구분 인자 인덱스에 async sequence 타입, sequence 타입, 또는 frozen array 타입을 가지는 경우가 있습니다. 이때는 %Symbol.asyncIterator% / %Symbol.iterator% 프로퍼티를 얻어 적합한 오버로드를 결정하며, 구분 인자에 대한 변환은 따로 수행한 뒤 다음 단계를 계속 진행합니다.)

이제 사용할 오버로드가 결정되었습니다. 남은 인자들은 구분 인자부터 오른쪽으로 변환하며, 앞서 초과되어 무시된 인자들은 계속 무시합니다.

optional 인자의 JavaScript 값을 해당 IDL 값으로 변환할 때, undefinedoptional 인자의 기본값이 있으면 그 값으로, 없으면 특수값 “missing”으로 변환됩니다.

마지막 가변 인자(variadic argument)에 해당하는 optional 인자에서는 undefined가 “missing”으로 특별하게 취급되지 않습니다. undefined 값은 가변 인자 타입으로, optional이 아닌 인자와 동일하게 변환됩니다.

3.7. 인터페이스

주어진 realm노출(exposed)된 모든 인터페이스(interface) 중, [LegacyNoInterfaceObject] 또는 [LegacyNamespace] 확장 어트리뷰트가 선언되지 않은 경우, 해당 인터페이스에 대응하는 프로퍼티가 realm글로벌 객체(global object)에 존재합니다. 프로퍼티 이름은 인터페이스의 식별자(identifier)이고, 값은 인터페이스 객체(interface object)입니다. 인터페이스 객체의 특성은 § 3.7.1 인터페이스 객체에서 설명합니다.

[LegacyWindowAlias] 확장 어트리뷰트가 노출된 인터페이스에 지정되어 있으면, [LegacyWindowAlias]의 각 식별자에 대해, Window 글로벌 객체에 대응하는 프로퍼티가 존재합니다. 프로퍼티 이름은 주어진 식별자이고, 값은 해당 인터페이스인터페이스 객체 참조입니다.

또한, 노출된 인터페이스에 [LegacyFactoryFunction] 확장 어트리뷰트가 있다면, 자바스크립트 글로벌 객체에 대응하는 프로퍼티가 존재합니다. 프로퍼티 이름은 [LegacyFactoryFunction]의 식별자이고, 값은 레거시 팩토리 함수(legacy factory function)이며, 해당 인터페이스를 구현하는 객체를 생성할 수 있도록 합니다. 레거시 팩토리 함수의 특성은 § 3.7.2 레거시 팩토리 함수에서 설명합니다.

이 절에서 정의된 몇몇 자바스크립트 메서드는 초기에 구현 객체 체크(implementation check)를 수행하여, 올바른 종류의 객체에서 호출되는지와 현재 컨텍스트에서 메서드 호출이 유효한지 확인합니다.

jsValueinterface 인터페이스에 대해, name 식별자와 type 타입으로 구현 객체 체크(implementation-check an object)하는 절차:

  1. objectToObject(jsValue)로 한다.

  2. object플랫폼 객체(platform object)라면, 보안 검사(perform a security check)를 다음과 같이 수행한다:

    • 플랫폼 객체 object

    • 식별자 name

    • 타입 type

  3. objectinterface구현(implement)하지 않으면 throw TypeError를 발생시킨다.

  4. object를 반환한다.

이 알고리즘은 아직 모든 곳에서 일관되게 사용되고 있지 않습니다.

3.7.1. 인터페이스 객체

주어진 인터페이스 객체인터페이스에 대한 내장 함수 객체(built-in function object)입니다. 해당 객체는 상수static 연산에 대응하는 프로퍼티를 가지며, 이에 대한 자세한 내용은 § 3.7.5 상수§ 3.7.7 연산에서 설명합니다.

해당 인터페이스생성자 연산(constructor operation)으로 선언된 경우, 인터페이스 객체생성자(constructor)로 호출하여 해당 인터페이스를 구현하는 객체를 생성할 수 있습니다. 인터페이스 객체를 함수로 호출하면 예외가 발생합니다.

인터페이스 객체인터페이스생성자 연산으로 선언되지 않은 경우, 함수로 호출하거나 생성자로 호출하면 예외가 발생합니다.

인터페이스 객체인터페이스에 대한 인터페이스 프로토타입 객체라는 연관 객체를 가집니다. 이 객체는 인터페이스에 정의된 정규 attribute정규 연산에 대응하는 프로퍼티를 가지며, § 3.7.3 인터페이스 프로토타입 객체에서 자세히 설명합니다.

참고: 인터페이스 객체함수 객체(function object)이므로, typeof 연산자를 적용하면 "function"을 반환합니다.

인터페이스는 생성자 재정의 단계(overridden constructor steps)를 가질 수 있으며, 인터페이스 객체가 호출되거나 생성될 때 동작을 변경할 수 있습니다. 기본적으로 인터페이스는 이러한 단계를 갖지 않습니다.

일반적으로 생성자는 생성자 연산 및 그 동작을 정의하여 설명합니다. 생성자 재정의 단계는 더 복잡한 상황에서만 사용해야 합니다. 이 기능을 사용하려는 편집자는 이슈를 등록하여 논의하는 것이 권장됩니다.

주어진 인터페이스 I에 대한 인터페이스 객체, id 식별자와 realm에서의 생성은 다음과 같이 생성(create an interface object)된다:

  1. stepsI생성자 재정의 단계로 하거나, 없으면 아래 단계를 따른다:

    1. I생성자 연산으로 선언되지 않았다면, throw TypeError를 발생시킨다.

    2. NewTargetundefined라면 throw TypeError를 발생시킨다.

    3. args를 전달된 인자들로 한다.

    4. nargs크기로 한다.

    5. id를 인터페이스 I의 식별자로 한다.

    6. 생성자에 대한 효과적 오버로드 집합을 식별자 id, 인터페이스 I, 인자 개수 n으로 계산하여 S로 한다.

    7. constructor, valuesSargs오버로드 해석 알고리즘에 전달한 결과로 한다.

    8. object내부적으로 새로운 객체 생성(I 구현, realm, NewTarget 사용) 결과로 한다.

    9. constructor생성자 단계objectthis로, values를 인자 값으로 하여 수행한다.

    10. Oobject자바스크립트 값으로 변환한 결과로 한다.

    11. 단언: OI구현하는 객체임.

    12. 단언: O.[[Realm]]은 realm임.

    13. O를 반환한다.

  2. constructorProtorealm.[[Intrinsics]].[[%Function.prototype%]]로 한다.

  3. I가 다른 인터페이스 P를 상속한다면, constructorProtoPrealm에서의 인터페이스 객체로 설정한다.

  4. FCreateBuiltinFunction(steps, « [[Unforgeables]] », realm, constructorProto)로 한다.

  5. unforgeablesOrdinaryObjectCreate(null)로 한다.

  6. 정규 unforgeable 연산 정의I, unforgeables, realm에 대해 수행한다.

  7. 정규 unforgeable attribute 정의I, unforgeables, realm에 대해 수행한다.

  8. F.[[Unforgeables]]에 unforgeables를 설정한다.

    참고: 이 객체는 사용자 코드에 노출되지 않으며, 인터페이스의 unforgeable 멤버가 모두 동일한 자바스크립트 함수 객체(attribute getter, setter, operation function)를 사용하도록 보장하기 위해 존재합니다.

  9. SetFunctionName(F, id)을 수행한다.

  10. length를 0으로 한다.

  11. I생성자 연산으로 선언되었다면,

    1. 식별자 id, I, 인자 개수 0으로 생성자에 대한 효과적 오버로드 집합을 계산하여 S로 한다.

    2. lengthS 엔트리 중 가장 짧은 인자 리스트의 길이로 한다.

  12. SetFunctionLength(F, length)을 수행한다.

  13. proto인터페이스 프로토타입 객체 생성(I, realm) 결과로 한다.

  14. DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: proto, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false})를 수행한다.

  15. 상수 정의I, F, realm에 대해 수행한다.

  16. static attribute 정의I, F, realm에 대해 수행한다.

  17. static 연산 정의I, F, realm에 대해 수행한다.

  18. F를 반환한다.

3.7.2. 레거시 팩토리 함수

하나 이상의 [LegacyFactoryFunction] 확장 어트리뷰트가 특정 식별자와 함께 존재하는 경우, 레거시 팩토리 함수가 생성됩니다. 이는 내장 함수 객체(built-in function object)이며, 해당 [LegacyFactoryFunction] 확장 어트리뷰트가 선언된 인터페이스를 구현하는 객체를 생성할 수 있습니다.

주어진 인터페이스 I식별자 id에 대한 레거시 팩토리 함수realm에서 다음과 같이 생성합니다:

  1. steps를 다음 단계로 한다:

    1. NewTargetundefined이면, throw TypeError를 발생시킨다.

    2. args를 전달된 인자로 한다.

    3. nargs크기로 한다.

    4. 레거시 팩토리 함수에 대해 식별자 id, 인터페이스 I, 인자 개수 n효과적 오버로드 집합을 계산하여 S로 한다.

    5. constructor, valuesS, args오버로드 해석 알고리즘에 전달한 결과로 한다.

    6. object내부적으로 새로운 객체 생성(I 구현, realm, NewTarget 사용) 결과로 한다.

    7. constructor생성자 단계objectthis로, values를 인자 값으로 하여 수행한다.

    8. Oobject자바스크립트 값으로 변환한 결과로 한다.

    9. 단언: OI구현하는 객체임.

    10. 단언: O.[[Realm]]은 realm임.

    11. O를 반환한다.

  2. FCreateBuiltinFunction(steps, « », realm)로 한다.

  3. SetFunctionName(F, id)을 수행한다.

  4. 레거시 팩토리 함수에 대해 식별자 id, 인터페이스 I, 인자 개수 0으로 효과적 오버로드 집합을 계산하여 S로 한다.

  5. lengthS 엔트리 중 가장 짧은 인자 리스트의 길이로 한다.

  6. SetFunctionLength(F, length)을 수행한다.

  7. proto인터페이스 프로토타입 객체(I, realm)로 한다.

  8. DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: proto, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false})를 수행한다.

  9. F를 반환한다.

3.7.3. 인터페이스 프로토타입 객체

모든 인터페이스에 대해 인터페이스 프로토타입 객체가 존재합니다. 해당 인터페이스가 [LegacyNoInterfaceObject] 확장 어트리뷰트로 선언되었는지 여부와 관계없이 정의됩니다.

주어진 인터페이스 프로토타입 객체인터페이스 interfacerealm realm에서 다음과 같이 생성됩니다:

  1. proto를 null로 한다.

  2. interface가 [Global] 확장 어트리뷰트로 선언되고, interface이름있는 프로퍼티(named properties)를 지원하면, proto이름있는 프로퍼티 객체 생성(interface, realm) 결과로 한다.

  3. 그 외에 interface가 다른 인터페이스를 상속하면, proto를 해당 상속 인터페이스realm에서의 인터페이스 프로토타입 객체로 한다.

  4. 그 외에 interfaceDOMException 인터페이스라면, protorealm.[[Intrinsics]].[[%Error.prototype%]]로 한다.

  5. 그 외에는 protorealm.[[Intrinsics]].[[%Object.prototype%]]로 한다.

  6. 단언: proto는 Object이다.

  7. interfaceProtoObj를 null로 한다.

  8. realm글로벌 프로토타입 체인이 mutable라면:

    1. interfaceProtoObjOrdinaryObjectCreate(proto)로 한다.

  9. 그 외에 interface가 [Global] 확장 어트리뷰트로 선언되었거나, interface가 [Global] 확장 어트리뷰트로 선언된 인터페이스의 상속 인터페이스 집합에 포함된다면:

    1. interfaceProtoObjMakeBasicObject(« [[Prototype]], [[Extensible]] »)로 한다.

    2. interfaceProtoObj.[[Prototype]]에 proto를 설정한다.

    3. interfaceProtoObj의 내부 메서드를 immutable prototype exotic objects에 맞게 ECMA-262 Immutable prototype exotic objects의 정의에 따라 설정한다.

  10. 그 외에는 interfaceProtoObjOrdinaryObjectCreate(proto)로 한다.

  11. interface에 [Unscopable] 확장 어트리뷰트로 선언된 멤버가 있으면:

    1. unscopableObjectOrdinaryObjectCreate(null)로 한다.

    2. 모든 노출된 [Unscopable] 확장 어트리뷰트로 선언된 멤버 member에 대해:

      1. idmember식별자로 한다.

      2. CreateDataPropertyOrThrow(unscopableObject, id, true)을 수행한다.

    3. desc를 PropertyDescriptor{[[Value]]: unscopableObject, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}로 한다.

    4. DefinePropertyOrThrow(interfaceProtoObj, %Symbol.unscopables%, desc)을 수행한다.

  12. interface가 [Global] 확장 어트리뷰트로 선언되지 않았다면:

    1. 정규 attribute 정의interface, interfaceProtoObj, realm에 대해 수행한다.

    2. 정규 연산 정의interface, interfaceProtoObj, realm에 대해 수행한다.

    3. 이터레이션 메서드 정의interface, interfaceProtoObj, realm에 대해 수행한다.

    4. 비동기 이터레이션 메서드 정의interface, interfaceProtoObj, realm에 대해 수행한다.

  13. 상수 정의interface, interfaceProtoObj, realm에 대해 수행한다.

  14. [LegacyNoInterfaceObject] 확장 어트리뷰트interface에 선언되지 않았다면:

    1. constructorrealm에서의 interface 인터페이스 객체로 한다.

    2. desc를 PropertyDescriptor{[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true, [[Value]]: constructor}로 한다.

    3. DefinePropertyOrThrow(interfaceProtoObj, "constructor", desc)을 수행한다.

  15. interfaceProtoObj를 반환한다.

또한 인터페이스 프로토타입 객체는 아래에서 선언적으로 프로퍼티를 추가로 갖습니다:

이러한 프로퍼티는 명령적으로 정의되어야 합니다.

[LegacyNoInterfaceObject] 확장 어트리뷰트로 정의된 인터페이스인터페이스 프로토타입 객체는 접근 가능합니다. 예를 들어, 아래 IDL에서:

[Exposed=Window,
 LegacyNoInterfaceObject]
interface Foo {
};

partial interface Window {
  attribute Foo foo;
};

인터페이스 객체(window.Foo)가 존재하지 않으므로 인터페이스 프로토타입 객체를 직접 접근할 수 없지만, Foo의 인스턴스에서 [[GetPrototypeOf]] 내부 메서드를 호출하여 인터페이스 프로토타입 객체를 노출할 수 있습니다. 즉, Object.getPrototypeOf(window.foo)를 통해 접근 가능합니다.

인터페이스 프로토타입 객체클래스 문자열(class string)인터페이스정규화된 이름(qualified name)입니다.

3.7.4. 이름있는 프로퍼티 객체

[Global] 확장 어트리뷰트로 선언되고 이름있는 프로퍼티(named properties)를 지원하는 모든 인터페이스에 대해, 해당 인터페이스에서 이름있는 프로퍼티가 노출되는 객체가 존재하며, 이를 이름있는 프로퍼티 객체(named properties object)라 한다.

주어진 인터페이스 interfacerealm realm에서 이름있는 프로퍼티 객체는 다음과 같이 생성(create a named properties object)된다:
  1. proto를 null로 한다.

  2. interface가 다른 인터페이스를 상속하면, proto를 해당 realm에서의 인터페이스 프로토타입 객체로 한다.

  3. 그렇지 않으면 protorealm.[[Intrinsics]].[[%Object.prototype%]]로 한다.

  4. objMakeBasicObject(« [[Prototype]], [[Extensible]] »)로 한다.

  5. obj.[[GetOwnProperty]]를 § 3.7.4.1 [[GetOwnProperty]]에 명시된 대로 설정한다.

  6. obj.[[DefineOwnProperty]]를 § 3.7.4.2 [[DefineOwnProperty]]에 명시된 대로 설정한다.

  7. obj.[[Delete]]를 § 3.7.4.3 [[Delete]]에 명시된 대로 설정한다.

  8. obj.[[SetPrototypeOf]]를 § 3.7.4.4 [[SetPrototypeOf]]에 명시된 대로 설정한다.

  9. obj.[[PreventExtensions]]를 § 3.7.4.5 [[PreventExtensions]]에 명시된 대로 설정한다.

  10. obj.[[Prototype]]에 proto를 설정한다.

  11. obj를 반환한다.

참고: 이름있는 프로퍼티 객체의 [[OwnPropertyKeys]] 내부 메서드는 OrdinaryOwnPropertyKeys를 계속 사용합니다. 이는 레거시 플랫폼 객체와 다릅니다. 이름있는 프로퍼티는 “실제” own property가 아니므로 이 내부 메서드에서는 반환되지 않습니다.

이름있는 프로퍼티 객체클래스 문자열(class string)인터페이스식별자와 문자열 "Properties"를 연결한 값입니다.

3.7.4.1. [[GetOwnProperty]]

이름있는 프로퍼티 객체 O의 [[GetOwnProperty]] 내부 메서드가 프로퍼티 키 P로 호출되면, 다음 단계가 수행된다:

  1. AO인터페이스로 한다.

  2. objectO.[[Realm]]의 글로벌 객체로 한다.

  3. 단언: objectA구현한다.

  4. 프로퍼티 이름 P와 객체 object이름있는 프로퍼티 가시성 알고리즘을 실행한 결과가 true라면:

    1. operation을 이름있는 프로퍼티 getter를 선언한 연산으로 한다.

    2. value를 초기화되지 않은 변수로 한다.

    3. operation식별자 없이 정의되었다면, value를 인터페이스 설명에 명시된 단계를 수행하여 이름있는 프로퍼티의 값 결정(P를 이름으로 사용) 결과로 한다.

    4. 그 외에는 operation이 식별자로 정의되었으므로, valueoperation 설명에 명시된 단계를 수행하여 P를 유일한 인자 값으로 사용한 결과로 한다.

    5. desc를 필드가 없는 새 프로퍼티 디스크립터(Property Descriptor)로 한다.

    6. desc.[[Value]]를 value자바스크립트 값으로 변환한 결과로 설정한다.

    7. A가 [LegacyUnenumerableNamedProperties] 확장 어트리뷰트가 선언된 인터페이스를 구현하면, desc.[[Enumerable]]를 false로, 그렇지 않으면 true로 한다.

    8. desc.[[Writable]]를 true, desc.[[Configurable]]를 true로 한다.

    9. desc를 반환한다.

  5. OrdinaryGetOwnProperty(O, P)를 반환한다.

3.7.4.2. [[DefineOwnProperty]]

이름있는 프로퍼티 객체의 [[DefineOwnProperty]] 내부 메서드가 호출될 때, 다음 단계가 수행됩니다:

  1. false를 반환한다.

3.7.4.3. [[Delete]]

이름있는 프로퍼티 객체의 [[Delete]] 내부 메서드가 호출될 때, 다음 단계가 수행됩니다:

  1. false를 반환한다.

3.7.4.4. [[SetPrototypeOf]]

이름있는 프로퍼티 객체 O의 [[SetPrototypeOf]] 내부 메서드가 JavaScript 값 V로 호출될 때, 다음 단계가 수행된다:

  1. 만약 O연관 realm글로벌 프로토타입 체인이 mutable라면, OrdinarySetPrototypeOf(O, V)를 반환한다.

  2. SetImmutablePrototype(O, V)를 반환한다.

3.7.4.5. [[PreventExtensions]]

이름있는 프로퍼티 객체의 [[PreventExtensions]] 내부 메서드가 호출될 때, 다음 단계가 수행된다:

  1. false를 반환한다.

참고: 이렇게 하면 [[PreventExtensions]]가 실패하면서 이름있는 프로퍼티 객체가 확장 가능(extensible)하게 유지됩니다.

3.7.5. 상수

상수인터페이스 객체, 레거시 콜백 인터페이스 객체, 인터페이스 프로토타입 객체 및 인터페이스를 구현하는 단일 객체에 노출됩니다. 인터페이스가 [Global] 확장 속성으로 선언된 경우에 해당합니다.

상수를 정의한다: 인터페이스, 콜백 인터페이스 또는 네임스페이스 definitiontarget에 대해, realm realm이 주어졌을 때, 아래 단계를 수행합니다:
  1. 각각의 상수 const에 대해, 멤버definition에 속한 경우:

    1. constrealm에서 노출되지 않았다면, 계속합니다.

    2. valueIDL 값을 자바스크립트 값으로 변환한 결과로 설정합니다.

    3. desc를 PropertyDescriptor{[[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false, [[Value]]: value}로 설정합니다.

    4. idconst식별자로 설정합니다.

    5. ! DefinePropertyOrThrow(target, id, desc)를 수행합니다.

3.7.6. 속성

정적 속성인터페이스 객체에 노출됩니다. 일반 속성인터페이스 프로토타입 객체에 노출되며, 해당 속성이 위조 불가이거나 인터페이스가 [Global] 확장 속성으로 선언된 경우, 이 경우 해당 인터페이스를 구현하는 모든 객체에 노출됩니다.

일반 속성 정의하기 인터페이스 또는 네임스페이스 definitiontargetrealm realm과 함께 정의하려면 다음 단계를 수행하세요:
  1. attributes목록으로 설정합니다. 이 목록은 일반 속성definition멤버인 것들입니다.

  2. 제거합니다. attributes에서 속성위조 불가인 것을 모두 제거합니다.

  3. 속성 정의하기: attributesdefinition의 속성으로 targetrealm을 사용해 정의합니다.

정적 속성 정의하기 인터페이스 또는 네임스페이스 definitiontarget에, realm realm과 함께 정의하려면 다음 단계를 수행하세요:
  1. attributes목록으로 설정합니다. 이 목록은 정적 속성멤버인 것들입니다.

  2. 속성 정의하기: attributesdefinition의 속성으로 targetrealm을 사용해 정의합니다.

위조 불가 일반 속성 정의하기 인터페이스 또는 네임스페이스 definitiontarget에, realm realm과 함께 정의하려면 다음 단계를 수행하세요:
  1. attributes목록으로 설정합니다. 이 목록은 위조 불가 일반 속성멤버인 것들입니다.

  2. 속성 정의하기: attributesdefinition의 속성으로 targetrealm을 사용해 정의합니다.

속성 정의하기 attributes인터페이스 또는 네임스페이스 definition의 속성으로 targetrealm realm을 사용해 정의하려면 다음 단계를 수행하세요:
  1. 각각속성 attr에 대해 attributes에서:

    1. 만약 attrrealm에서 노출되지 않았다면, continue합니다.

    2. getter속성 getter를 생성해서 attr, definition, realm을 인자로 하여 설정합니다.

    3. setter속성 setter를 생성해서 attr, definition, realm을 인자로 하여 설정합니다.

      참고: 속성 setter 생성 알고리즘은 attr읽기 전용일 경우 undefined를 반환합니다.

    4. configurableattr위조 불가이면 false로, 그렇지 않으면 true로 설정합니다.

    5. desc를 PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}로 설정합니다.

    6. idattr식별자로 설정합니다.

    7. ! DefinePropertyOrThrow(target, id, desc)를 수행합니다.

    8. 만약 attr의 타입이 observable array type이고 타입 인자가 T라면, targetbacking observable array exotic objectobservable array exotic object 생성하기의 결과로 설정합니다. 인자는 realm, T, attr인덱스 값 설정 알고리즘, 인덱스 값 삭제 알고리즘입니다.

속성 getter는 다음과 같이 생성됩니다. 속성 attribute, 네임스페이스 또는 인터페이스 target, realm realm을 인자로 합니다:

  1. steps를 다음 단계 시리즈로 설정합니다:

    1. 다음 단계를 시도합니다:

      1. idlObject를 null로 설정합니다.

      2. 만약 target인터페이스이고, attribute일반 속성이라면:

        1. jsValuethis 값으로 설정합니다. 값이 null 또는 undefined가 아니면 그대로 사용하고, 그렇지 않으면 realm전역 객체를 사용합니다. (전역 객체가 target을 구현하지 않거나 [LegacyLenientThis] 가 지정되지 않았다면 이후 단계에서 TypeError 를 발생시킵니다.)

        2. 만약 jsValue플랫폼 객체라면, 보안 검사 수행jsValue, attribute식별자, "getter"를 인자로 하여 실행합니다.

        3. 만약 jsValuetarget을 구현하지 않으면:

          1. 만약 attribute가 [LegacyLenientThis] 확장 속성으로 지정되었다면, undefined를 반환합니다.

          2. 그렇지 않으면 throw를 사용하여 TypeError를 발생시킵니다.

        4. 만약 attribute의 타입이 observable array type이라면, jsValuebacking observable array exotic objectattribute에 대해 반환합니다.

        5. idlObjectjsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.

      3. Rgetter 단계attribute에 대해 idlObjectthis로 사용하여 실행한 결과로 설정합니다.

      4. IDL을 자바스크립트 값으로 변환하여 Rattribute에 선언된 타입의 자바스크립트 값으로 반환합니다.

    그리고 예외 E가 발생한 경우:

    1. 만약 attribute의 타입이 promise type이라면 ! Call(%Promise.reject%, %Promise%, «E»)를 반환합니다.

    2. 그 외의 경우 단계 종료 후 예외를 전파합니다.

  2. FCreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.

  3. name을 문자열 "get "를 attribute식별자 앞에 붙여서 설정합니다.

  4. SetFunctionName(F, name)를 수행합니다.

  5. SetFunctionLength(F, 0)를 수행합니다.

  6. F를 반환합니다.

속성 setter 는 다음과 같이 생성됩니다. 속성 attribute, 네임스페이스 또는 인터페이스 target, 그리고 realm realm이 주어졌을 때:

  1. 만약 target네임스페이스라면:

    1. 단언: attribute읽기 전용이다.

    2. undefined를 반환한다.

  2. 만약 attribute읽기 전용이고 [LegacyLenientSetter], [PutForwards] 또는 [Replaceable] 확장 속성이 없으면, undefined를 반환한다; 속성 setter 함수는 없다.

  3. 단언: attribute의 타입은 프라미스 타입이 아니다.

  4. steps를 다음 단계 시리즈로 설정한다:

    1. Vundefined로 설정한다.

    2. 인자가 전달된 경우, V를 전달된 첫 번째 인자의 값으로 설정한다.

    3. idattribute식별자로 설정한다.

    4. idlObject를 null로 설정한다.

    5. 만약 attribute일반 속성이라면:

      1. jsValuethis 값으로 설정하며, null이나 undefined가 아니면 그대로 사용하고, 그렇지 않으면 realm전역 객체를 사용한다. (전역 객체가 target을 구현하지 않거나 [LegacyLenientThis] 가 지정되지 않았다면 이후 단계에서 TypeError 를 발생시킨다.)

      2. jsValue플랫폼 객체라면, 보안 검사 수행jsValue, id, "setter"를 인자로 하여 실행한다.

      3. validThisjsValuetarget을 구현하면 true, 그렇지 않으면 false로 설정한다.

      4. 만약 validThis가 false이고 attribute가 [LegacyLenientThis] 확장 속성으로 지정되지 않았다면, throw를 사용하여 TypeError를 발생시킨다.

      5. 만약 attribute가 [Replaceable] 확장 속성으로 선언되었다면:

        1. ? CreateDataPropertyOrThrow(jsValue, id, V)를 수행한다.

        2. undefined를 반환한다.

      6. 만약 validThis가 false이면 undefined를 반환한다.

      7. 만약 attribute가 [LegacyLenientSetter] 확장 속성으로 선언되었다면 undefined를 반환한다.

      8. 만약 attribute가 [PutForwards] 확장 속성으로 선언되었다면:

        1. Q? Get(jsValue, id)의 결과로 설정한다.

        2. 만약 Q객체가 아니면, throw를 사용하여 TypeError를 발생시킨다.

        3. forwardId를 [PutForwards] 확장 속성의 identifier 인자로 설정한다.

        4. ? Set(Q, forwardId, V, false)를 수행한다.

        5. undefined를 반환한다.

      9. idlObjectjsValue를 참조하는 IDL 인터페이스 타입 값으로 설정한다.

      10. 만약 attribute의 타입이 observable array type이고 타입 인자가 T라면:

        1. newValuesECMAScript 값을 IDL 값으로 변환하여 Vsequence<T> 타입의 IDL 값으로 설정한다.

        2. oaidlObjectattributebacking observable array exotic object로 설정한다.

        3. 길이 설정oa.[[ProxyHandler]]에 대해 0으로 한다.

        4. i를 0으로 설정한다.

        5. i < newValues크기일 동안:

          1. oa.[[ProxyHandler]].[[SetAlgorithm]] 알고리즘을 newValues[i]와 i를 인자로 하여 실행한다.

          2. 추가 newValues[i]를 oa.[[ProxyHandler]].[[BackingList]]에 추가한다.

        6. undefined를 반환한다.

    6. idlValue를 다음과 같이 결정한다:

      attribute의 타입이 열거형일 경우
      1. S? ToString(V)의 결과로 설정한다.

      2. 만약 S열거형 값에 없으면 undefined를 반환한다.

      3. 그렇지 않으면 idlValueS와 동일한 열거형 값으로 설정한다.

      그 외의 경우
      idlValueECMAScript 값을 IDL 값으로 변환하여 Vattribute 타입의 IDL 값으로 설정한다.
    7. setter 단계attribute에 대해, idlObjectthis로, idlValue주어진 값으로 사용하여 수행한다.

    8. undefined를 반환한다.

  5. FCreateBuiltinFunction(steps, « », realm)의 결과로 설정한다.

  6. name을 문자열 "set "를 id 앞에 붙여서 설정한다.

  7. SetFunctionName(F, name)를 수행한다.

  8. SetFunctionLength(F, 1)를 수행한다.

  9. F를 반환한다.

참고: IDL 속성에는 단일 프로퍼티만 있지만, 접근자 프로퍼티 getter와 setter는 해당 IDL 속성에 대응하는 프로퍼티가 접근된 객체의 this 값을 전달받으므로 인스턴스별 데이터를 노출할 수 있습니다.

참고: 읽기 전용 속성 에 대응하는 프로퍼티에 값을 할당하려고 하면, 스크립트가 엄격 모드(strict mode)인지에 따라 동작이 달라집니다. 엄격 모드에서는 해당 할당이 TypeError 를 발생시키고, 엄격 모드가 아니면 할당 시도가 무시됩니다.

3.7.7. 연산(Operations)

인터페이스에서 정의된, 노출된 연산의 고유한 식별자마다 해당하는 프로퍼티가 존재합니다. 정적 연산인터페이스 객체에 노출됩니다. 일반 연산인터페이스 프로토타입 객체에 노출됩니다. 단, 연산이 위조 불가이거나, 인터페이스가 [Global] 확장 속성으로 선언된 경우에는, 해당 인터페이스를 구현하는 모든 객체에 노출됩니다.

일반 연산 정의하기 인터페이스 또는 네임스페이스 definitiontarget에, realm realm과 함께 정의하려면 다음 단계를 수행하세요:
  1. operations목록으로 설정합니다. 이 목록은 일반 연산멤버인 것들입니다.

  2. 제거합니다. operations에서 연산위조 불가인 것들을 모두 제거합니다.

  3. 연산 정의하기: operationsdefinition의 연산으로 targetrealm을 사용해 정의합니다.

정적 연산 정의하기 인터페이스 또는 네임스페이스 definitiontarget에, realm realm과 함께 정의하려면 다음 단계를 수행하세요:
  1. operations목록으로 설정합니다. 이 목록은 정적 연산멤버인 것들입니다.

  2. 연산 정의하기: operationsdefinition의 연산으로 targetrealm을 사용해 정의합니다.

위조 불가 일반 연산 정의하기 인터페이스 또는 네임스페이스 definitiontarget에, realm realm과 함께 정의하려면 다음 단계를 수행하세요:
  1. operations목록으로 설정합니다. 이 목록은 위조 불가 일반 연산멤버인 것들입니다.

  2. 연산 정의하기: operationsdefinition의 연산으로 targetrealm을 사용해 정의합니다.

연산 정의하기 operations인터페이스 또는 네임스페이스 definition의 연산으로 targetrealm realm을 사용해 정의하려면 다음 단계를 수행하세요:
  1. 각각연산 op에 대해 operations에서:

    1. 만약 oprealm에서 노출되지 않았다면, continue합니다.

    2. method연산 함수 생성하기의 결과로 op, definition, realm을 인자로 하여 설정합니다.

    3. modifiableop위조 불가이면 false로, 그렇지 않으면 true로 설정합니다.

    4. desc를 PropertyDescriptor{[[Value]]: method, [[Writable]]: modifiable, [[Enumerable]]: true, [[Configurable]]: modifiable}로 설정합니다.

    5. idop식별자로 설정합니다.

    6. ! DefinePropertyOrThrow(target, id, desc)를 수행합니다.

연산 함수 생성하기 연산 op, 네임스페이스 또는 인터페이스 target, realm realm이 주어졌을 때:
  1. idop식별자로 설정합니다.

  2. steps를 다음 단계 시리즈로 설정하며, 함수 인자값 args가 주어집니다:

    1. 다음 단계를 시도합니다:

      1. idlObject를 null로 설정합니다.

      2. 만약 target인터페이스이고, op정적 연산이 아니라면:

        1. jsValuethis 값으로 설정하며, null 또는 undefined가 아니면 그대로 사용하고, 그렇지 않으면 realm전역 객체를 사용합니다. (전역 객체가 target을 구현하지 않거나 [LegacyLenientThis] 가 지정되지 않았다면 이후 단계에서 TypeError 를 발생시킵니다.)

        2. 만약 jsValue플랫폼 객체라면, 보안 검사 수행jsValue, id, "method"를 인자로 하여 실행합니다.

        3. 만약 jsValue가 인터페이스 target구현하지 않으면, throw를 사용하여 TypeError를 발생시킵니다.

        4. idlObjectjsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.

      3. nargs크기로 설정합니다.

      4. 유효 오버로드 집합 계산하기: op이 일반 연산이면 일반 연산에 대해, 정적 연산이면 정적 연산에 대해 식별자 idtarget, 인자 개수 n를 사용해 계산하여 S로 설정합니다.

      5. <operation, values>를 Sargs오버로드 해결 알고리즘에 전달하여 얻은 결과로 설정합니다.

      6. Rnull로 설정합니다.

      7. 만약 operation이 [Default] 확장 속성으로 선언되었다면:

        1. 단언: operation기본 메서드 단계를 가진다.

        2. R기본 메서드 단계operation에 대해, idlObjectthis로, values를 인자값으로 사용하여 실행한 결과로 설정합니다.

      8. 그렇지 않으면 R메서드 단계operation에 대해, idlObjectthis로, values를 인자값으로 사용하여 실행한 결과로 설정합니다.

      9. R자바스크립트 값으로 변환하여 반환합니다.

        Rop이 반환하도록 선언된 타입의 IDL 값이라고 가정합니다. [whatwg/webidl Issue #674]

    그리고 예외 E가 발생한 경우:

    1. 만약 op반환 타입프라미스 타입이라면 ! Call(%Promise.reject%, %Promise%, «E»)를 반환합니다.

    2. 그 외의 경우 단계 종료 후 예외를 전파합니다.

  3. FCreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.

  4. SetFunctionName(F, id)를 수행합니다.

  5. 유효 오버로드 집합 계산하기: op이 일반 연산이면 일반 연산에 대해, 정적 연산이면 정적 연산에 대해 식별자 idtarget, 인자 개수 0을 사용해 계산하여 S로 설정합니다.

  6. lengthS의 엔트리 중 가장 짧은 인자 리스트의 길이로 설정합니다.

  7. SetFunctionLength(F, length)를 수행합니다.

  8. F를 반환합니다.

3.7.7.1. 기본 연산

일반 연산기본 메서드 단계를 갖는다 는 그 식별자가 아래 표의 첫 번째 열에 등장하는 경우를 말합니다. 이 경우, 기본 메서드 단계는 표 두 번째 열에서 연결된 알고리즘에 따라 결정되고, 연산은 표 세 번째 열에 명시된 반환 타입을 가져야 합니다.

식별자 기본 메서드 단계 반환 타입
"toJSON" 기본 toJSON 단계 object

일반 연산기본 메서드 단계를 갖지 않는다면, [Default] 확장 속성으로 선언하면 안 됩니다.

3.7.7.1.1. 기본 toJSON 연산

기본 toJSON 단계인터페이스 I에 대해 다음과 같이 동작합니다:

  1. map을 새로운 순서가 있는 맵으로 설정합니다.

  2. stack상속 스택 생성 알고리즘을 인터페이스 I에 대해 실행한 결과로 설정합니다.

  3. 상속 스택의 속성 값 수집 알고리즘을 this, stack, map과 함께 실행합니다.

  4. resultOrdinaryObjectCreate(%Object.prototype%)의 결과로 설정합니다.

  5. keyvalue에 대해 map에서:

    1. kkey 자바스크립트 값으로 변환한 결과로 설정합니다.

    2. vvalue 자바스크립트 값으로 변환한 결과로 설정합니다.

    3. ! CreateDataPropertyOrThrow(result, k, v)를 실행합니다.

  6. result를 반환합니다.

상속 스택의 속성 값 수집 알고리즘은, 플랫폼 객체 object, 스택 stack, 순서가 있는 맵 map이 주어졌을 때 다음과 같이 동작합니다:

  1. Istack에서 pop한 결과로 설정합니다.

  2. 속성 값 수집 알고리즘을 object, I, map과 함께 실행합니다.

  3. 만약 stack비어있지 않다면, 상속 스택의 속성 값 수집 알고리즘을 object, stack, map과 함께 다시 실행합니다.

속성 값 수집 알고리즘은 플랫폼 객체 object, 인터페이스 I, 순서가 있는 맵 map이 주어졌을 때 다음과 같이 동작합니다:

  1. 만약 I에 [Default] 확장 속성이 붙은 toJSON 연산이 선언되어 있다면, 노출된 일반 속성 attr에 대해, 인터페이스 멤버I인 것들을 순서대로:

    1. idattr식별자로 설정합니다.

    2. valuegetter 단계attr에 대해 objectthis로 사용해 실행한 결과로 설정합니다.

    3. 만약 valueJSON 타입이라면, map에 설정하여 map[id]에 value를 지정합니다.

상속 스택 생성 알고리즘은 인터페이스 I에 대해 다음과 같이 동작합니다:

  1. stack을 새로운 스택으로 설정합니다.

  2. stack에 push하여 I를 넣습니다.

  3. while I상속하는 인터페이스가 있을 때,

    1. I를 그 인터페이스로 설정합니다.

    2. stack에 push하여 I를 넣습니다.

  4. stack을 반환합니다.

toJSON 연산에 [Default] 확장 속성이 선언된 인터페이스일반 속성만 포함되며, 상속된 인터페이스에 해당 연산이 선언되었더라도 포함되지 않습니다. 예를 들어, 아래 IDL fragment를 보세요:

[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 fragment를 보세요:

[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. 문자열화자(Stringifiers)

인터페이스노출된 문자열화자(stringifier)가 있다면, 다음 특성을 가진 프로퍼티가 반드시 존재해야 합니다:

3.7.9. 이터러블 선언

이터레이션 메서드 정의하기 인터페이스 definitiontarget에, realm realm과 함께 정의하려면 다음 단계를 수행하세요:
  1. 만약 definition인덱스 프로퍼티 getter가 있다면:

    1. DefineMethodProperty(target, %Symbol.iterator%, %Array.prototype.values%, false)를 수행합니다.

    2. 만약 definition값 이터레이터가 있다면:

      1. ! CreateDataPropertyOrThrow(target, "entries", %Array.prototype.entries%)를 수행합니다.

      2. ! CreateDataPropertyOrThrow(target, "keys", %Array.prototype.keys%)를 수행합니다.

      3. ! CreateDataPropertyOrThrow(target, "values", %Array.prototype.values%)를 수행합니다.

      4. ! CreateDataPropertyOrThrow(target, "forEach", %Array.prototype.forEach%)를 수행합니다.

  2. 그렇지 않고 definition쌍 이터레이터가 있다면:

    1. %Symbol.iterator%entries 메서드를 정의합니다:

      1. steps를 다음 단계 시리즈로 설정합니다:

        1. jsValue? ToObject(this 값)으로 설정합니다.

        2. jsValue플랫폼 객체이면 보안 검사 수행jsValue, "%Symbol.iterator%", "method"와 함께 실행합니다.

        3. jsValuedefinition구현하지 않으면 throw를 사용해 TypeError를 발생시킵니다.

        4. definition에 대해 jsValuetarget으로, "key+value"를 kind로, index를 0으로 한 새 기본 이터레이터 객체를 반환합니다.

      2. FCreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.

      3. SetFunctionName(F, "entries")를 수행합니다.

      4. SetFunctionLength(F, 0)을 수행합니다.

      5. DefineMethodProperty(target, %Symbol.iterator%, F, false)를 수행합니다.

      6. ! CreateDataPropertyOrThrow(target, "entries", F)를 수행합니다.

    2. keys 메서드를 정의합니다:

      1. steps를 다음 단계 시리즈로 설정합니다:

        1. jsValue? ToObject(this 값)으로 설정합니다.

        2. jsValue플랫폼 객체이면 보안 검사 수행jsValue, "keys", "method"와 함께 실행합니다.

        3. jsValuedefinition구현하지 않으면 throw를 사용해 TypeError를 발생시킵니다.

        4. definition에 대해 jsValuetarget으로, "key"를 kind로, index를 0으로 한 새 기본 이터레이터 객체를 반환합니다.

      2. FCreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.

      3. SetFunctionName(F, "keys")를 수행합니다.

      4. SetFunctionLength(F, 0)을 수행합니다.

      5. ! CreateDataPropertyOrThrow(target, "keys", F)를 수행합니다.

    3. values 메서드를 정의합니다:

      1. steps를 다음 단계 시리즈로 설정합니다:

        1. jsValue? ToObject(this 값)으로 설정합니다.

        2. jsValue플랫폼 객체이면 보안 검사 수행jsValue, "values", "method"와 함께 실행합니다.

        3. jsValuedefinition구현하지 않으면 throw를 사용해 TypeError를 발생시킵니다.

        4. definition에 대해 jsValuetarget으로, "value"를 kind로, index를 0으로 한 새 기본 이터레이터 객체를 반환합니다.

      2. FCreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.

      3. SetFunctionName(F, "values")를 수행합니다.

      4. SetFunctionLength(F, 0)을 수행합니다.

      5. ! CreateDataPropertyOrThrow(target, "values", F)를 수행합니다.

    4. forEach 메서드를 정의합니다:

      1. steps를 다음 단계 시리즈로 설정합니다. 함수 인자값 callbackthisArg이 주어집니다:

        1. jsValue? ToObject(this 값)으로 설정합니다.

        2. jsValue플랫폼 객체이면 보안 검사 수행jsValue, "forEach", "method"와 함께 실행합니다.

        3. jsValuedefinition구현하지 않으면 throw를 사용해 TypeError를 발생시킵니다.

        4. idlCallbackcallback IDL 값으로 변환하여 Function 타입으로 설정합니다.

        5. idlObjectjsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.

        6. pairsidlObject이터레이션 할 값 쌍 목록으로 설정합니다.

        7. i를 0으로 설정합니다.

        8. i < pairs크기일 동안:

          1. pairpairs[i]로 설정합니다.

          2. 콜백 함수 호출idlCallback에 대해 « pairvalue, pairkey, idlObject » 와 thisArg콜백 this 값으로 사용하여 실행합니다.

          3. pairsidlObject의 현재 이터레이션 할 값 쌍 목록으로 다시 설정합니다. (변경될 수 있음)

          4. ii + 1로 설정합니다.

      2. FCreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.

      3. SetFunctionName(F, "forEach")를 수행합니다.

      4. SetFunctionLength(F, 1)을 수행합니다.

      5. ! CreateDataPropertyOrThrow(target, "forEach", F)를 수행합니다.

3.7.9.1. 기본 이터레이터 객체

기본 이터레이터 객체는 지정된 인터페이스, target, 이터레이션 kind에 대해 [[Prototype]] 내부 슬롯이 해당 인터페이스이터레이터 프로토타입 객체인 객체입니다.

기본 이터레이터 객체는 세 가지 내부 값을 가집니다:

참고: 기본 이터레이터 객체는 쌍 이터레이터에만 사용됩니다. 값 이터레이터는 현재 객체의 지원하는 인덱스 프로퍼티만 이터레이션하도록 제한되어 있으므로, 표준 JavaScript Array 이터레이터 객체를 사용합니다.

참고: 기본 이터레이터 객체클래스 문자열을 가지지 않습니다; Object.prototype.toString()인터페이스기본 이터레이터 객체에 호출하면, 해당 인터페이스이터레이터 프로토타입 객체의 클래스 문자열이 사용됩니다.

3.7.9.2. 이터레이터 프로토타입 객체

이터레이터 프로토타입 객체는 지정된 인터페이스에 대해 쌍 이터레이터가 있는 모든 인터페이스에 존재합니다. 해당 인터페이스의 기본 이터레이터 객체의 프로토타입 역할을 합니다.

[[Prototype]] 내부 슬롯이터레이터 프로토타입 객체에서 %Iterator.prototype%이어야 합니다.

이터레이터 결과값 쌍 pair와 kind kind에 대해 다음 단계로 결정합니다:
  1. kind 값에 따라 result를 다음과 같이 결정합니다:

    "key"
    1. idlKeypairkey로 설정합니다.

    2. keyIDL to JS 값 변환하여 idlKey를 자바스크립트 값으로 변환한 결과로 설정합니다.

    3. resultkey입니다.

    "value"
    1. idlValuepairvalue로 설정합니다.

    2. valueIDL to JS 값 변환하여 idlValue를 자바스크립트 값으로 변환한 결과로 설정합니다.

    3. resultvalue입니다.

    "key+value"
    1. idlKeypairkey로 설정합니다.

    2. idlValuepairvalue로 설정합니다.

    3. keyIDL to JS 값 변환하여 idlKey를 자바스크립트 값으로 변환한 결과로 설정합니다.

    4. valueIDL to JS 값 변환하여 idlValue를 자바스크립트 값으로 변환한 결과로 설정합니다.

    5. array! ArrayCreate(2)로 설정합니다.

    6. ! CreateDataPropertyOrThrow(array, "0", key)를 수행합니다.

    7. ! CreateDataPropertyOrThrow(array, "1", value)를 수행합니다.

    8. resultarray입니다.

  2. CreateIteratorResultObject(result, false)를 반환합니다.

이터레이터 프로토타입 객체next 데이터 프로퍼티를 가져야 하며 속성은 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }이고, 값은 다음처럼 동작하는 내장 함수 객체입니다:

  1. interface를 해당 이터레이터 프로토타입 객체가 존재하는 인터페이스로 설정합니다.

  2. thisValuethis 값으로 설정합니다.

  3. object? ToObject(thisValue)로 설정합니다.

  4. object플랫폼 객체이면, 보안 검사 수행을 다음 인자로 하여 실행합니다:

    • 플랫폼 객체 object,

    • 식별자 "next",

    • 타입 "method"

  5. objectinterface기본 이터레이터 객체가 아니면, throw를 사용해 TypeError를 발생시킵니다.

  6. indexobjectindex로 설정합니다.

  7. kindobjectkind로 설정합니다.

  8. valuesobjecttarget이터레이션 할 값 쌍 목록으로 설정합니다.

  9. lenvalues의 길이로 설정합니다.

  10. indexlen보다 크거나 같으면, CreateIteratorResultObject(undefined, true)를 반환합니다.

  11. pairvaluesindex번째 엔트리로 설정합니다.

  12. object의 index를 index + 1로 설정합니다.

  13. 이터레이터 결과pair, kind에 대해 반환합니다.

이터레이터 프로토타입 객체클래스 문자열은 지정된 인터페이스식별자와 문자열 " Iterator"를 연결한 결과입니다.

3.7.10. 비동기 이터러블 선언

비동기 이터레이션 메서드 정의하기 인터페이스 definitiontarget에, realm realm과 함께 정의하려면 다음 단계를 수행하세요:
  1. 만약 definition비동기 이터러블 선언(두 종류 중 어느 것이든)이 없다면, 반환합니다.

  2. 단언: definition에는 인덱스 프로퍼티 getter 또는 이터러블 선언이 없습니다.

  3. 만약 definition쌍 비동기 이터러블 선언이 있다면, %Symbol.asyncIterator%entries 메서드를 정의합니다:

    1. steps를 다음 단계 시리즈로 설정합니다. 함수 인자값 args가 주어집니다:

      1. jsValue? ToObject(this 값)으로 설정합니다.

      2. jsValue플랫폼 객체라면 보안 검사 수행jsValue, "%Symbol.asyncIterator%", "method"와 함께 실행합니다.

      3. jsValuedefinition구현하지 않으면, throw 를 사용해 TypeError를 발생시킵니다.

      4. idlObjectjsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.

      5. idlArgs비동기 이터레이터 메서드 인자 변환 알고리즘을 args와 함께 실행한 결과로 설정합니다.

      6. iteratordefinition에 대해 idlObjecttarget으로, "key+value"를 kind로, is finished를 false로 한 새 기본 비동기 이터레이터 객체로 설정합니다.

      7. 비동기 이터레이터 초기화 단계가 존재한다면 definition, idlObject, iterator, idlArgs를 인자로 실행합니다.

      8. iterator를 반환합니다.

    2. FCreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.

    3. SetFunctionName(F, "entries")를 수행합니다.

    4. SetFunctionLength(F, 0)을 수행합니다.

    5. DefineMethodProperty(target, %Symbol.asyncIterator%, F, false)를 수행합니다.

    6. ! CreateDataPropertyOrThrow(target, "entries", F)를 수행합니다.

  4. 만약 definition쌍 비동기 이터러블 선언이 있다면, keys 메서드를 정의합니다:

    1. steps를 다음 단계 시리즈로 설정합니다. 함수 인자값 args가 주어집니다:

      1. jsValue? ToObject(this 값)으로 설정합니다.

      2. jsValue플랫폼 객체라면 보안 검사 수행jsValue, "keys", "method"와 함께 실행합니다.

      3. jsValuedefinition구현하지 않으면, throw 를 사용해 TypeError를 발생시킵니다.

      4. idlObjectjsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.

      5. idlArgs비동기 이터레이터 메서드 인자 변환 알고리즘을 args와 함께 실행한 결과로 설정합니다.

      6. iteratordefinition에 대해 idlObjecttarget으로, "key"를 kind로, is finished를 false로 한 새 기본 비동기 이터레이터 객체로 설정합니다.

      7. 비동기 이터레이터 초기화 단계가 존재한다면 definition, idlObject, iterator, idlArgs를 인자로 실행합니다.

      8. iterator를 반환합니다.

    2. FCreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.

    3. SetFunctionName(F, "keys")를 수행합니다.

    4. SetFunctionLength(F, 0)을 수행합니다.

    5. ! CreateDataPropertyOrThrow(target, "keys", F)를 수행합니다.

  5. values 및 필요시 %Symbol.asyncIterator% 메서드를 정의합니다:

    1. steps를 다음 단계 시리즈로 설정합니다. 함수 인자값 args가 주어집니다:

      1. jsValue? ToObject(this 값)으로 설정합니다.

      2. jsValue플랫폼 객체라면 보안 검사 수행jsValue, "values", "method"와 함께 실행합니다.

      3. jsValuedefinition구현하지 않으면, throw 를 사용해 TypeError를 발생시킵니다.

      4. idlObjectjsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.

      5. idlArgs비동기 이터레이터 메서드 인자 변환 알고리즘을 args와 함께 실행한 결과로 설정합니다.

      6. iteratordefinition에 대해 idlObjecttarget으로, "value"를 kind로, is finished를 false로 한 새 기본 비동기 이터레이터 객체로 설정합니다.

      7. 비동기 이터레이터 초기화 단계가 존재한다면 definition, idlObject, iterator, idlArgs를 인자로 실행합니다.

      8. iterator를 반환합니다.

    2. FCreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.

    3. SetFunctionName(F, "values")를 수행합니다.

    4. SetFunctionLength(F, 0)을 수행합니다.

    5. ! CreateDataPropertyOrThrow(target, "values", F)를 수행합니다.

    6. 만약 definition값 비동기 이터러블 선언이 있다면, ! DefineMethodProperty(target, %Symbol.asyncIterator%, F, false)를 수행합니다.

비동기 이터레이터 메서드 인자 변환 알고리즘은, 인터페이스 definition비동기 이터러블 선언을 가지고 있고 자바스크립트 값의 목록 args가 주어졌을 때 다음과 같이 동작합니다:
  1. idlArgs를 빈 리스트로 설정합니다.

  2. argCountdefinition비동기 이터러블 선언의 인자 개수로 설정하거나, 인자 리스트가 없으면 0으로 설정합니다.

  3. i를 0으로 설정합니다.

  4. i < argCount일 동안:

    1. 만약 iargs크기이거나, args[i]가 undefined이면, 다음을 수행합니다:

      1. 만약 i번째 비동기 이터러블 선언의 인자가 기본값으로 선언되어 있다면, 그 기본값을 idlArgs에 추가합니다.

      2. 그렇지 않으면, idlArgs에 "missing" 특수 값을 추가합니다.

    2. 그 외의 경우, idlArgs에 추가합니다. ECMAScript 값을 해당 타입의 IDL 값으로 변환하여 args[i]를 비동기 이터러블 선언의 인자 리스트 i번째 타입으로 변환한 결과를 추가합니다.

    3. ii + 1로 설정합니다.

  5. idlArgs를 반환합니다.

이 알고리즘은 오버로드 해결 알고리즘을 오버로드가 허용되지 않고 모든 인자가 옵션인 경우로 특화한 것입니다.

3.7.10.1. 기본 비동기 이터레이터 객체

기본 비동기 이터레이터 객체는 지정된 인터페이스, target, 이터레이션 kind에 대해 [[Prototype]] 내부 슬롯이 해당 인터페이스비동기 이터레이터 프로토타입 객체인 객체입니다.

기본 비동기 이터레이터 객체는 내부 값을 가집니다:

참고: 기본 비동기 이터레이터 객체클래스 문자열을 가지지 않습니다. Object.prototype.toString()기본 비동기 이터레이터 객체에 호출하면, 해당 인터페이스비동기 이터레이터 프로토타입 객체클래스 문자열이 사용됩니다.

3.7.10.2. 비동기 이터레이터 프로토타입 객체

비동기 이터레이터 프로토타입 객체 는 지정된 인터페이스에 대해, 비동기 이터러블 선언을 가진 모든 인터페이스에 존재하는 객체입니다. 해당 인터페이스의 기본 비동기 이터레이터 객체의 프로토타입 역할을 합니다.

비동기 이터레이터 프로토타입 객체의 [[Prototype]] 내부 슬롯%AsyncIteratorPrototype%이어야 합니다.

비동기 이터레이터 프로토타입 객체next 데이터 프로퍼티를 가져야 하며, 속성은 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }이고, 값은 다음처럼 동작하는 내장 함수 객체입니다:

  1. interface를 해당 비동기 이터레이터 프로토타입 객체가 존재하는 인터페이스로 설정합니다.

  2. thisValidationPromiseCapability! NewPromiseCapability(%Promise%)로 설정합니다.

  3. thisValuethis 값으로 설정합니다.

  4. objectCompletion(ToObject(thisValue))로 설정합니다.

  5. IfAbruptRejectPromise(object, thisValidationPromiseCapability)를 실행합니다.

  6. object플랫폼 객체이면 보안 검사 수행을 다음 인자로 하여 실행합니다:

    • 플랫폼 객체 object,

    • 식별자 "next",

    • 타입 "method"

    여기서 예외 e가 발생했다면:

    1. ! Call(thisValidationPromiseCapability.[[Reject]], undefined, « e »)를 실행합니다.

    2. thisValidationPromiseCapability.[[Promise]]를 반환합니다.

  7. objectinterface기본 비동기 이터레이터 객체가 아니면:

    1. error를 새 TypeError로 설정합니다.

    2. ! Call(thisValidationPromiseCapability.[[Reject]], undefined, « error »)를 실행합니다.

    3. thisValidationPromiseCapability.[[Promise]]를 반환합니다.

  8. nextSteps를 다음 단계로 설정합니다:

    1. nextPromiseCapability! NewPromiseCapability(%Promise%)로 설정합니다.

    2. objectis finished가 true라면:

      1. resultCreateIteratorResultObject(undefined, true)로 설정합니다.

      2. ! Call(nextPromiseCapability.[[Resolve]], undefined, « result »)를 실행합니다.

      3. nextPromiseCapability.[[Promise]]를 반환합니다.

    3. kindobjectkind로 설정합니다.

    4. nextPromise다음 이터레이션 결과 가져오기 알고리즘을 objecttargetobject에 대해 실행한 결과로 설정합니다.

    5. fulfillSteps를 다음 단계로 설정합니다. next가 주어졌을 때:

      1. objectongoing promise 를 null로 설정합니다.

      2. next이터레이션 종료라면:

        1. objectis finished를 true로 설정합니다.

        2. CreateIteratorResultObject(undefined, true)를 반환합니다.

      3. 그 외의 경우, interface쌍 비동기 이터러블 선언이 있다면:

        1. 단언: next값 쌍이다.

        2. 이터레이터 결과next, kind에 대해 반환합니다.

      4. 그 외의 경우:

        1. 단언: interface값 비동기 이터러블 선언이 있다.

        2. 단언: next는 선언에 나오는 타입의 값이다.

        3. valuenext 자바스크립트 값으로 변환한 결과로 설정합니다.

        4. CreateIteratorResultObject(value, false)를 반환합니다.

    6. onFulfilledCreateBuiltinFunction(fulfillSteps, « »)로 설정합니다.

    7. rejectSteps를 다음 단계로 설정합니다. reason이 주어진 경우:

      1. objectongoing promise 를 null로 설정합니다.

      2. objectis finished를 true로 설정합니다.

      3. Throw reason을 실행합니다.

    8. onRejectedCreateBuiltinFunction(rejectSteps, « »)로 설정합니다.

    9. PerformPromiseThen(nextPromise, onFulfilled, onRejected, nextPromiseCapability)를 실행합니다.

    10. nextPromiseCapability.[[Promise]]를 반환합니다.

  9. ongoingPromiseobjectongoing promise로 설정합니다.

  10. ongoingPromise가 null이 아니면:

    1. afterOngoingPromiseCapability! NewPromiseCapability(%Promise%)로 설정합니다.

    2. onSettledCreateBuiltinFunction(nextSteps, « »)로 설정합니다.

    3. PerformPromiseThen(ongoingPromise, onSettled, onSettled, afterOngoingPromiseCapability)를 실행합니다.

    4. objectongoing promiseafterOngoingPromiseCapability.[[Promise]]로 설정합니다.

  11. 그 외의 경우:

    1. objectongoing promisenextSteps 실행 결과로 설정합니다.

  12. objectongoing promise를 반환합니다.

만약 비동기 이터레이터 리턴 알고리즘이 해당 인터페이스에 대해 정의되어 있다면, 비동기 이터레이터 프로토타입 객체return 데이터 프로퍼티를 가져야 하며, 속성은 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }이고, 값은 다음처럼 동작하는 내장 함수 객체이며, 인자 value를 하나 받습니다:

  1. interface를 해당 비동기 이터레이터 프로토타입 객체가 존재하는 인터페이스로 설정합니다.

  2. returnPromiseCapability! NewPromiseCapability(%Promise%)로 설정합니다.

  3. thisValuethis 값으로 설정합니다.

  4. objectCompletion(ToObject(thisValue))로 설정합니다.

  5. IfAbruptRejectPromise(object, returnPromiseCapability)를 실행합니다.

  6. object플랫폼 객체이면 보안 검사 수행을 다음 인자로 하여 실행합니다:

    • 플랫폼 객체 object,

    • 식별자 "return",

    • 타입 "method"

    여기서 예외 e가 발생했다면:

    1. ! Call(returnPromiseCapability.[[Reject]], undefined, « e »)를 실행합니다.

    2. returnPromiseCapability.[[Promise]]를 반환합니다.

  7. objectinterface기본 비동기 이터레이터 객체가 아니면:

    1. error를 새 TypeError로 설정합니다.

    2. ! Call(returnPromiseCapability.[[Reject]], undefined, « error »)를 실행합니다.

    3. returnPromiseCapability.[[Promise]]를 반환합니다.

  8. returnSteps를 다음 단계로 설정합니다:

    1. returnPromiseCapability! NewPromiseCapability(%Promise%)로 다시 설정합니다.

    2. objectis finished가 true라면:

      1. resultCreateIteratorResultObject(value, true)로 설정합니다.

      2. ! Call(returnPromiseCapability.[[Resolve]], undefined, « result »)를 실행합니다.

      3. returnPromiseCapability.[[Promise]]를 반환합니다.

    3. objectis finished를 true로 설정합니다.

    4. 비동기 이터레이터 리턴 알고리즘을 interface, objecttarget, object, value로 실행한 결과를 반환합니다.

  9. ongoingPromiseobjectongoing promise로 설정합니다.

  10. ongoingPromise가 null이 아니면:

    1. afterOngoingPromiseCapability! NewPromiseCapability(%Promise%)로 설정합니다.

    2. onSettledCreateBuiltinFunction(returnSteps, « »)로 설정합니다.

    3. PerformPromiseThen(ongoingPromise, onSettled, onSettled, afterOngoingPromiseCapability)를 실행합니다.

    4. objectongoing promiseafterOngoingPromiseCapability.[[Promise]]로 설정합니다.

  11. 그 외의 경우:

    1. objectongoing promisereturnSteps 실행 결과로 설정합니다.

  12. fulfillSteps를 다음 단계로 설정합니다:

    1. CreateIteratorResultObject(value, true)를 반환합니다.

  13. onFulfilledCreateBuiltinFunction(fulfillSteps, « »)로 설정합니다.

  14. PerformPromiseThen(objectongoing promise, onFulfilled, undefined, returnPromiseCapability)를 실행합니다.

  15. returnPromiseCapability.[[Promise]]를 반환합니다.

비동기 이터레이터 프로토타입 객체클래스 문자열은 지정된 인터페이스식별자와 문자열 " AsyncIterator"를 연결한 결과입니다.

3.7.11. 맵라이크(maplike) 선언

만약 인터페이스 A맵라이크 선언으로 선언되었다면, A인터페이스 프로토타입 객체에 추가 프로퍼티가 존재합니다. 이 추가 프로퍼티들은 아래 하위 섹션에서 설명합니다.

3.7.11.1. size

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 size 프로퍼티가 반드시 존재해야 합니다:

3.7.11.2. %Symbol.iterator%

A인터페이스 프로토타입 객체에는 %Symbol.iterator% 심볼 이름을 가진 데이터 프로퍼티가 반드시 존재해야 하며, 속성은 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }이고, 값은 entries 프로퍼티의 함수 객체 값입니다.

맵 이터레이터 생성하기 mapkind (값: "key+value", "key", "value")가 주어졌을 때:
  1. closure추상 클로저(Abstract Closure)로 생성합니다. 파라미터 없이 mapkind를 캡처하며, 호출 시 다음 단계를 수행합니다:

    1. keyvalue에 대해 map에서:

      1. keyvalue를 각각 자바스크립트 값으로 변환합니다.

      2. kind가 "key"이면 resultkey로 설정합니다.

      3. 그 외 kind가 "value"이면 resultvalue로 설정합니다.

      4. 그 외의 경우 resultCreateArrayFromListkey, value »)로 설정합니다.

      5. ? GeneratorYield(CreateIteratorResultObject(result, false))를 실행합니다.

      참고: map크기와 엔트리 순서는 Yield로 인해 이 추상 연산이 일시 중지되는 동안 변경될 수 있습니다.

    2. undefined를 반환합니다.

  2. CreateIteratorFromClosure(closure, "%MapIteratorPrototype%", %MapIteratorPrototype%)를 반환합니다.

3.7.11.3. entries

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 entries 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 0입니다.

함수 객체name 프로퍼티 값은 문자열 "entries"입니다.

3.7.11.4. keys

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 keys 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 0입니다.

함수 객체name 프로퍼티 값은 문자열 "keys"입니다.

3.7.11.5. values

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 values 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 0입니다.

함수 객체name 프로퍼티 값은 문자열 "values"입니다.

3.7.11.6. forEach

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 forEach 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 1입니다.

함수 객체name 프로퍼티 값은 문자열 "forEach"입니다.

3.7.11.7. get

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 get 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 1입니다.

함수 객체name 프로퍼티 값은 문자열 "get"입니다.

3.7.11.8. has

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 has 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 1입니다.

함수 객체name 프로퍼티 값은 문자열 "has"입니다.

3.7.11.9. set

만약 A가 식별자 "set"을 가진 멤버를 선언하지 않았고, A가 읽기-쓰기 맵라이크 선언으로 선언되었다면, A인터페이스 프로토타입 객체에는 다음 특성을 가지는 set 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 2입니다.

함수 객체name 프로퍼티 값은 문자열 "set"입니다.

만약 인터페이스가 set 메서드를 선언한다면, -0 키를 +0으로 변환해야 하며, 반드시 this를 반환해야 합니다.

3.7.11.10. delete

만약 A가 식별자 "delete"를 가진 멤버를 선언하지 않았고, A가 읽기-쓰기 맵라이크 선언으로 선언되었다면, A인터페이스 프로토타입 객체에는 다음 특성을 가지는 delete 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 1입니다.

함수 객체name 프로퍼티 값은 문자열 "delete"입니다.

만약 인터페이스가 delete 메서드를 선언한다면, -0 키를 +0으로 변환해야 하며, 키가 존재했는지를 나타내는 boolean을 반환해야 합니다.

3.7.11.11. clear

만약 A가 식별자 "clear"를 가진 멤버를 선언하지 않았고, A가 읽기-쓰기 맵라이크 선언으로 선언되었다면, A인터페이스 프로토타입 객체에는 다음 특성을 가지는 clear 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 0입니다.

함수 객체name 프로퍼티 값은 문자열 "clear"입니다.

만약 인터페이스가 clear 메서드를 선언한다면, map 엔트리 객체를 새로 만들지 않고 반드시 보존해야 하며, undefined를 반환해야 합니다.

3.7.12. 셋라이크(setlike) 선언

만약 인터페이스 A셋라이크 선언으로 선언되었다면, A인터페이스 프로토타입 객체에 추가 프로퍼티가 존재합니다. 이 추가 프로퍼티들은 아래 하위 섹션에서 설명합니다.

3.7.12.1. size

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 size 프로퍼티가 반드시 존재해야 합니다:

3.7.12.2. %Symbol.iterator%

A인터페이스 프로토타입 객체에는 %Symbol.iterator% 심볼 이름을 가진 데이터 프로퍼티가 반드시 존재해야 하며, 속성은 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }이고, 값은 values 프로퍼티의 함수 객체 값입니다.

셋 이터레이터 생성하기 setkind (값: "key+value" 또는 "value")가 주어졌을 때:
  1. closure추상 클로저(Abstract Closure)로 생성합니다. 파라미터 없이 setkind를 캡처하며, 호출 시 다음 단계를 수행합니다:

    1. entry에 대해 set에서:

      1. entry자바스크립트 값으로 변환합니다.

      2. kind가 "value"이면 resultentry로 설정합니다.

      3. 그 외의 경우 resultCreateArrayFromListentry, entry »)로 설정합니다.

      4. ? GeneratorYield(CreateIteratorResultObject(result, false))를 실행합니다.

      참고: set크기와 엔트리 순서는 Yield로 인해 이 추상 연산이 일시 중지된 동안 변경될 수 있습니다.

    2. undefined를 반환합니다.

  2. CreateIteratorFromClosure(closure, "%SetIteratorPrototype%", %SetIteratorPrototype%)를 반환합니다.

3.7.12.3. entries

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 entries 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 0입니다.

함수 객체name 프로퍼티 값은 문자열 "entries"입니다.

3.7.12.4. keys

A인터페이스 프로토타입 객체에는 keys 데이터 프로퍼티가 반드시 존재해야 하며, 속성은 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }이고, 값은 values 프로퍼티의 함수 객체 값입니다.

3.7.12.5. values

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 values 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 0입니다.

함수 객체name 프로퍼티 값은 문자열 "values"입니다.

3.7.12.6. forEach

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 forEach 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 1입니다.

함수 객체name 프로퍼티 값은 문자열 "forEach"입니다.

3.7.12.7. has

A인터페이스 프로토타입 객체에는 다음 특성을 가지는 has 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 1입니다.

함수 객체name 프로퍼티 값은 문자열 "has"입니다.

3.7.12.8. add

만약 A가 식별자 "add"를 가진 멤버를 선언하지 않았고, A가 읽기-쓰기 셋라이크 선언으로 선언되었다면, A인터페이스 프로토타입 객체에는 다음 특성을 가지는 add 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 1입니다.

함수 객체name 프로퍼티 값은 문자열 "add"입니다.

만약 인터페이스가 add 메서드를 선언한다면, -0 값을 +0으로 변환해야 하며, 반드시 설정된 값을 반환해야 합니다.

3.7.12.9. delete

만약 A가 식별자 "delete"를 가진 멤버를 선언하지 않았고, A가 읽기-쓰기 셋라이크 선언으로 선언되었다면, A인터페이스 프로토타입 객체에는 다음 특성을 가지는 delete 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 1입니다.

함수 객체name 프로퍼티 값은 문자열 "delete"입니다.

만약 인터페이스가 delete 메서드를 선언한다면, -0 값을 +0으로 변환해야 하며, 값이 존재했는지를 나타내는 boolean을 반환해야 합니다.

3.7.12.10. clear

만약 A가 식별자 "clear"를 가진 멤버를 선언하지 않았고, A가 읽기-쓰기 셋라이크 선언으로 선언되었다면, A인터페이스 프로토타입 객체에는 다음 특성을 가지는 clear 데이터 프로퍼티가 반드시 존재해야 합니다:

함수 객체length 프로퍼티 값은 숫자 0입니다.

함수 객체name 프로퍼티 값은 문자열 "clear"입니다.

만약 인터페이스가 clear 메서드를 선언한다면, set 엔트리 객체를 새로 만들지 않고 반드시 보존해야 하며, undefined를 반환해야 합니다.

3.8. 인터페이스를 구현하는 플랫폼 객체

자바스크립트 값 value플랫폼 객체임은 value객체(Object)이고, value가 [[PrimaryInterface]] 내부 슬롯을 가지고 있을 때입니다.
자바스크립트 값 value인터페이스 interface구현한다는 것은 value플랫폼 객체이고, value.[[PrimaryInterface]]의 포함된 상속 인터페이스 목록interface포함되어 있을 때입니다.

명세서는 "objectinterface 객체이다" 등 다양한 방식으로 "objectinterface를 구현한다"는 개념을 참조할 수 있습니다.

모든 플랫폼 객체realm과 연관되어 있습니다. 초기 객체들도 마찬가지입니다. 이 realm은 플랫폼 객체의 [[Realm]] 슬롯에 저장됩니다. Web IDL을 사용하는 명세서는 각 플랫폼 객체가 어떤 realm(혹은 그에 대응하는 글로벌 객체)에 속하는지 명시해야 합니다. 특히, 아래 알고리즘은 새 플랫폼 객체를 전달받은 realm에 연관시킵니다.

인터페이스를 구현하는 새 객체 생성하기: realm realm에서 interface를 구현하는 객체를 생성하려면 다음 단계를 수행합니다:
  1. 인터페이스를 내부적으로 구현하는 새 객체 생성 알고리즘을 interface, realm, undefined로 실행한 결과를 반환합니다.

인터페이스를 내부적으로 구현하는 새 객체 생성하기: realm realm과 자바스크립트 값 newTarget을 전달받아 interface를 구현하는 객체를 생성하려면 다음 단계를 수행합니다:
  1. 단언: interfacerealm노출되어 있다.

  2. newTargetundefined이면:

    1. prototyperealminterface에 대한 인터페이스 프로토타입 객체로 설정합니다.

  3. 그 외의 경우:

    1. 단언: IsCallable(newTarget)가 true이다.

    2. prototype? Get(newTarget, "prototype")의 결과로 설정합니다.

    3. prototype객체가 아니면:

      1. targetRealm? GetFunctionRealm(newTarget)의 결과로 설정합니다.

      2. prototypetargetRealminterface에 대한 인터페이스 프로토타입 객체로 설정합니다.

  4. slots를 « [[Prototype]], [[Extensible]], [[Realm]], [[PrimaryInterface]] »로 설정합니다.

  5. interfaceDOMException이면, [[ErrorData]]를 slots에 추가합니다.

  6. instanceMakeBasicObject(slots)로 생성합니다.

  7. instance.[[Realm]]에 realm을 할당합니다.

  8. instance.[[PrimaryInterface]]에 interface를 할당합니다.

  9. instance.[[Prototype]]에 prototype을 할당합니다.

  10. interfacesinterface포함된 상속 인터페이스 목록으로 설정합니다.

  11. 인터페이스 ancestor interface에 대해 interfaces에서:

    1. unforgeablesrealmancestor interface 인터페이스 객체의 [[Unforgeables]] 슬롯 값으로 설정합니다.

    2. keys! unforgeables.[[OwnPropertyKeys]]()의 결과로 설정합니다.

    3. key에 대해 keys에서:

      1. descriptor! unforgeables.[[GetOwnProperty]](key)로 설정합니다.

      2. ! DefinePropertyOrThrow(instance, key, descriptor)를 실행합니다.

  12. interface가 [Global] 확장 속성으로 선언되었다면:

    1. 정규 연산 정의하기 알고리즘을 interface, instance, realm에 대해 실행합니다.

    2. 정규 속성 정의하기 알고리즘을 interface, instance, realm에 대해 실행합니다.

    3. 이터레이션 메서드 정의하기 알고리즘을 interface, instance, realm에 대해 실행합니다.

    4. 비동기 이터레이션 메서드 정의하기 알고리즘을 interface, instance, realm에 대해 실행합니다.

    5. 글로벌 프로퍼티 참조 정의하기 알고리즘을 instance, realm에 대해 실행합니다.

    6. instance.[[SetPrototypeOf]]를 § 3.8.1 [[SetPrototypeOf]]에서 정의된 대로 설정합니다.

  13. 그 외의 경우, interfaces인터페이스가 있고, 인덱스 프로퍼티 지원 또는 이름 프로퍼티 지원 인터페이스가 포함되어 있다면:

    1. instance.[[GetOwnProperty]]를 § 3.9.1 [[GetOwnProperty]]에서 정의된 대로 설정합니다.

    2. instance.[[Set]]을 § 3.9.2 [[Set]]에서 정의된 대로 설정합니다.

    3. instance.[[DefineOwnProperty]]를 § 3.9.3 [[DefineOwnProperty]]에서 정의된 대로 설정합니다.

    4. instance.[[Delete]]를 § 3.9.4 [[Delete]]에서 정의된 대로 설정합니다.

    5. instance.[[PreventExtensions]]를 § 3.9.5 [[PreventExtensions]]에서 정의된 대로 설정합니다.

    6. instance.[[OwnPropertyKeys]]를 § 3.9.6 [[OwnPropertyKeys]]에서 정의된 대로 설정합니다.

  14. instance를 반환합니다.

글로벌 프로퍼티 참조 정의하기: target에 대해 realm realm을 전달받아 다음 단계를 수행합니다:
  1. interfaces목록으로 하여, realm노출된 모든 인터페이스를 포함시킵니다.

  2. interfaces를 정렬합니다. 만약 interfaces항목 AB에 대해, A상속받았다면, A의 인덱스가 B보다 높게 정렬합니다.

  3. interface에 대해 interfaces에서:

    1. interface가 [LegacyNoInterfaceObject] 또는 [LegacyNamespace] 확장 속성으로 선언되지 않았다면:

      1. idinterface식별자로 설정합니다.

      2. interfaceObject인터페이스 객체 생성 알고리즘을 interface, id, realm에 대해 실행한 결과로 설정합니다.

      3. DefineMethodProperty(target, id, interfaceObject, false)를 실행합니다.

      4. interface가 [LegacyWindowAlias] 확장 속성으로 선언되어 있고, targetWindow 인터페이스를 구현하고 있다면:

        1. [LegacyWindowAlias]의 식별자 id에 대해:

          1. DefineMethodProperty(target, id, interfaceObject, false)를 실행합니다.

    2. interface가 [LegacyFactoryFunction] 확장 속성으로 선언되었다면:

      1. [LegacyFactoryFunction]의 식별자 id에 대해:

        1. legacyFactoryFunction레거시 팩토리 함수 생성 알고리즘을 id, interface, realm에 대해 실행한 결과로 설정합니다.

        2. DefineMethodProperty(target, id, legacyFactoryFunction, false)를 실행합니다.

  4. 콜백 인터페이스 interface에 대해, realm에 노출되고, 상수가 정의되어 있는 경우:

    1. idinterface식별자로 설정합니다.

    2. interfaceObject레거시 콜백 인터페이스 객체 생성 알고리즘을 interface, id, realm에 대해 실행한 결과로 설정합니다.

    3. DefineMethodProperty(target, id, interfaceObject, false)를 실행합니다.

  5. 네임스페이스 namespace에 대해, realm에 노출된 경우:

    1. idnamespace식별자로 설정합니다.

    2. namespaceObject네임스페이스 객체 생성 알고리즘을 namespace, realm에 대해 실행한 결과로 설정합니다.

    3. DefineMethodProperty(target, id, namespaceObject, false)를 실행합니다.

플랫폼 객체구현하는 인터페이스 집합은 객체의 생명주기 동안 변하지 않습니다.

서로 다른 플랫폼 객체가 서로 다른 글로벌 객체를 가지더라도, [[PrimaryInterface]] 내부 슬롯에 같은 인터페이스를 참조할 수 있습니다. 예를 들어, 같은 오리진의 iframe이 있고, iframe의 메서드가 메인 페이지의 같은 종류의 요소에 호출되어도 예외가 발생하지 않습니다.

인터페이스 믹스인구현 알고리즘 평가에 직접 참여하지 않습니다. 대신, 인터페이스 믹스인포함된 각 인터페이스는 믹스인의 각 멤버에 대해 자신의 "복사본"을 가지며, 해당 operation function은 수신자가 구현하는 인터페이스가 믹스인을 포함하는지 확인합니다.

플랫폼 객체주 인터페이스(primary interface)는 객체의 [[PrimaryInterface]] 내부 슬롯 값입니다. 이는 해당 객체가 구현하는 가장 파생된 인터페이스입니다.

플랫폼 객체가 연관된 realm은 객체 생성 후 변경될 수 있습니다. 플랫폼 객체에 연관된 realm이 변경되면, [[Prototype]] 내부 슬롯은 즉시 해당 플랫폼 객체의 새 realm의 주 인터페이스인터페이스 프로토타입 객체로 업데이트되어야 합니다.

또한, [Global] 확장 속성을 가진 인터페이스를 구현하는 플랫폼 객체는 다음에서 선언적으로 프로퍼티를 얻습니다:

대신 그 프로퍼티들을 명령형으로 정의해야 합니다.

3.8.1. [[SetPrototypeOf]]

[Global] 확장 속성을 가진 인터페이스를 구현하는 플랫폼 객체 O의 [[SetPrototypeOf]] 내부 메서드가 자바스크립트 값 V로 호출될 때, 다음 단계를 수행합니다:

  1. O연관된 realm글로벌 프로토타입 체인이 변경 가능 이 true이면, ? OrdinarySetPrototypeOf(O, V)를 반환합니다.

  2. ? SetImmutablePrototype(O, V)를 반환합니다.

참고: Window 객체의 경우, WindowProxy 객체의 존재로 인해 [[SetPrototypeOf]]가 Window 객체에 직접 호출되는 것이 관찰되지 않으므로 이 구현 여부는 관찰 불가합니다. 그러나 다른 글로벌 객체의 경우에는 필요합니다.

3.9. 레거시 플랫폼 객체

레거시 플랫폼 객체는 자신의 인덱스 프로퍼티이름 프로퍼티에 해당하는 추가 프로퍼티를 갖는 것처럼 보입니다. 이러한 프로퍼티는 객체의 실제 own 프로퍼티가 아니지만, [[GetOwnProperty]] 내부 메서드를 통해 노출되어 객체의 own 프로퍼티처럼 동작합니다.

하나의 객체가 인덱스 프로퍼티를 지원하는 여러 인터페이스를 구현하는 것이 허용됩니다. 그러나 이 경우, 객체의 지원되는 프로퍼티 인덱스에 대해 정의가 충돌한다면, 객체가 어떤 추가 프로퍼티를 갖는지, 인덱스 프로퍼티와 관련한 정확한 동작은 정의되지 않습니다. 이름 프로퍼티도 마찬가지입니다.

파생된 인터페이스에서 정의된 인덱스 프로퍼티 getter가 레거시 플랫폼 객체가 구현하는 인터페이스 중 가장 파생된 인터페이스의 동작을 정의합니다. 객체를 배열 인덱스로 인덱싱할 때 해당 getter가 동작합니다. setter도 마찬가지로 가장 파생된 인터페이스의 정의를 따릅니다. 이렇게 하면 상위 인터페이스의 특수 연산 정의가 오버라이드될 수 있습니다.

프로퍼티 이름 O가 구현하는 인터페이스 중 어떤 인터페이스의 인터페이스 멤버가 해당 식별자로 존재하고, 그 인터페이스 멤버가 해당 인터페이스들 중 하나에서 위조 불가(unforgeable)일 경우, 해당 플랫폼 객체 O위조 불가 프로퍼티 이름이 됩니다.

getter 지원은 § 3.9.1 [[GetOwnProperty]]에서, setter 지원은 § 3.9.3 [[DefineOwnProperty]]§ 3.9.2 [[Set]]에서 처리됩니다.

또한, 레거시 플랫폼 객체는 다음에서 정의된 내부 메서드를 갖습니다:

3.9.1. [[GetOwnProperty]]

모든 레거시 플랫폼 객체 O의 [[GetOwnProperty]] 내부 메서드는 프로퍼티 이름 P로 호출될 때 다음과 같이 동작해야 합니다:

  1. ? LegacyPlatformObjectGetOwnProperty(O, P, false)를 반환합니다.

3.9.2. [[Set]]

모든 레거시 플랫폼 객체 O의 [[Set]] 내부 메서드는 프로퍼티 이름 P, 값 V, 자바스크립트 값 Receiver로 호출될 때 다음과 같이 동작해야 합니다:

  1. OReceiver가 같은 객체라면:

    1. O인덱스 프로퍼티 setter가 있는 인터페이스를 구현하고, P배열 인덱스라면:

      1. 인덱스 프로퍼티 setter 호출OPV로 실행합니다.

      2. true를 반환합니다.

    2. O이름 프로퍼티 setter가 있는 인터페이스를 구현하고, P문자열(String)이라면:

      1. 이름 프로퍼티 setter 호출OPV로 실행합니다.

      2. true를 반환합니다.

  2. ownDesc? LegacyPlatformObjectGetOwnProperty(O, P, true)의 결과로 설정합니다.

  3. ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc)를 수행합니다.

3.9.3. [[DefineOwnProperty]]

레거시 플랫폼 객체 O의 [[DefineOwnProperty]] 내부 메서드는 프로퍼티 키 P프로퍼티 디스크립터(Property Descriptor) Desc로 호출될 때 다음 단계를 수행해야 합니다:

  1. O인덱스 프로퍼티를 지원하고 P배열 인덱스라면:

    1. IsDataDescriptor(Desc)의 결과가 false라면 false를 반환합니다.

    2. O인덱스 프로퍼티 setter가 있는 인터페이스를 구현하지 않는다면 false를 반환합니다.

    3. 인덱스 프로퍼티 setter 호출OPDesc.[[Value]]로 실행합니다.

    4. true를 반환합니다.

  2. O이름 프로퍼티를 지원하고, O가 [Global] 확장 속성이 있는 인터페이스를 구현하지 않으며, P문자열이며, PO위조 불가 프로퍼티 이름이 아니라면:

    1. P지원되는 프로퍼티 이름이 아니면 creating을 true로, 그렇지 않으면 false로 설정합니다.

    2. O가 [LegacyOverrideBuiltIns] 확장 속성이 있는 인터페이스를 구현하거나 OP라는 own 프로퍼티가 없다면:

      1. creating이 false이고 O이름 프로퍼티 setter가 있는 인터페이스를 구현하지 않는다면 false를 반환합니다.

      2. O이름 프로퍼티 setter가 있는 인터페이스를 구현한다면:

        1. IsDataDescriptor(Desc)의 결과가 false라면 false를 반환합니다.

        2. 이름 프로퍼티 setter 호출OPDesc.[[Value]]로 실행합니다.

        3. true를 반환합니다.

  3. ! OrdinaryDefineOwnProperty(O, P, Desc)를 반환합니다.

3.9.4. [[Delete]]

모든 레거시 플랫폼 객체 O의 [[Delete]] 내부 메서드는 프로퍼티 이름 P로 호출될 때 다음과 같이 동작해야 합니다.

  1. O인덱스 프로퍼티를 지원하고, P배열 인덱스라면:

    1. index! ToUint32(P)의 결과로 설정합니다.

    2. index지원되는 프로퍼티 인덱스가 아니면 true를 반환합니다.

    3. false를 반환합니다.

  2. O이름 프로퍼티를 지원하고, O가 [Global] 확장 속성이 있는 인터페이스를 구현하지 않으며, 이름 프로퍼티 가시성 알고리즘을 프로퍼티 이름 P와 객체 O로 호출한 결과가 true라면:

    1. O이름 프로퍼티 deleter가 있는 인터페이스를 구현하지 않는다면 false를 반환합니다.

    2. operation을 이름 프로퍼티 deleter를 선언할 때 사용한 operation으로 설정합니다.

    3. operation이 식별자 없이 정의되었다면:

      1. 인터페이스 설명에 명시된 단계에 따라 기존 이름 프로퍼티 삭제P 이름으로 수행합니다.

      2. 해당 단계가 삭제 실패를 나타낸다면 false를 반환합니다.

    4. 그 외의 경우, operation이 식별자와 함께 정의되었다면:

      1. 메서드 단계operation에 대해 Othis로, 인자 값 « P »로 실행합니다.

      2. operationboolean 반환 타입으로 선언되고 단계 결과가 false라면 false를 반환합니다.

    5. true를 반환합니다.

  3. O에 이름 P의 own 프로퍼티가 있다면:

    1. 그 프로퍼티가 configurable이 아니라면 false를 반환합니다.

    2. 그 외의 경우, O에서 해당 프로퍼티를 제거합니다.

  4. true를 반환합니다.

3.9.5. [[PreventExtensions]]

레거시 플랫폼 객체의 [[PreventExtensions]] 내부 메서드가 호출될 때, 다음 단계를 수행합니다:

  1. false를 반환합니다.

참고: 이렇게 하면 레거시 플랫폼 객체가 [[PreventExtensions]]가 실패하도록 만들어 계속 확장 가능하게 유지됩니다.

3.9.6. [[OwnPropertyKeys]]

이 문서는 플랫폼 객체인터페이스를 구현할 때 (또는 예외를 나타내는 플랫폼 객체에 대해) 전체 프로퍼티 열거 순서를 정의하지 않습니다. 그러나 레거시 플랫폼 객체에 대해서는 아래와 같이 [[OwnPropertyKeys]] 내부 메서드를 정의합니다.

레거시 플랫폼 객체 O의 [[OwnPropertyKeys]] 내부 메서드가 호출될 때, 다음 단계를 수행합니다:

  1. keys를 자바스크립트 String과 Symbol 값의 빈 목록으로 생성합니다.

  2. O인덱스 프로퍼티를 지원하면, O지원되는 프로퍼티 인덱스 index에 대해, 숫자 오름차순으로 append ! ToString(index)을 keys에 추가합니다.

  3. O이름 프로퍼티를 지원하면, O지원되는 프로퍼티 이름 P이름 프로퍼티 가시성 알고리즘에 따라 visible한 것에 대해, append Pkeys에 추가합니다.

  4. O의 own 프로퍼티 키 중 String 타입 P에 대해, 프로퍼티 생성 시간 오름차순으로 append Pkeys에 추가합니다.

  5. O의 own 프로퍼티 키 중 Symbol 타입 P에 대해, 프로퍼티 생성 시간 오름차순으로 append Pkeys에 추가합니다.

  6. 단언: keys에는 중복 항목이 없다.

  7. keys를 반환합니다.

3.9.7. 추상 연산

프로퍼티 이름 P배열 인덱스인지 판단하기 위해, 다음 알고리즘을 적용한다:

  1. P문자열이 아니면 false를 반환합니다.

  2. indexCanonicalNumericIndexString(P)의 결과로 설정합니다.

  3. indexundefined이면 false를 반환합니다.

  4. IsInteger(index)가 false이면 false를 반환합니다.

  5. index가 −0이면 false를 반환합니다.

  6. index < 0이면 false를 반환합니다.

  7. index ≥ 232 − 1이면 false를 반환합니다.

    참고: 232 − 1은 자바스크립트에서 허용되는 최대 배열 길이입니다.

  8. true를 반환합니다.

이름 프로퍼티 가시성 알고리즘은 주어진 이름 프로퍼티가 객체에 노출되는지 판별할 때 사용합니다. 일부 이름 프로퍼티는 [LegacyOverrideBuiltIns] 확장 속성에 따라 객체에 노출되지 않을 수 있습니다. 프로퍼티 이름 P 및 객체 O에 대해 알고리즘은 다음과 같이 동작합니다:

  1. PO지원되는 프로퍼티 이름이 아니면 false를 반환합니다.

  2. OP라는 own 프로퍼티가 있으면 false를 반환합니다.

    참고: 이는 O에 위조 불가 프로퍼티가 있는 경우도 포함합니다. 실제로 이런 프로퍼티는 객체가 지원되는 프로퍼티 이름을 갖기 전에 항상 설정되며, 일단 설정되면 해당 이름 프로퍼티는 더 이상 노출되지 않습니다.

  3. O가 [LegacyOverrideBuiltIns] 확장 속성이 있는 인터페이스를 구현한다면 true를 반환합니다.

  4. prototypeO.[[GetPrototypeOf]]()로 설정합니다.

  5. prototype이 null이 아닐 때까지 반복:

    1. prototype이름 프로퍼티 객체가 아니고, prototypeP라는 own 프로퍼티가 있으면 false를 반환합니다.

    2. prototypeprototype.[[GetPrototypeOf]]()로 갱신합니다.

  6. true를 반환합니다.

이 알고리즘은 이름 프로퍼티를 가진 객체의 프로퍼티 해석 순서가 다음과 같이 이루어지도록 보장합니다:

  1. 인덱스 프로퍼티.

  2. own 프로퍼티(위조 불가 속성과 연산 포함).

  3. [LegacyOverrideBuiltIns]이 지정된 경우:

    1. 이름 프로퍼티.

    2. 프로토타입 체인에서 오는 프로퍼티.

  4. [LegacyOverrideBuiltIns]이 없는 경우:

    1. 프로토타입 체인에서 오는 프로퍼티.

    2. 이름 프로퍼티.

플랫폼 객체 O에서 프로퍼티 이름 P와 자바스크립트 값 V인덱스 프로퍼티 setter 호출을 하려면 다음 단계를 수행합니다:

  1. index? ToUint32(P)로 설정합니다.

  2. index지원되는 프로퍼티 인덱스가 아니면 creating을 true로, 그렇지 않으면 false로 설정합니다.

  3. operation을 인덱스 프로퍼티 setter를 선언한 operation으로 설정합니다.

  4. Toperation의 두 번째 인자의 타입으로 설정합니다.

  5. valueV를 T 타입의 IDL 값으로 변환한 결과로 설정합니다.

  6. operation이 식별자 없이 정의되어 있다면:

    1. creating이 true이면 인터페이스 설명에 따라 새 인덱스 프로퍼티 값 설정 단계(인덱스 index, 값 value)를 수행합니다.

    2. 그 외의 경우(creating이 false) 인터페이스 설명에 따라 기존 인덱스 프로퍼티 값 설정 단계(인덱스 index, 값 value)를 수행합니다.

  7. 그 외의 경우, operation이 식별자와 함께 정의되어 있다면 메서드 단계operation에 대해 Othis로, 인자값 « index, value »로 실행합니다.

플랫폼 객체 O에서 프로퍼티 이름 P와 자바스크립트 값 V이름 프로퍼티 setter 호출을 하려면 다음 단계를 수행합니다:

  1. creatingP지원되는 프로퍼티 이름이 아니면 true로, 그렇지 않으면 false로 설정합니다.

  2. operation을 이름 프로퍼티 setter를 선언한 operation으로 설정합니다.

  3. Toperation의 두 번째 인자의 타입으로 설정합니다.

  4. valueV를 T 타입의 IDL 값으로 변환한 결과로 설정합니다.

  5. operation이 식별자 없이 정의되어 있다면:

    1. creating이 true이면 인터페이스 설명에 따라 새 이름 프로퍼티 값 설정 단계(P, value)를 수행합니다.

    2. 그 외의 경우(creating이 false) 인터페이스 설명에 따라 기존 이름 프로퍼티 값 설정 단계(P, value)를 수행합니다.

  6. 그 외의 경우, operation이 식별자와 함께 정의되어 있다면 메서드 단계operation에 대해 Othis로, 인자값 « P, value »로 실행합니다.

LegacyPlatformObjectGetOwnProperty 추상 연산은 객체 O, 프로퍼티 이름 P, 불리언 ignoreNamedProps 값을 받아 다음 단계를 수행합니다:

  1. O인덱스 프로퍼티를 지원하고, P배열 인덱스라면:

    1. index! ToUint32(P)로 설정합니다.

    2. index지원되는 프로퍼티 인덱스라면:

      1. operation을 인덱스 프로퍼티 getter를 선언한 operation으로 설정합니다.

      2. value를 초기화되지 않은 변수로 설정합니다.

      3. operation이 식별자 없이 정의되어 있다면 value를 인터페이스 설명에 따라 인덱스 프로퍼티 값 결정(index)의 결과로 설정합니다.

      4. 그 외의 경우, operation이 식별자와 함께 정의되어 있다면 value메서드 단계operation에 대해 Othis로, 인자값 « index »로 실행한 결과로 설정합니다.

      5. desc를 필드가 없는 새로운 프로퍼티 디스크립터(Property Descriptor)로 생성합니다.

      6. desc.[[Value]]를 value를 자바스크립트 값으로 변환한 결과로 설정합니다.

      7. O인덱스 프로퍼티 setter가 있는 인터페이스를 구현하면 desc.[[Writable]]을 true로, 그렇지 않으면 false로 설정합니다.

      8. desc.[[Enumerable]] 및 desc.[[Configurable]]을 true로 설정합니다.

      9. desc를 반환합니다.

    3. ignoreNamedProps를 true로 설정합니다.

  2. O이름 프로퍼티를 지원하고, ignoreNamedProps가 false이면:

    1. 이름 프로퍼티 가시성 알고리즘을 프로퍼티 이름 P와 객체 O로 실행한 결과가 true이면:

      1. operation을 이름 프로퍼티 getter를 선언한 operation으로 설정합니다.

      2. value를 초기화되지 않은 변수로 설정합니다.

      3. operation이 식별자 없이 정의되어 있다면 value를 인터페이스 설명에 따라 이름 프로퍼티 값 결정(P)의 결과로 설정합니다.

      4. 그 외의 경우, operation이 식별자와 함께 정의되어 있다면 value메서드 단계operation에 대해 Othis로, 인자값 « P »로 실행한 결과로 설정합니다.

      5. desc를 필드가 없는 새로운 프로퍼티 디스크립터(Property Descriptor)로 생성합니다.

      6. desc.[[Value]]를 value를 자바스크립트 값으로 변환한 결과로 설정합니다.

      7. O이름 프로퍼티 setter가 있는 인터페이스를 구현하면 desc.[[Writable]]을 true로, 그렇지 않으면 false로 설정합니다.

      8. O가 [LegacyUnenumerableNamedProperties] 확장 속성이 있는 인터페이스를 구현하면 desc.[[Enumerable]]을 false로, 그렇지 않으면 true로 설정합니다.

      9. desc.[[Configurable]]을 true로 설정합니다.

      10. desc를 반환합니다.

  3. OrdinaryGetOwnProperty(O, P)를 반환합니다.

3.10. 관찰 가능한 배열 이그조틱 객체

관찰 가능한 배열 이그조틱 객체는 자바스크립트의 프록시(Proxy) 이그조틱 객체의 한 종류로, 이 절에서 정의된 프록시 트랩을 사용해 생성됩니다. 자바스크립트 명세는 프록시 이그조틱 객체Array 인스턴스를 프록시 대상으로 가질 때 특별 처리를 포함하므로, 관찰 가능한 배열 타입이 자바스크립트 코드에 이러한 특별 처리가 유지된 채 노출되도록 하기 위해 이렇게 정의합니다.

관찰 가능한 배열 이그조틱 객체의 프록시 트랩은 일반 Array 인스턴스의 불변성 외에도 다음의 불변성을 보장합니다:

관찰 가능한 배열 이그조틱 객체 생성하기: realm realm에서 Web IDL 타입 T와 알고리즘 setAlgorithm, deleteAlgorithm이 주어졌을 때:
  1. innerArray! ArrayCreate(0)로 생성합니다.

  2. handlerOrdinaryObjectCreate(null, « [[Type]], [[SetAlgorithm]], [[DeleteAlgorithm]], [[BackingList]] »)로 생성합니다.

  3. handler.[[Type]]에 T를 할당합니다.

  4. handler.[[SetAlgorithm]]에 setAlgorithm을 할당합니다.

  5. handler.[[DeleteAlgorithm]]에 deleteAlgorithm을 할당합니다.

  6. definePropertyCreateBuiltinFunction(§ 3.10.1 defineProperty의 단계, « », realm)로 생성합니다.

  7. ! CreateDataPropertyOrThrow(handler, "defineProperty", defineProperty)를 실행합니다.

  8. deletePropertyCreateBuiltinFunction(§ 3.10.2 deleteProperty의 단계, « », realm)로 생성합니다.

  9. ! CreateDataPropertyOrThrow(handler, "deleteProperty", deleteProperty)를 실행합니다.

  10. getCreateBuiltinFunction(§ 3.10.3 get의 단계, « », realm)로 생성합니다.

  11. ! CreateDataPropertyOrThrow(handler, "get", get)를 실행합니다.

  12. getOwnPropertyDescriptorCreateBuiltinFunction(§ 3.10.4 getOwnPropertyDescriptor의 단계, « », realm)로 생성합니다.

  13. ! CreateDataPropertyOrThrow(handler, "getOwnPropertyDescriptor", getOwnPropertyDescriptor)를 실행합니다.

  14. hasCreateBuiltinFunction(§ 3.10.5 has의 단계, « », realm)로 생성합니다.

  15. ! CreateDataPropertyOrThrow(handler, "has", has)를 실행합니다.

  16. ownKeysCreateBuiltinFunction(§ 3.10.6 ownKeys의 단계, « », realm)로 생성합니다.

  17. ! CreateDataPropertyOrThrow(handler, "ownKeys", ownKeys)를 실행합니다.

  18. preventExtensionsCreateBuiltinFunction(§ 3.10.7 preventExtensions의 단계, « », realm)로 생성합니다.

  19. ! CreateDataPropertyOrThrow(handler, "preventExtensions", preventExtensions)를 실행합니다.

  20. setCreateBuiltinFunction(§ 3.10.8 set의 단계, « », realm)로 생성합니다.

  21. ! CreateDataPropertyOrThrow(handler, "set", set)를 실행합니다.

  22. ! ProxyCreate(innerArray, handler)를 반환합니다.

3.10.1. defineProperty

defineProperty 프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P, descriptorObj가 주어진 경우):
  1. handlerthis 값으로 설정합니다.

  2. descriptor! ToPropertyDescriptor(descriptorObj)로 설정합니다.

  3. P가 "length"이면:

    1. IsAccessorDescriptor(descriptor) 값이 true이면 false를 반환합니다.

    2. descriptor.[[Configurable]]가 존재하고 값이 true이면 false를 반환합니다.

    3. descriptor.[[Enumerable]]가 존재하고 값이 true이면 false를 반환합니다.

    4. descriptor.[[Writable]]가 존재하고 값이 false이면 false를 반환합니다.

    5. descriptor.[[Value]]가 존재하면 길이 설정 알고리즘을 handler, descriptor.[[Value]]로 실행한 결과를 반환합니다.

    6. true를 반환합니다.

  4. P배열 인덱스이면:

    1. IsAccessorDescriptor(descriptor) 값이 true이면 false를 반환합니다.

    2. descriptor.[[Configurable]]가 존재하고 값이 false이면 false를 반환합니다.

    3. descriptor.[[Enumerable]]가 존재하고 값이 false이면 false를 반환합니다.

    4. descriptor.[[Writable]]가 존재하고 값이 false이면 false를 반환합니다.

    5. descriptor.[[Value]]가 존재하면 인덱스 값 설정 알고리즘을 handler, P, descriptor.[[Value]]로 실행한 결과를 반환합니다.

    6. true를 반환합니다.

  5. ? O.[[DefineOwnProperty]](P, descriptor)를 반환합니다.

3.10.2. deleteProperty

deleteProperty 프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P가 주어진 경우):
  1. handlerthis 값으로 설정합니다.

  2. P가 "length"이면 false를 반환합니다.

  3. P배열 인덱스이면:

    1. oldLenhandler.[[BackingList]]의 크기로 설정합니다.

    2. index! ToUint32(P)로 설정합니다.

    3. indexoldLen − 1이면 false를 반환합니다.

    4. handler.[[DeleteAlgorithm]] 알고리즘 단계를 handler.[[BackingList]][index]와 index로 실행합니다.

    5. handler.[[BackingList]]의 마지막 아이템을 제거합니다.

    6. true를 반환합니다.

  4. ? O.[[Delete]](P)를 반환합니다.

3.10.3. get

get 프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P, Receiver가 주어진 경우):
  1. handlerthis 값으로 설정합니다.

  2. lengthhandler.[[BackingList]]의 크기로 설정합니다.

  3. P가 "length"이면 length를 반환합니다.

  4. P배열 인덱스이면:

    1. index! ToUint32(P)로 설정합니다.

    2. indexlength이면 undefined를 반환합니다.

    3. jsValue변환 하여 얻은 handler.[[BackingList]][index]의 JavaScript 값으로 한다.

    4. 위 단계는 절대 예외를 발생시키지 않습니다.

    5. jsValue를 반환합니다.

  5. ? O.[[Get]](P, Receiver)를 반환합니다.

3.10.4. getOwnPropertyDescriptor

getOwnPropertyDescriptor 프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P가 주어진 경우):
  1. handlerthis 값으로 설정합니다.

  2. lengthhandler.[[BackingList]]의 크기로 설정합니다.

  3. P가 "length"이면 ! FromPropertyDescriptor(PropertyDescriptor{[[Configurable]]: false, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: length })를 반환합니다.

  4. P배열 인덱스이면

    1. index! ToUint32(P)로 설정합니다.

    2. indexlength이면 undefined를 반환합니다.

    3. jsValue변환 하여 얻은 handler.[[BackingList]][index]의 JavaScript 값으로 한다.

    4. 위 단계는 절대 예외를 발생시키지 않습니다.

    5. FromPropertyDescriptor(PropertyDescriptor{[[Configurable]]: true, [[Enumerable]]: true, [[Writable]]: true, [[Value]]: jsValue })를 반환합니다.

  5. FromPropertyDescriptor(? O.[[GetOwnProperty]](P))를 반환합니다.

3.10.5. has

has 프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P가 주어진 경우):
  1. handlerthis 값으로 설정합니다.

  2. P가 "length"이면 true를 반환합니다.

  3. P배열 인덱스이면:

    1. index! ToUint32(P)로 설정합니다.

    2. indexhandler.[[BackingList]]의 크기보다 작으면 true를 반환합니다.

    3. false를 반환합니다.

  4. ? O.[[HasProperty]](P)를 반환합니다.

3.10.6. ownKeys

ownKeys 프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O가 주어진 경우):
  1. handlerthis 값으로 설정합니다.

  2. lengthhandler.[[BackingList]]의 크기로 설정합니다.

  3. keys를 빈 목록으로 설정합니다.

  4. i를 0으로 설정합니다.

  5. While i < length 동안:

    1. keys! ToString(i)를 추가합니다.

    2. ii + 1로 설정합니다.

  6. keys! O.[[OwnPropertyKeys]]()를 확장합니다.

  7. CreateArrayFromList(keys)를 반환합니다.

3.10.7. preventExtensions

preventExtensions 프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해):
  1. false를 반환합니다.

3.10.8. set

set 프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P, V, Receiver가 주어진 경우):
  1. handlerthis 값으로 설정합니다.

  2. P가 "length"이면 길이 설정 알고리즘을 handler, V로 실행한 결과를 반환합니다.

  3. P배열 인덱스이면 인덱스 값 설정 알고리즘을 handler, P, V로 실행한 결과를 반환합니다.

  4. ? O.[[Set]](P, V, Receiver)를 반환합니다.

3.10.9. 추상 연산

길이 설정 알고리즘(관찰 가능한 배열 이그조틱 객체의 handlernewLen이 주어진 경우):
  1. uint32Len? ToUint32(newLen)로 설정합니다.

  2. numberLen? ToNumber(newLen)로 설정합니다.

  3. uint32LennumberLen이면 RangeError 예외를 throw합니다.

  4. oldLenhandler.[[BackingList]]의 크기로 설정합니다.

  5. uint32Len > oldLen이면 false를 반환합니다.

  6. indexToDeleteoldLen − 1로 설정합니다.

  7. While indexToDeleteuint32Len 동안:

    1. handler.[[DeleteAlgorithm]] 알고리즘 단계를 handler.[[BackingList]][indexToDelete]와 indexToDelete로 실행합니다.

    2. handler.[[BackingList]]의 마지막 아이템을 제거합니다.

    3. indexToDeleteindexToDelete − 1로 설정합니다.

  8. true를 반환합니다.

인덱스 값 설정 알고리즘(관찰 가능한 배열 이그조틱 객체의 handler, P, V가 주어진 경우):
  1. oldLenhandler.[[BackingList]]의 크기로 설정합니다.

  2. index! ToUint32(P)로 설정합니다.

  3. index > oldLen이면 false를 반환합니다.

  4. idlValueV를 handler.[[Type]] 타입의 IDL 값으로 변환한 결과로 설정합니다.

  5. index < oldLen이면:

    1. handler.[[DeleteAlgorithm]] 알고리즘 단계를 handler.[[BackingList]][index]와 index로 실행합니다.

  6. handler.[[SetAlgorithm]] 알고리즘 단계를 idlValueindex로 실행합니다.

  7. index = oldLen이면 idlValue를 handler.[[BackingList]]에 추가합니다.

  8. 그 외의 경우, handler.[[BackingList]][index]를 idlValue로 설정합니다.

  9. true를 반환합니다.

3.11. 콜백 인터페이스

§ 2.12 인터페이스를 구현하는 객체에서 설명한 것처럼, 콜백 인터페이스는 스크립트에서 임의의 자바스크립트 객체로 구현될 수 있습니다. 아래의 경우들은 주어진 객체에서 콜백 인터페이스연산이 어떻게 호출되는지 설명합니다:

자바스크립트 객체는 해당 객체가 콜백 인터페이스를 구현하는 것으로 간주되기 위해 그 인터페이스에 선언된 상수에 해당하는 프로퍼티를 가질 필요가 없습니다.

Web IDL 인자 리스트란 각 값이 IDL 값이거나 “누락(missing)”이라는 특수 값(선택적 인자가 누락됨을 나타냄)인 값 목록(list)입니다.

Web IDL 인자 리스트를 자바스크립트 인자 리스트로 변환하기: Web IDL 인자 리스트 args가 주어졌을 때, 다음 단계를 수행합니다:
  1. jsArgs를 빈 목록으로 생성합니다.

  2. i를 0으로 설정합니다.

  3. count를 0으로 설정합니다.

  4. i < args크기인 동안:

    1. args[i]가 특수 값 “missing”이면, jsArgsundefined를 추가합니다.

    2. 그 외의 경우, args[i]는 IDL 값입니다:

      1. convertResultargs[i]를 자바스크립트 값으로 변환한 결과로 설정합니다. 예외가 발생하면 다시 throw합니다.

      2. convertResult를 jsArgs에 추가합니다.

      3. counti + 1로 설정합니다.

    3. ii + 1로 설정합니다.

  5. jsArgs를 count 개의 항목만 남도록 잘라냅니다.

  6. jsArgs를 반환합니다.

사용자 객체의 연산 호출하기: 콜백 인터페이스 타입value, 연산 이름 opName, Web IDL 인자 리스트 args, 선택적 콜백 this 값 thisArg가 주어졌을 때, 다음 단계를 수행합니다. 이 단계들은 IDL 값을 반환하거나 예외를 throw합니다.

  1. completion을 초기화되지 않은 변수로 설정합니다.

  2. thisArg가 주어지지 않았다면 thisArgundefined로 설정합니다.

  3. Ovalue에 해당하는 자바스크립트 객체로 설정합니다.

  4. realmO연결된 realm으로 설정합니다.

  5. relevant settingsrealm설정 객체(settings object)로 설정합니다.

  6. stored settingsvalue콜백 컨텍스트로 설정합니다.

  7. 스크립트 실행 준비relevant settings로 실행합니다.

  8. 콜백 실행 준비stored settings로 실행합니다.

  9. XO로 설정합니다.

  10. IsCallable(O)가 false이면:

    1. getResultCompletion(Get(O, opName))로 설정합니다.

    2. getResult비정상 완료(abrupt completion)이면, completiongetResult를 할당하고 return 단계로 점프합니다.

    3. XgetResult.[[Value]]로 설정합니다.

    4. IsCallable(X)가 false이면, completionCompletion Record { [[Type]]: throw, [[Value]]: 새로 생성된 TypeError 객체, [[Target]]: 빈 값 }로 설정하고 return 단계로 점프합니다.

    5. thisArgO로 설정합니다(주어진 값을 덮어씀).

  11. jsArgsargs를 자바스크립트 인자 리스트로 변환한 결과로 설정합니다. 변환 중 예외 발생 시, completion을 예외를 나타내는 completion 값으로 설정하고 return 단계로 점프합니다.

  12. callResultCompletion(Call(X, thisArg, jsArgs))로 설정합니다.

  13. callResult비정상 완료(abrupt completion)이면 completioncallResult를 할당하고 return 단계로 점프합니다.

  14. completioncallResult.[[Value]]를 연산의 반환 타입과 동일한 타입의 IDL 값으로 변환한 결과로 설정합니다. 변환 중 예외 발생 시 completion을 예외를 나타내는 completion 값으로 설정합니다.

  15. Return: 이 시점에서 completion은 IDL 값이거나 비정상 완료임.

    1. 콜백 실행 후 정리(clean up)stored settings로 실행합니다.

    2. 스크립트 실행 후 정리(clean up)relevant settings로 실행합니다.

    3. completion이 IDL 값이면 completion을 반환합니다.

    4. completion비정상 완료이고, 연산이 반환 타입프라미스 타입이 아닌 경우, completion.[[Value]]를 throw합니다.

    5. rejectedPromise! Call(%Promise.reject%, %Promise%, «completion.[[Value]]»)로 설정합니다.

    6. rejectedPromise를 연산의 반환 타입으로 변환한 결과를 반환합니다.

3.11.1. 레거시 콜백 인터페이스 객체

특정 콜백 인터페이스특정 realm에 노출되고, 해당 인터페이스에 상수가 정의되어 있다면, 대응하는 프로퍼티가 그 realm글로벌 객체에 존재합니다. 프로퍼티 이름은 해당 콜백 인터페이스의 식별자이며, 그 값은 레거시 콜백 인터페이스 객체입니다.

특정 콜백 인터페이스에 대한 레거시 콜백 인터페이스 객체내장 함수 객체입니다. 해당 객체에는 그 인터페이스에 정의된 상수에 대응하는 프로퍼티가 있습니다. 자세한 내용은 § 3.7.5 상수 참고.

참고: 레거시 콜백 인터페이스 객체함수 객체이므로, typeof 연산자를 적용하면 "function"이 반환됩니다.

특정 콜백 인터페이스 interface에 대해, 식별자 idrealm realm이 주어졌을 때, 레거시 콜백 인터페이스 객체 생성 알고리즘은 다음과 같습니다:

  1. steps를 다음 단계로 설정합니다:

    1. TypeError 예외를 throw합니다.

  2. FCreateBuiltinFunction(steps, « », realm)으로 생성합니다.

  3. SetFunctionName(F, id)를 수행합니다.

  4. SetFunctionLength(F, 0)를 수행합니다.

  5. 상수 정의interface, F, realm에 대해 수행합니다.

  6. F를 반환합니다.

3.12. 콜백 함수 호출하기

자바스크립트 호출 가능(callable) 객체가 콜백 함수 값으로 사용될 때는, 콜백 인터페이스 값의 연산을 호출하는 방식(이전 섹션 참조)과 유사하게 호출됩니다.

콜백 함수 타입callableWeb IDL 인자 리스트 args, 예외 동작 exceptionBehavior("report" 또는 "rethrow")와 선택적 콜백 this 값 thisArg콜백 함수 호출하기: 다음 단계를 수행합니다. 이 단계는 IDL 값을 반환하거나 예외를 throw합니다.

exceptionBehavior 인자는 callable반환 타입프라미스 타입이 아닐 때만 제공되어야 하며, callable의 반환 타입이 undefined 또는 any가 아니라면 반드시 "rethrow"여야 합니다.

콜 사이트가 이를 준수하도록 업데이트되기 전까지, 명세에서 해당 값을 제공하지 않으면 "rethrow"가 공급된 것으로 간주해야 합니다.
  1. completion을 초기화되지 않은 변수로 설정합니다.

  2. thisArg가 주어지지 않았다면 thisArgundefined로 설정합니다.

  3. Fcallable에 해당하는 자바스크립트 객체로 설정합니다.

  4. IsCallable(F)가 false이면:

    1. 참고: 이것은 콜백 함수가 [LegacyTreatNonObjectAsNull] 특성이 붙은 attribute에서 온 경우에만 발생할 수 있습니다.

    2. undefined를 콜백 함수의 반환 타입으로 변환한 결과를 반환합니다.

  5. realmF연결된 realm으로 설정합니다.

  6. relevant settingsrealm설정 객체로 설정합니다.

  7. stored settingscallable콜백 컨텍스트로 설정합니다.

  8. 스크립트 실행 준비relevant settings로 실행합니다.

  9. 콜백 실행 준비stored settings로 실행합니다.

  10. jsArgsargs를 자바스크립트 인자 리스트로 변환한 결과로 설정합니다. 변환 중 예외가 발생하면 completion을 예외를 나타내는 completion 값으로 설정하고 return 단계로 점프합니다.

  11. callResultCompletion(Call(F, thisArg, jsArgs))로 설정합니다.

  12. callResult비정상 완료(abrupt completion)이면 completioncallResult로 설정하고 return 단계로 점프합니다.

  13. completioncallResult.[[Value]]를 callable의 반환 타입과 동일한 타입의 IDL 값으로 변환한 결과로 설정합니다. 변환 중 예외가 발생하면 completion을 예외를 나타내는 completion 값으로 설정합니다.

  14. Return: 이 시점에서 completion은 IDL 값이거나 비정상 완료입니다.

    1. 콜백 실행 후 정리(clean up)stored settings로 실행합니다.

    2. 스크립트 실행 후 정리(clean up)relevant settings로 실행합니다.

    3. completion이 IDL 값이면 completion을 반환합니다.

    4. 단언: completion비정상 완료이다.

    5. exceptionBehavior가 "rethrow"이면 completion.[[Value]]를 throw합니다.

    6. 그 외 exceptionBehavior가 "report"일 경우:

      1. 단언: callable반환 타입undefined 또는 any이다.

      2. 예외 보고completion.[[Value]]에 대해 realm글로벌 객체로 실행합니다.

      3. 유일한 undefined IDL 값을 반환합니다.

    7. 단언: callable반환 타입프라미스 타입이다.

    8. rejectedPromise! Call(%Promise.reject%, %Promise%, «completion.[[Value]]»)로 설정합니다.

    9. rejectedPromise를 콜백 함수의 반환 타입으로 변환한 결과를 반환합니다.

일부 콜백 함수는 생성자(constructor)로 사용될 수 있습니다. 이런 콜백 함수는 프라미스 타입 반환 타입을 갖지 않아야 합니다.

콜백 함수 타입callableWeb IDL 인자 리스트 args콜백 함수 생성자 호출을 하려면 다음 단계를 수행합니다. 이 단계는 IDL 값을 반환하거나 예외를 throw합니다.

  1. completion을 초기화되지 않은 변수로 설정합니다.

  2. Fcallable에 해당하는 자바스크립트 객체로 설정합니다.

  3. IsConstructor(F)가 false이면 TypeError 예외를 throw합니다.

  4. realmF연결된 realm으로 설정합니다.

  5. relevant settingsrealm설정 객체로 설정합니다.

  6. stored settingscallable콜백 컨텍스트로 설정합니다.

  7. 스크립트 실행 준비relevant settings로 실행합니다.

  8. 콜백 실행 준비stored settings로 실행합니다.

  9. jsArgsargs를 자바스크립트 인자 리스트로 변환한 결과로 설정합니다. 변환 중 예외가 발생하면 completion을 예외를 나타내는 completion 값으로 설정하고 return 단계로 점프합니다.

  10. callResultCompletion(Construct(F, jsArgs))로 설정합니다.

  11. callResult비정상 완료(abrupt completion)이면 completioncallResult로 설정하고 return 단계로 점프합니다.

  12. completioncallResult.[[Value]]를 callable의 반환 타입과 동일한 타입의 IDL 값으로 변환한 결과로 설정합니다. 변환 중 예외가 발생하면 completion을 예외를 나타내는 completion 값으로 설정합니다.

  13. Return: 이 시점에서 completion은 IDL 값이거나 비정상 완료입니다.

    1. 콜백 실행 후 정리(clean up)stored settings로 실행합니다.

    2. 스크립트 실행 후 정리(clean up)relevant settings로 실행합니다.

    3. completion비정상 완료이면 completion.[[Value]]를 throw합니다.

    4. completion을 반환합니다.

3.13. 네임스페이스

특정 네임스페이스가 특정 realm에 노출되는 경우, 해당 realm글로벌 객체에 대응하는 프로퍼티가 존재합니다. 프로퍼티 이름은 네임스페이스의 식별자이고, 값은 네임스페이스 객체라 부르는 객체입니다.

네임스페이스 객체의 특성은 § 3.13.1 네임스페이스 객체에서 설명합니다.

3.13.1. 네임스페이스 객체

특정 네임스페이스 namespacerealm realm에 대해 네임스페이스 객체는 다음과 같이 생성됩니다:

  1. namespaceObjectOrdinaryObjectCreate(realm.[[Intrinsics]].[[%Object.prototype%]])로 생성합니다.

  2. 정규 속성 정의 알고리즘을 namespace, namespaceObject, realm에 대해 실행합니다.

  3. 정규 연산 정의 알고리즘을 namespace, namespaceObject, realm에 대해 실행합니다.

  4. 상수 정의 알고리즘을 namespace, namespaceObject, realm에 대해 실행합니다.

  5. 노출된 인터페이스 interface 중, [LegacyNamespace] 확장 속성이 있고, 그 인자가 namespace의 식별자인 경우:

    1. idinterface식별자로 설정합니다.

    2. interfaceObject인터페이스 객체 생성 알고리즘을 interface, id, realm에 대해 실행한 결과로 설정합니다.

    3. DefineMethodProperty(namespaceObject, id, interfaceObject, false)를 실행합니다.

  6. namespaceObject를 반환합니다.

네임스페이스 객체class string네임스페이스식별자입니다.

3.14. 예외

3.14.1. DOMException 커스텀 바인딩

자바스크립트 바인딩에서는 DOMException인터페이스 프로토타입 객체의 [[Prototype]] 내부 슬롯%Error.prototype% 내재 객체로 설정됩니다(추상 연산 인터페이스 프로토타입 객체 생성에 따라). 또한 [[ErrorData]] 슬롯을 가지며, 모든 내장 예외와 같습니다.

추가적으로, 구현체가 네이티브 Error 객체에 특수 기능이나 비표준 프로퍼티(예: stack 프로퍼티)를 제공한다면, 해당 기능도 DOMException 객체에도 노출되어야 합니다.

3.14.2. 예외 객체

단순 예외는 해당 타입의 네이티브 자바스크립트 객체로 표현됩니다.

DOMException플랫폼 객체로 표현되며, DOMException 인터페이스를 구현합니다.

3.14.3. 예외 생성 및 throw

단순 예외 타입 T예외 생성 알고리즘:
  1. message를 예외 상황에 적합한 구현체 정의(implementation-defined) 메시지로 설정합니다. 호출 명세가 구현체가 메시지를 구성하는 데 참고할 수 있는 정보를 포함할 수 있습니다.

    구현체는 민감하거나 보안 정보가 누출되지 않도록 주의해야 합니다. 예를 들어 크로스 오리진 프레임의 URL, 사용자를 식별할 수 있는 정보 등이 포함되지 않아야 합니다.

  2. args를 « message »로 설정합니다.

  3. constructor현재 realm.[[Intrinsics]].[[%T%]]로 설정합니다.

  4. ! Construct(constructor, args)를 반환합니다.

DOMException예외 생성 알고리즘(name: name):
  1. 단언: nameDOMException 이름 테이블에 포함되어 있다.

  2. exnew DOMException으로 현재 realm에서 생성합니다.

  3. exnamename으로 설정합니다.

  4. exmessage를 예외 상황에 적합한 구현체 정의 메시지로 설정합니다. 호출 명세가 구현체가 메시지를 구성하는 데 참고할 수 있는 정보를 포함할 수 있습니다.

    구현체는 민감하거나 보안 정보가 누출되지 않도록 주의해야 합니다. 예를 들어 크로스 오리진 프레임의 URL, 사용자를 식별할 수 있는 정보 등이 포함되지 않아야 합니다.

  5. ex를 반환합니다.

DOMException 파생 인터페이스의 예외 생성 알고리즘(type: type, 추가 초기화 지침 포함):
  1. exnew type 인터페이스의 인스턴스로 현재 realm에서 생성합니다.

  2. exnametype으로 설정합니다.

  3. exmessage를 예외 상황에 적합한 구현체 정의 메시지로 설정합니다. 호출 명세가 구현체가 메시지를 구성하는 데 참고할 수 있는 정보를 포함할 수 있습니다.

    구현체는 민감하거나 보안 정보가 누출되지 않도록 주의해야 합니다. 예를 들어 크로스 오리진 프레임의 URL, 사용자를 식별할 수 있는 정보 등이 포함되지 않아야 합니다.

  4. 호출자가 기술한 추가 초기화 작업을 ex에 대해 수행합니다.

  5. ex를 반환합니다.

예외 throw 알고리즘:
  1. O를 동일한 인자로 예외 생성 알고리즘을 실행한 결과로 설정합니다.

  2. O를 throw합니다.

위 알고리즘들은 예외를 나타내는 객체함수 객체에서 전파될 때 해당 함수 객체의 realm(즉, 함수 실행 시점의 현행 realm)에 연관된 객체만 전파되도록 제한합니다. 예를 들어, 다음과 같이 IDL이 있다고 가정합니다:

[Exposed=Window]
interface MathUtils {
  // x가 음수면, "NotSupportedError" DOMException을 throw합니다.
  double computeSquareRoot(double x);
};

myMU가 다른 realm에서 온 MathUtils 객체라면, 메서드를 호출할 때 throw된 예외는 해당 메서드의 realm에서 생성된 예외가 됩니다:

const myMU = window.getMathUtils();          // 이 realm의 MathUtils 객체
const otherMU = otherWindow.getMathUtils();  // 다른 realm의 MathUtils 객체

myMU instanceof Object;                      // true
otherMU instanceof Object;                   // false
otherMU instanceof otherWindow.Object;       // true

try {
  otherMU.doComputation.call(myMU, -1);
} catch (e) {
  console.assert(!(e instanceof DOMException));
  console.assert(e instanceof otherWindow.DOMException);
}

3.14.4. 예외 처리

별도로 명시되지 않는 한, 본 문서의 요구사항에 따라 자바스크립트 런타임 의미론이 호출되고 예외가 throw되어 종료될 때, 해당 예외는 호출자에게 전파되어야 하며, 호출자에서 잡히지 않으면 그 상위 호출자에게 계속 전파되어야 합니다.

문서 규약에 따라, 본 문서에서 명세된 알고리즘은 throw된 예외를 가로채거나, 예외가 throw된 경우의 정확한 처리 단계를 명시하거나, 비정상 완료(abrupt completion)을 명시적으로 처리할 수 있습니다.

다음 IDL 조각(fragment)은 두 인터페이스와 하나의 예외를 정의합니다. ExceptionThrowervalueOf 속성은 값을 얻으려 할 때마다 예외를 throw하도록 정의되어 있습니다.

[Exposed=Window]
interface Dahut {
  attribute DOMString type;
};

[Exposed=Window]
interface ExceptionThrower {
  // 이 속성은 항상 NotSupportedError를 throw하며 값을 반환하지 않습니다.
  attribute long valueOf;
};

이 인터페이스를 지원하는 자바스크립트 구현체가 있다고 가정할 때, 다음 코드는 예외가 어떻게 처리되는지 보여줍니다:

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 값에 대해 자바스크립트 ToString 추상 연산을 시도하고 있기 때문입니다.
}

d.type = et;
// 여기서는 잡히지 않은 "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 타입은 ArrayBufferSharedArrayBuffer ([AllowShared]이 사용될 때)에 대한 뷰를 제공하는 객체를 나타내는 데 사용됩니다.

4.2. BufferSource

typedef (ArrayBufferView or ArrayBuffer) BufferSource;

BufferSource 타입은 객체 자체가 ArrayBuffer이거나, ArrayBuffer에 대한 뷰를 제공하는 객체를 나타내는 데 사용됩니다.

참고: [AllowShared] 는 BufferSource와 함께 사용할 수 없습니다. ArrayBuffer가 이를 지원하지 않기 때문입니다. 대신 AllowSharedBufferSource를 사용하세요.

4.3. AllowSharedBufferSource

typedef (ArrayBuffer or SharedArrayBuffer or [AllowShared] ArrayBufferView) AllowSharedBufferSource;

AllowSharedBufferSource 타입은 객체 자체가 ArrayBuffer이거나 SharedArrayBuffer이거나, ArrayBuffer 또는 SharedArrayBuffer에 대한 뷰를 제공하는 객체를 나타내는 데 사용됩니다.

4.4. DOMException

DOMException 타입은 다음 IDL 조각으로 정의된 인터페이스 타입입니다:

[Exposed=*,
 Serializable]
interface DOMException { // but see below note about JavaScript binding
  constructor(optional DOMString message = "", optional DOMString name = "Error");
  readonly attribute DOMString name;
  readonly attribute DOMString message;
  readonly attribute unsigned short code;

  const unsigned short INDEX_SIZE_ERR = 1;
  const unsigned short DOMSTRING_SIZE_ERR = 2;
  const unsigned short HIERARCHY_REQUEST_ERR = 3;
  const unsigned short WRONG_DOCUMENT_ERR = 4;
  const unsigned short INVALID_CHARACTER_ERR = 5;
  const unsigned short NO_DATA_ALLOWED_ERR = 6;
  const unsigned short NO_MODIFICATION_ALLOWED_ERR = 7;
  const unsigned short NOT_FOUND_ERR = 8;
  const unsigned short NOT_SUPPORTED_ERR = 9;
  const unsigned short INUSE_ATTRIBUTE_ERR = 10;
  const unsigned short INVALID_STATE_ERR = 11;
  const unsigned short SYNTAX_ERR = 12;
  const unsigned short INVALID_MODIFICATION_ERR = 13;
  const unsigned short NAMESPACE_ERR = 14;
  const unsigned short INVALID_ACCESS_ERR = 15;
  const unsigned short VALIDATION_ERR = 16;
  const unsigned short TYPE_MISMATCH_ERR = 17;
  const unsigned short SECURITY_ERR = 18;
  const unsigned short NETWORK_ERR = 19;
  const unsigned short ABORT_ERR = 20;
  const unsigned short URL_MISMATCH_ERR = 21;
  const unsigned short QUOTA_EXCEEDED_ERR = 22;
  const unsigned short TIMEOUT_ERR = 23;
  const unsigned short INVALID_NODE_TYPE_ERR = 24;
  const unsigned short DATA_CLONE_ERR = 25;
};

참고: § 3.14.1 DOMException 커스텀 바인딩에서 논의된 바와 같이, 자바스크립트 바인딩은 인터페이스 타입에 대한 일반 요구사항 외에 추가 요구사항을 부과합니다.

DOMException 객체에는 namemessage가 연관되어 있으며, 둘 다 문자열입니다.

new DOMException(message, name) 생성자 단계는 다음과 같습니다:

  1. thisnamename으로 설정합니다.

  2. thismessagemessage로 설정합니다.

name getter 단계는 thisname을 반환하는 것입니다.

message getter 단계는 thismessage를 반환하는 것입니다.

code getter 단계는 DOMException 이름 테이블에서 thisname에 해당하는 레거시 코드를 반환하거나, 테이블에 항목이 없으면 0을 반환합니다.

DOMException 객체는 직렬화 가능한 객체입니다.

이 객체의 직렬화 단계valueserialized가 주어졌을 때 다음과 같습니다:

  1. serialized.[[Name]]을 valuename으로 설정합니다.
  2. serialized.[[Message]]를 valuemessage로 설정합니다.
  3. User agent는 아직 명세되지 않은 흥미로운 부가 데이터(특히 stack 프로퍼티)의 직렬화 표현을 serialized에 붙여야 합니다.

이 객체의 역직렬화 단계valueserialized가 주어졌을 때 다음과 같습니다:

  1. valuenameserialized.[[Name]]으로 설정합니다.
  2. valuemessageserialized.[[Message]]로 설정합니다.
  3. serialized에 다른 데이터가 붙어 있으면 역직렬화하여 value에 붙입니다.

4.5. Function

callback Function = any (any... arguments);

Function 콜백 함수 타입은 인자에 어떤 제한도 없으며 반환값도 제한이 없는 함수 값을 나타내는 데 사용됩니다.

4.6. VoidFunction

callback VoidFunction = undefined ();

VoidFunction 콜백 함수 타입은 인자를 받지 않으며 반환값도 없는 함수 값을 나타내는 데 사용됩니다.

5. 확장성

이 절은 참고용입니다.

언어 바인딩 요구사항에 대한 확장은, 본 문서에서 정의된 것과 충돌하지 않는 확장 속성을 사용하여 명세할 수 있습니다. 개인이나 프로젝트별 사용을 위한 확장은 다른 명세에 나오는 IDL 조각에 포함하지 않아야 하며, 다른 명세에서 사용이 필요한 확장은 Web IDL 작업 그룹(작성 시점 기준 W3C Web Platform Working Group)과 협의하여 본 문서의 향후 버전에 포함될 수 있도록 하는 것이 좋습니다.

IDL 언어의 다른 측면에 대한 확장은 강력히 권장되지 않습니다.

6. 레거시 구성 요소

이 절은 참고용입니다.

레거시 Web IDL 구성 요소는 오직 레거시 웹 플랫폼 기능을 명세하기 위해 존재합니다. 일반적으로 "Legacy"라는 접두사가 붙습니다. 레거시 Web IDL 구성 요소는 레거시 웹 플랫폼 기능의 동작을 명세하기 위해 필요하거나 해당 기능과의 일관성을 위해서만 명세에서 사용하는 것이 강력히 권장됩니다. 레거시 Web IDL 구성 요소 사용을 원하는 편집자는 진행 전에 이슈를 등록하여 논의하는 것이 좋습니다.

구성 요소를 레거시로 표시하는 것은 곧 본 문서에서 제거될 것임을 의미하지는 않습니다. 다만, 이것이 향후 본 문서에서 제거될 좋은 후보임을 시사하며, 여러 휴리스틱에 따라 해당 구성 요소가 명세하려는 웹 플랫폼 기능이 완전히 제거되거나 레거시 Web IDL 구성 요소를 사용하지 않고도 명세할 수 있게 되면 제거될 수 있음을 의미합니다.

7. 이 명세 참조

이 절은 참고용입니다.

여러 IDL 조각을 사용하여 웹 플랫폼 인터페이스를 정의하는 다른 명세들이 본 명세를 참조할 것으로 예상됩니다. 그런 명세들은 아래와 같은 문장을 포함하여, IDL이 본 명세에서 설명한 대로 해석되어야 함을 명시하는 것이 좋습니다:

이 명세의 부록 A에 있는 IDL 조각은, 본 명세의 규범적 참조에서 정의된 IDL 조각들과 함께, “Web IDL” 명세에서 설명한 대로 적합한 IDL 조각 집합에 대해 요구되는 대로 해석되어야 한다. [WEBIDL]

또한, 참조 명세에서 사용자 에이전트의 적합성 클래스는 본 명세의 적합 구현체 클래스로 연결하는 것이 좋습니다:

적합한 FooML 사용자 에이전트는 또한 본 명세의 부록 A의 IDL 조각에 대한 적합 구현체여야 하며, 이는 “Web IDL” 명세에서 설명한 대로 해석되어야 한다. [WEBIDL]

8. 프라이버시 및 보안 고려사항

이 명세는 자바스크립트와 IDL 값 사이의 변환 계층을 정의합니다. 이 계층을 잘못 구현하면 보안 문제가 발생할 수 있습니다.

이 명세는 또한 anyobject IDL 타입을 통해 자바스크립트 값을 직접 사용할 수 있도록 합니다. 이러한 값들은 보안 문제를 피하기 위해 신중하게 다루어야 합니다. 특히, 사용자 스크립트는 이러한 값의 거의 모든 조작에 응답하여 실행될 수 있으며, 이를 사용하는 명세나 구현체의 기대치를 무효화할 수 있습니다.

이 명세는 SharedArrayBuffer 객체와의 상호작용도 가능하게 하는데, 이러한 객체는 타이밍 공격을 구축하는 데 사용할 수 있습니다. 이 객체를 사용하는 명세에서는 이러한 공격을 고려해야 합니다.

감사의 글

이 절은 참고용입니다.

편집자들은 다음 분들께 이 명세에 기여해 주신 것에 대해 감사의 말씀을 전합니다: Glenn Adams, David Andersson, Jake Archibald, Tab Atkins-Bittner, L. David Baron, Art Barstow, Nils Barth, Robin Berjon, David Bruant, Jan-Ivar Bruaroey, Marcos Cáceres, Giovanni Campagna, François Daoust, Domenic Denicola, Chris Dumez, Michael Dyck, Daniel Ehrenberg, Brendan Eich, João Eiras, Gorm Haug Eriksen, Sigbjorn Finne, David Flanagan, Aryeh Gregor, Dimitry Golubovsky, James Graham, Aryeh Gregor, Tiancheng “Timothy” Gu, Kartikaya Gupta, Marcin Hanclik, Jed Hartman, Stefan Haustein, Dominique Hazaël-Massieux, Ian Hickson, Björn Höhrmann, Kyle Huey, Lachlan Hunt, Oliver Hunt, Jim Jewett, Wolfgang Keller, Anne van Kesteren, Olav Junker Kjær, Takayoshi Kochi, Magnus Kristiansen, Raphael Kubo da Costa, Takeshi Kurosawa, Yves Lafon, Travis Leithead, Jim Ley, Kevin Lindsey, Jens Lindström, Peter Linss, 呂康豪 (Kang-Hao Lu), Kyle Machulis, Darien Maillet Valentine, Mark Miller, Ms2ger, Andrew Oakley, 岡坂 史紀 (Shiki Okasaka), Jason Orendorff, Olli Pettay, Simon Pieters, Andrei Popescu, François Remy, Tim Renouf, Jeremy Roman, Tim Ruffles, Alex Russell, Takashi Sakamoto, Doug Schepers, Jonas Sicking, Garrett Smith, Sam Sneddon, Jungkee Song, Josh Soref, Maciej Stachowiak, Austin Sullivan, Anton Tayanovskyy, triple-underscore, Peter Van der Beken, Jeff Walden, Allen Wirfs-Brock, Jeffrey Yasskin 그리고, Collin Xu.

편집자가 명세 관리를 할 수 없었던 기간 동안 이 문서를 관리해 준 Sam Weinig에게도 특별히 감사를 전합니다.

이 현행 표준은 Edgar Chen (Mozilla, echen@mozilla.com)과 Tiancheng "Timothy" Gu (timothygu99@gmail.com)가 집필하였으며, Boris Zbarsky (bzbarsky@mit.edu), Cameron McCormack (cam@mcc.id.au), 그리고 Tobie Langel (tobie@unlockopen.com)의 중요한 기여가 있었습니다.

IDL 문법

이 절에서는 시작 기호 Definitions가 전체 IDL 조각과 매칭되는 LL(1) 문법을 정의합니다.

문법의 각 생성식(production)은 오른쪽에 0이 아닌 개수의 터미널과 비터미널 기호가 있거나, 기호가 없음을 나타내는 엡실론(ε)이 있습니다. 대문자로 시작하는 기호는 비터미널 기호입니다. 고정폭 글꼴로 표시되는 기호는 터미널 기호입니다. 소문자로 시작하는 산세리프 글꼴의 기호는 터미널 기호로, 다음과 같이 Perl 5 정규표현식 문법([PERLRE])을 사용해 매칭됩니다:

integer = /-?([1-9][0-9]*|0[Xx][0-9A-Fa-f]+|0[0-7]*)/
decimal = /-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)/
identifier = /[_-]?[A-Za-z][0-9A-Z_a-z-]*/
string = /"[^"]*"/
whitespace = /[\t\n\r ]+/
comment = /\/\/.*|\/\*(.|\n)*?\*\//
other = /[^\t\n\r 0-9A-Za-z]/

토크나이저는 스칼라 값 시퀀스에 대해 동작합니다. 토크나이징할 때는 가능한 가장 긴 일치 항목을 사용해야 합니다. 예를 들어, 입력 텍스트가 “a1”이면 하나의 identifier로 토크나이즈되고, identifierinteger로 분리되지 않습니다. 가장 긴 일치가 위에 명시된 터미널 심볼 또는 문법의 다른 터미널 심볼 중 하나와 모두 일치할 수 있으면, 후자가 되도록 토크나이즈해야 합니다. 따라서 입력 텍스트 “long”은 터미널 심볼 long으로 토크나이즈되고, identifier "long"이 아닙니다. “.”는 터미널 심볼 .로 토크나이즈되며, other가 아닙니다.

IDL 문법은 고정폭 터미널 심볼과 identifier 터미널의 값 모두에 대해 대소문자를 구분합니다. 예를 들어, 입력 텍스트 “Const”는 identifier로 토크나이즈되고 터미널 심볼 const가 아닙니다. interfaceidentifier가 "A"인 것과 "a"인 것은 구분됩니다. 또한 확장 속성 [legacyfactoryfunction]은 [LegacyFactoryFunction] 확장 속성으로 인식되지 않습니다.

암시적으로, 파싱되는 입력 텍스트의 모든 터미널 사이에는 임의 개수의 whitespacecomment 터미널이 허용됩니다. 이러한 whitespacecomment 터미널은 파싱 중에 무시됩니다.

아래의 LL(1) 문법은 Definitions에서 시작하여 IDL 조각에 매칭됩니다:

Definitions ::
    ExtendedAttributeList Definition Definitions
    ε

Definition ::
    CallbackOrInterfaceOrMixin
    Namespace
    Partial
    Dictionary
    Enum
    Typedef
    IncludesStatement

ArgumentNameKeyword ::
    attribute
    callback
    const
    constructor
    deleter
    dictionary
    enum
    getter
    includes
    inherit
    interface
    iterable
    maplike
    mixin
    namespace
    partial
    readonly
    required
    setlike
    setter
    static
    stringifier
    typedef
    unrestricted

CallbackOrInterfaceOrMixin ::
    callback CallbackRestOrInterface
    interface InterfaceOrMixin

InterfaceOrMixin ::
    InterfaceRest
    MixinRest

InterfaceRest ::
    identifier Inheritance { InterfaceMembers } ;

Partial ::
    partial PartialDefinition

PartialDefinition ::
    interface PartialInterfaceOrPartialMixin
    PartialDictionary
    Namespace

PartialInterfaceOrPartialMixin ::
    PartialInterfaceRest
    MixinRest

PartialInterfaceRest ::
    identifier { PartialInterfaceMembers } ;

InterfaceMembers ::
    ExtendedAttributeList InterfaceMember InterfaceMembers
    ε

InterfaceMember ::
    PartialInterfaceMember
    Constructor

PartialInterfaceMembers ::
    ExtendedAttributeList PartialInterfaceMember PartialInterfaceMembers
    ε

PartialInterfaceMember ::
    Const
    Operation
    Stringifier
    StaticMember
    Iterable
    AsyncIterable
    ReadOnlyMember
    ReadWriteAttribute
    ReadWriteMaplike
    ReadWriteSetlike
    InheritAttribute

Inheritance ::
    : identifier
    ε

MixinRest ::
    mixin identifier { MixinMembers } ;

MixinMembers ::
    ExtendedAttributeList MixinMember MixinMembers
    ε

MixinMember ::
    Const
    RegularOperation
    Stringifier
    OptionalReadOnly AttributeRest

IncludesStatement ::
    identifier includes identifier ;

CallbackRestOrInterface ::
    CallbackRest
    interface identifier { CallbackInterfaceMembers } ;

CallbackInterfaceMembers ::
    ExtendedAttributeList CallbackInterfaceMember CallbackInterfaceMembers
    ε

CallbackInterfaceMember ::
    Const
    RegularOperation

Const ::
    const ConstType identifier = ConstValue ;

ConstValue ::
    BooleanLiteral
    FloatLiteral
    integer

BooleanLiteral ::
    true
    false

FloatLiteral ::
    decimal
    -Infinity
    Infinity
    NaN

ConstType ::
    PrimitiveType
    identifier

ReadOnlyMember ::
    readonly ReadOnlyMemberRest

ReadOnlyMemberRest ::
    AttributeRest
    MaplikeRest
    SetlikeRest

ReadWriteAttribute ::
    AttributeRest

InheritAttribute ::
    inherit AttributeRest

AttributeRest ::
    attribute TypeWithExtendedAttributes AttributeName ;

AttributeName ::
    AttributeNameKeyword
    identifier

AttributeNameKeyword ::
    required

OptionalReadOnly ::
    readonly
    ε

DefaultValue ::
    ConstValue
    string
    [ ]
    { }
    null
    undefined

Operation ::
    RegularOperation
    SpecialOperation

RegularOperation ::
    Type OperationRest

SpecialOperation ::
    Special RegularOperation

Special ::
    getter
    setter
    deleter

OperationRest ::
    OptionalOperationName ( ArgumentList ) ;

OptionalOperationName ::
    OperationName
    ε

OperationName ::
    OperationNameKeyword
    identifier

OperationNameKeyword ::
    includes

ArgumentList ::
    Argument Arguments
    ε

Arguments ::
    , Argument Arguments
    ε

Argument ::
    ExtendedAttributeList ArgumentRest

ArgumentRest ::
    optional TypeWithExtendedAttributes ArgumentName Default
    Type Ellipsis ArgumentName

ArgumentName ::
    ArgumentNameKeyword
    identifier

Ellipsis ::
    ...
    ε

Constructor ::
    constructor ( ArgumentList ) ;

Stringifier ::
    stringifier StringifierRest

StringifierRest ::
    OptionalReadOnly AttributeRest
    ;

StaticMember ::
    static StaticMemberRest

StaticMemberRest ::
    OptionalReadOnly AttributeRest
    RegularOperation

Iterable ::
    iterable < TypeWithExtendedAttributes OptionalType > ;

OptionalType ::
    , TypeWithExtendedAttributes
    ε

AsyncIterable ::
    async_iterable < TypeWithExtendedAttributes OptionalType > OptionalArgumentList ;

OptionalArgumentList ::
    ( ArgumentList )
    ε

ReadWriteMaplike ::
    MaplikeRest

MaplikeRest ::
    maplike < TypeWithExtendedAttributes , TypeWithExtendedAttributes > ;

ReadWriteSetlike ::
    SetlikeRest

SetlikeRest ::
    setlike < TypeWithExtendedAttributes > ;

Namespace ::
    namespace identifier { NamespaceMembers } ;

NamespaceMembers ::
    ExtendedAttributeList NamespaceMember NamespaceMembers
    ε

NamespaceMember ::
    RegularOperation
    readonly AttributeRest
    Const

Dictionary ::
    dictionary identifier Inheritance { DictionaryMembers } ;

DictionaryMembers ::
    DictionaryMember DictionaryMembers
    ε

DictionaryMember ::
    ExtendedAttributeList DictionaryMemberRest

DictionaryMemberRest ::
    required TypeWithExtendedAttributes identifier ;
    Type identifier Default ;

PartialDictionary ::
    dictionary identifier { DictionaryMembers } ;

Default ::
    = DefaultValue
    ε

Enum ::
    enum identifier { EnumValueList } ;

EnumValueList ::
    string EnumValueListComma

EnumValueListComma ::
    , EnumValueListString
    ε

EnumValueListString ::
    string EnumValueListComma
    ε

CallbackRest ::
    identifier = Type ( ArgumentList ) ;

Typedef ::
    typedef TypeWithExtendedAttributes identifier ;

Type ::
    SingleType
    UnionType Null

TypeWithExtendedAttributes ::
    ExtendedAttributeList Type

SingleType ::
    DistinguishableType
    any
    PromiseType

UnionType ::
    ( UnionMemberType or UnionMemberType UnionMemberTypes )

UnionMemberType ::
    ExtendedAttributeList DistinguishableType
    UnionType Null

UnionMemberTypes ::
    or UnionMemberType UnionMemberTypes
    ε

DistinguishableType ::
    PrimitiveType Null
    StringType Null
    identifier Null
    sequence < TypeWithExtendedAttributes > Null
    async_sequence < TypeWithExtendedAttributes > Null
    object Null
    symbol Null
    BufferRelatedType Null
    FrozenArray < TypeWithExtendedAttributes > Null
    ObservableArray < TypeWithExtendedAttributes > Null
    RecordType Null
    undefined Null

PrimitiveType ::
    UnsignedIntegerType
    UnrestrictedFloatType
    boolean
    byte
    octet
    bigint

UnrestrictedFloatType ::
    unrestricted FloatType
    FloatType

FloatType ::
    float
    double

UnsignedIntegerType ::
    unsigned IntegerType
    IntegerType

IntegerType ::
    short
    long OptionalLong

OptionalLong ::
    long
    ε

StringType ::
    ByteString
    DOMString
    USVString

PromiseType ::
    Promise < Type >

RecordType ::
    record < StringType , TypeWithExtendedAttributes >

Null ::
    ?
    ε

BufferRelatedType ::
    ArrayBuffer
    SharedArrayBuffer
    DataView
    Int8Array
    Int16Array
    Int32Array
    Uint8Array
    Uint16Array
    Uint32Array
    Uint8ClampedArray
    BigInt64Array
    BigUint64Array
    Float16Array
    Float32Array
    Float64Array

ExtendedAttributeList ::
    [ ExtendedAttribute ExtendedAttributes ]
    ε

ExtendedAttributes ::
    , ExtendedAttribute ExtendedAttributes
    ε

ExtendedAttribute ::
    ( ExtendedAttributeInner ) ExtendedAttributeRest
    [ ExtendedAttributeInner ] ExtendedAttributeRest
    { ExtendedAttributeInner } ExtendedAttributeRest
    Other ExtendedAttributeRest

ExtendedAttributeRest ::
    ExtendedAttribute
    ε

ExtendedAttributeInner ::
    ( ExtendedAttributeInner ) ExtendedAttributeInner
    [ ExtendedAttributeInner ] ExtendedAttributeInner
    { ExtendedAttributeInner } ExtendedAttributeInner
    OtherOrComma ExtendedAttributeInner
    ε

Other ::
    integer
    decimal
    identifier
    string
    other
    -
    -Infinity
    .
    ...
    :
    ;
    <
    =
    >
    ?
    *
    ByteString
    DOMString
    FrozenArray
    Infinity
    NaN
    ObservableArray
    Promise
    USVString
    any
    bigint
    boolean
    byte
    double
    false
    float
    long
    null
    object
    octet
    or
    optional
    record
    sequence
    short
    symbol
    true
    unsigned
    undefined
    ArgumentNameKeyword
    BufferRelatedType

OtherOrComma ::
    Other
    ,

IdentifierList ::
    identifier Identifiers

Identifiers ::
    , identifier Identifiers
    ε

IntegerList ::
    integer Integers

Integers ::
    , integer Integers
    ε

ExtendedAttributeNoArgs ::
    identifier

ExtendedAttributeArgList ::
    identifier ( ArgumentList )

ExtendedAttributeIdent ::
    identifier = identifier

ExtendedAttributeString ::
    identifier = string

ExtendedAttributeInteger ::
    identifier = integer

ExtendedAttributeDecimal ::
    identifier = decimal

ExtendedAttributeWildcard ::
    identifier = *

ExtendedAttributeIdentList ::
    identifier = ( IdentifierList )

ExtendedAttributeIntegerList ::
    identifier = ( IntegerList )

ExtendedAttributeNamedArgList ::
    identifier = identifier ( ArgumentList )

참고: Other 비단말은 (, ), [, ], {, } 그리고 ,를 제외한 모든 단일 단말 기호와 일치합니다.

ExtendedAttribute 비단말은 괄호, 대괄호, 중괄호가 균형을 이루고 , 토큰이 그 균형 잡힌 괄호 안에서만 나타나는 한, 비어 있지 않은 단말 기호 시퀀스와 일치하지만, 이러한 가능한 시퀀스 중 오직 일부만이 이 명세에서 정의된 확장 속성 에서 사용됩니다 — 사용되는 확장 속성의 구문에 대해서는 § 2.14 확장 속성 을 참조하세요.

문서 관례

이 문서에서는 다음과 같은 서체 관례를 사용합니다:

이 문서의 알고리즘에서는 다음과 같은 관례를 사용합니다:

적합성

이 명세서의 모든 내용은 도표, 예시, 참고 및 정보용으로 표시된 섹션을 제외하면 규범적입니다.

이 명세서는 Infra 표준에 의존합니다. [INFRA]

이 명세서에서는 다음과 같은 적합성 클래스가 정의됩니다:

적합한 IDL 조각 집합

IDL 조각들의 집합은, 함께 고려했을 때, 이 명세서에서 IDL 조각에 적용되는 must-, required-, shall- 수준의 기준을 모두 충족시키면 적합한 IDL 조각 집합으로 간주됩니다.

적합한 구현

사용자 에이전트가 지원하는 모든 언어 바인딩에 대해 구현에 적용되는 must-, required-, shall- 수준의 기준을 이 명세서에서 모두 충족시키면, 해당 사용자 에이전트는 적합한 구현으로, 해당 적합한 IDL 조각 집합에 대해 간주됩니다.

적합한 JavaScript 구현

사용자 에이전트가 JavaScript 언어 바인딩에 대해 구현에 적용되는 must-, required-, shall- 수준의 기준을 이 명세서에서 모두 충족시키면, 해당 사용자 에이전트는 적합한 JavaScript 구현으로, 해당 적합한 IDL 조각 집합에 대해 간주됩니다.

지적 재산권

이 현행 표준에는 W3C의 WebIDL [sic] Level 1에서 복사된 자료가 포함되어 있으며, 해당 자료는 W3C 소프트웨어 및 문서 라이선스에 따라 제공됩니다.

Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). 이 저작물은 크리에이티브 커먼즈 저작자 표시 4.0 국제 라이선스에 따라 라이선스가 부여됩니다. 일부 내용이 소스 코드에 통합된 범위 내에서는, 해당 소스 코드의 부분은 BSD 3-Clause 라이선스에 따라 별도로 라이선스됩니다.

이것이 현행 표준입니다. 특허 검토용 버전에 관심이 있는 분은 현행 표준 검토 초안을 참고하시기 바랍니다.

색인

이 명세에서 정의된 용어

참조로 정의된 용어

참고 문헌

규범적 참고 문헌

[DOM]
Anne van Kesteren. DOM 표준. 현행 표준. URL: https://dom.spec.whatwg.org/
[ECMA-262]
ECMAScript 언어 명세. URL: https://tc39.es/ecma262/multipage/
[ECMA-402]
ECMAScript 국제화 API 명세. URL: https://tc39.es/ecma402/
[HTML]
Anne van Kesteren; et al. HTML 표준. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[IEEE-754]
IEEE 부동소수점 산술 표준. 2019년 7월 22일. URL: https://ieeexplore.ieee.org/document/8766229
[Infra]
Anne van Kesteren; Domenic Denicola. Infra 표준. 현행 표준. URL: https://infra.spec.whatwg.org/
[PERLRE]
Perl 정규식 (Perl 5.8.8). 2006년 2월. URL: http://search.cpan.org/dist/perl/pod/perlre.pod
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 표준. 현행 표준. URL: https://webidl.spec.whatwg.org/

정보용 참고 문헌

[API-DESIGN-PRINCIPLES]
Martin Thomson; Jeffrey Yasskin. 웹 플랫폼 설계 원칙. URL: https://w3ctag.github.io/design-principles/
[CSS3-CONDITIONAL]
Chris Lilley; David Baron; Elika Etemad. CSS 조건부 규칙 모듈 3단계. URL: https://drafts.csswg.org/css-conditional-3/
[CSSOM]
Daniel Glazman; Emilio Cobos Álvarez. CSS 오브젝트 모델 (CSSOM). URL: https://drafts.csswg.org/cssom/
[FETCH]
Anne van Kesteren. Fetch 표준. 현행 표준. URL: https://fetch.spec.whatwg.org/
[INDEXEDDB]
Nikunj Mehta; et al. Indexed Database API. URL: https://w3c.github.io/IndexedDB/
[PROPOSAL-FLOAT16ARRAY]
JavaScript에 float16 TypedArrays 추가 제안. URL: https://tc39.es/proposal-float16array/
[SERVICE-WORKERS]
Yoshisato Yanagisawa; Monica CHINTALA. 서비스 워커. URL: https://w3c.github.io/ServiceWorker/
[STREAMS]
Adam Rice; et al. Streams 표준. 현행 표준. URL: https://streams.spec.whatwg.org/
[WASM-JS-API-1]
Daniel Ehrenberg. WebAssembly JavaScript 인터페이스. URL: https://webassembly.github.io/spec/js-api/
[WASM-JS-API-2]
. Ms2ger. WebAssembly JavaScript 인터페이스. URL: https://webassembly.github.io/spec/js-api/
[XML-NAMES]
Tim Bray; et al. Namespaces in XML 1.0 (세 번째 판). 2009년 12월 8일. REC. URL: https://www.w3.org/TR/xml-names/

IDL 색인

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

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

dictionary QuotaExceededErrorOptions {
  double quota;
  double requested;
};

typedef (Int8Array or Int16Array or Int32Array or
         Uint8Array or Uint16Array or Uint32Array or Uint8ClampedArray or
         BigInt64Array or BigUint64Array or
         Float16Array or Float32Array or Float64Array or DataView) ArrayBufferView;

typedef (ArrayBufferView or ArrayBuffer) BufferSource;
typedef (ArrayBuffer or SharedArrayBuffer or [AllowShared] ArrayBufferView) AllowSharedBufferSource;
[Exposed=*,
 Serializable]
interface DOMException { // but see below note about JavaScript binding
  constructor(optional DOMString message = "", optional DOMString name = "Error");
  readonly attribute DOMString name;
  readonly attribute DOMString message;
  readonly attribute unsigned short code;

  const unsigned short INDEX_SIZE_ERR = 1;
  const unsigned short DOMSTRING_SIZE_ERR = 2;
  const unsigned short HIERARCHY_REQUEST_ERR = 3;
  const unsigned short WRONG_DOCUMENT_ERR = 4;
  const unsigned short INVALID_CHARACTER_ERR = 5;
  const unsigned short NO_DATA_ALLOWED_ERR = 6;
  const unsigned short NO_MODIFICATION_ALLOWED_ERR = 7;
  const unsigned short NOT_FOUND_ERR = 8;
  const unsigned short NOT_SUPPORTED_ERR = 9;
  const unsigned short INUSE_ATTRIBUTE_ERR = 10;
  const unsigned short INVALID_STATE_ERR = 11;
  const unsigned short SYNTAX_ERR = 12;
  const unsigned short INVALID_MODIFICATION_ERR = 13;
  const unsigned short NAMESPACE_ERR = 14;
  const unsigned short INVALID_ACCESS_ERR = 15;
  const unsigned short VALIDATION_ERR = 16;
  const unsigned short TYPE_MISMATCH_ERR = 17;
  const unsigned short SECURITY_ERR = 18;
  const unsigned short NETWORK_ERR = 19;
  const unsigned short ABORT_ERR = 20;
  const unsigned short URL_MISMATCH_ERR = 21;
  const unsigned short QUOTA_EXCEEDED_ERR = 22;
  const unsigned short TIMEOUT_ERR = 23;
  const unsigned short INVALID_NODE_TYPE_ERR = 24;
  const unsigned short DATA_CLONE_ERR = 25;
};

callback Function = any (any... arguments);
callback VoidFunction = undefined ();
MDN

DOMException/DOMException

In all current engines.

Firefox37+Safari10.1+Chrome46+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DOMException/message

In all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

DOMException/name

In all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

DOMException

In all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
Node.js17.0.0+