1. 소개
이 섹션은 참고용입니다.
이 표준은 웹 브라우저에 구현될 인터페이스를 기술하는 데 사용할 수 있는 인터페이스 정의 언어, 웹 IDL을 정의합니다. 웹 IDL은 웹 플랫폼의 일반적인 스크립트 객체의 동작을 보다 쉽게 명세할 수 있도록 하는 다양한 기능을 가진 IDL 변형입니다. 웹 IDL로 기술된 인터페이스가 자바스크립트 실행 환경 내의 구조와 어떻게 대응되는지도 이곳에서 자세히 설명합니다.
구체적으로, 웹 IDL은 웹 플랫폼 객체의 표면 API를 명세하는 구문과, 그 API가 자바스크립트 구조로 어떻게 나타나는지 상세히 기술하는 자바스크립트 바인딩을 제공합니다. 이로 인해 글로벌 속성 설치, 숫자 입력 처리, 반복 동작 노출과 같은 일반적인 작업들이 웹 플랫폼 명세서 전체에서 일관성을 유지할 수 있습니다. 이러한 명세서들은 웹 IDL로 인터페이스를 기술하고, 프로즈로 API 고유의 세부사항을 명세합니다.
"자바스크립트"라는 용어는 공식 용어 ECMAScript가 아닌 ECMA-262를 의미하며, 자바스크립트라는 명칭이 더 널리 알려져 있기 때문에 사용합니다.
2. 인터페이스 정의 언어
이 섹션에서는 웹 IDL이라는 언어를 설명합니다. 이는 웹 플랫폼의 API를 정의하는 인터페이스를 명세하는 데 사용할 수 있습니다. 웹 API를 정의하는 명세서는 하나 이상의
IDL
프래그먼트를 포함하여,
해당 명세서에서 정의된 API의 인터페이스(객체가 가질 수 있는 상태와 동작)를 기술합니다.
IDL 프래그먼트는
IDL 프래그먼트에 등장할 수 있는 다양한 정의의 종류는 다음과 같습니다: 인터페이스, 부분 인터페이스 정의, 인터페이스 믹스인, 부분 믹스인 정의, 콜백 함수, 콜백 인터페이스, 네임스페이스, 부분 네임스페이스 정의, 딕셔너리, 부분 딕셔너리 정의, 타입 정의(typedef) 및 includes 문입니다. 모든 종류는 아래 섹션에서 정의됩니다.
각 정의
(
[extended_attributes ]interface identifier { /* interface_members... */ };
Definitions ::ExtendedAttributeList Definition Definitions ε
Definition ::CallbackOrInterfaceOrMixin Namespace Partial Dictionary Enum Typedef IncludesStatement
아래는 IDL 프래그먼트의 예시입니다.
[Exposed =Window ]interface Paint { }; [Exposed =Window ]interface SolidColor :Paint {attribute double red ;attribute double green ;attribute double blue ; }; [Exposed =Window ]interface Pattern :Paint {attribute DOMString imageURL ; }; [Exposed =Window ]interface GraphicalWindow {constructor ();readonly attribute unsigned long width ;readonly attribute unsigned long height ;attribute Paint currentPaint ;undefined drawRectangle (double x ,double y ,double width ,double height );undefined drawText (double x ,double y ,DOMString text ); };
여기서는 네 개의 인터페이스가 정의되고 있습니다.
GraphicalWindow
인터페이스에는 두 개의
읽기 전용 속성,
하나의 쓰기 가능한 속성, 그리고 두 개의 연산이
정의되어 있습니다. GraphicalWindow
인터페이스를 구현하는 객체들은 해당 언어에 맞는 방식으로 이 속성과 연산을 노출합니다.
자바스크립트에서는, IDL 인터페이스의 속성들이 접근자 속성으로, 연산들은 모든 GraphicalWindow
객체의 프로토타입 객체에 내장 함수
객체(built-in function object)로서 데이터 속성으로 노출됩니다. 각 자바스크립트
객체는 GraphicalWindow
를 구현하면 해당 프로토타입 객체를 프로토타입 체인에 갖게 됩니다.
GraphicalWindow
에 등장하는 생성자 연산은 자바스크립트 구현체에서 생성자가 존재하도록 하여,
new GraphicalWindow()
를 호출하면 해당 인터페이스를 구현하는 새로운 객체를 반환합니다.
모든 인터페이스에는 [Exposed
] 확장 속성이
붙어 있으며, 이로 인해 인터페이스가 realm의 글로벌 객체가 Window
객체인 경우에만 사용할 수 있도록 보장합니다.
2.1. 이름
모든 인터페이스,
부분 인터페이스 정의,
네임스페이스,
부분 네임스페이스 정의,
딕셔너리,
부분 딕셔너리 정의,
열거형,
콜백 함수,
콜백 인터페이스 및
타입 정의(typedef) (이들을 통틀어 이름이 있는 정의이라 함)
그리고 모든 상수,
속성,
딕셔너리 멤버는
식별자를 가지며, 일부
연산도 마찬가지입니다.
식별자는 선언 내 어딘가에 등장하는
-
이름이 있는 정의의 경우,
identifier 토큰이interface ,namespace ,dictionary ,enum 또는callback 키워드 바로 뒤에 나오며, 이 토큰이 해당 정의의 식별자를 결정합니다.interface interface_identifier { /* interface_members... */ };partial interface interface_identifier { /* interface_members... */ };namespace namespace_identifier { /* namespace_members... */ };partial namespace namespace_identifier { /* namespace_members... */ };dictionary dictionary_identifier { /* dictionary_members... */ };partial dictionary dictionary_identifier { /* dictionary_members... */ };enum enumeration_identifier {"enum" ,"values" /* , ... */ };callback callback_identifier =return_type (/* arguments... */);callback interface callback_interface_identifier { /* interface_members... */ }; -
속성, 타입 정의, 딕셔너리 멤버의 경우, 선언 마지막에 세미콜론 앞에 위치한
identifier 토큰이 식별자를 결정합니다.[
extended_attributes ]interface identifier {attribute type attribute_identifier ; };typedef type typedef_identifier ;dictionary identifier {type dictionary_member_identifier ; }; -
상수의 경우, 등호 앞에 위치한
identifier 토큰이 식별자를 결정합니다.const type constant_identifier = 42; -
연산의 경우, 반환 타입 뒤, 여는 괄호 앞에 위치한
identifier 토큰(즉,OptionalOperationName 문법 기호의 일부로 매칭되는 토큰)이 연산의 식별자를 결정합니다. 만약 해당identifier 토큰이 없다면, 연산은 식별자를 가지지 않습니다.interface interface_identifier {return_type operation_identifier (/* arguments... */); };
참고: 연산은 getter, setter와 같은 특수 연산을 선언할 때 식별자가 없을 수 있습니다.
이러한 모든 구조에서, 식별자는
참고: 앞에 오는 U+005F (_)는 식별자가 예약어처럼 보이지 않게 하기 위해 사용되며, 예를
들어 "interface
"라는 이름의 인터페이스를 정의할 수 있습니다. 식별자를 해제할 때는 앞의 U+005F (_)를 삭제합니다.
연산의 인자(argument)는 더 넓은 범위의 식별자 집합을 가질 수 있습니다. 연산 선언에서 인자의 식별자는 타입 뒤에 바로 명시되며,
interface interface_identifier {return_type operation_identifier (argument_type argument_identifier /* , ... */); };
ArgumentNameKeyword ::attribute callback const constructor deleter dictionary enum getter includes inherit interface iterable maplike mixin namespace partial readonly required setlike setter static stringifier typedef unrestricted
위에 언급된 IDL 구조(연산 인자 제외)의 식별자는
"constructor
", "toString
"이거나 U+005F (_)로 시작해서는 안 됩니다. 이런 것들은 예약 식별자라 부릅니다.
"toJSON
" 식별자는 예약 식별자는
아니지만,
정상 연산에서만 객체를 JSON 타입으로 변환하는 목적으로 사용해야 하며,
§ 2.5.3.1 toJSON에서 설명합니다.
참고: 특정 구조에 대한 식별자 명명 제한은 이후 섹션에서 추가될 수 있습니다.
주어진 구현체가 지원하는 IDL 프래그먼트 집합 내에서, 모든 인터페이스, 네임스페이스, 딕셔너리, 열거형, 콜백 함수, 콜백 인터페이스, 타입 정의의 식별자는 서로 같아서는 안 됩니다.
하나의 IDL 프래그먼트 내에서는, 정의에 대한 참조가 참조된 정의의 선언 뒤에 등장하지 않아도 됩니다. 또한 IDL 프래그먼트 간에도 참조할 수 있습니다.
따라서, 아래의 IDL 프래그먼트는 유효합니다:
[Exposed =Window ]interface B :A {undefined f (SequenceOfLongs x ); }; [Exposed =Window ]interface A { };typedef sequence <long >SequenceOfLongs ;
아래의 IDL 프래그먼트는 정의와 인터페이스 멤버에 어떻게 식별자가 부여되는지 보여줍니다.
// 타입 정의 식별자: "number"typedef double number ; // 인터페이스 식별자: "System" [Exposed =Window ]interface System { // 연산 식별자: "createObject" // 연산 인자 식별자: "interface"object createObject (DOMString _interface ); // 연산 인자 식별자: "interface"sequence <object >getObjects (DOMString interface ); // 연산에는 식별자가 없음; getter 선언임.getter DOMString (DOMString keyName ); }; // 인터페이스 식별자: "TextField" [Exposed =Window ]interface TextField { // 속성 식별자: "const"attribute boolean _const ; // 속성 식별자: "value"attribute DOMString ?_value ; };
TextField
인터페이스의 두 번째 속성은 (IDL 문법에서 "value"가 키워드가 아니므로) 반드시 밑줄로 이스케이프할 필요는 없지만, 그래도 속성의 식별자를 얻기 위해 언이스케이프됩니다.
2.2. 인터페이스
IDL 프래그먼트는 객체 지향 시스템을
기술하는 데 사용됩니다. 이러한 시스템에서 객체란 정체성을 가지고 있으며, 상태와 행동을 캡슐화한 엔티티입니다.
인터페이스는
(
[extended_attributes ]interface identifier { /* interface_members... */ };
인터페이스는
인터페이스 멤버
(
웹 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가 상속하는 인터페이스 B와 B의 상속 인터페이스들이 포함됩니다.
인터페이스의 상속 계층에 순환(cycle)이 있어서는 안 됩니다. 즉, 인터페이스 A가 자기 자신을 상속하거나, B에서 A를 상속하는 등 반복적으로 상속할 수 없습니다.
-
result를 « »로 둔다.
-
interface를 I로 둔다.
-
interface가 null이 아닐 동안:
-
result를 반환한다.
일반적인 인터페이스의 다중 상속은 지원하지 않으며, 객체도 임의의 인터페이스 집합을 구현할 수 없습니다. 객체는 하나의 주어진 인터페이스 A를 구현하도록 정의되며, 이는 A의 상속 인터페이스들도 구현함을 의미합니다. 추가로, includes 문을 사용하여 인터페이스 A를 구현하는 객체가 인터페이스 믹스인 멤버도 항상 포함하도록 정의할 수 있습니다. A가 include하는 인터페이스 믹스인의 멤버를 포함합니다.
각 인터페이스 멤버는 확장
속성 리스트(
[extended_attributes ]interface identifier { [extended_attributes ]const type constant_identifier = 42; [extended_attributes ]attribute type identifier ; [extended_attributes ]return_type identifier (/* arguments... */); };
인터페이스에 대한 IDL은
부분 인터페이스
정의(
interface SomeInterface { /* interface_members... */ };partial interface SomeInterface { /* interface_members... */ };
참고: 부분 인터페이스 정의는 명세 편집 시, 하나의 인터페이스 정의를 여러 문서 또는 여러 섹션에 나눠서 기술하는 데 도움을 주기 위한 것입니다.
인터페이스 정의와 그 부분 인터페이스 정의의 등장 순서는 중요하지 않습니다.
참고: 부분 인터페이스 정의는 인터페이스가 다른 인터페이스를 상속하도록 지정할 수 없습니다. 상속은 원래의 인터페이스 정의에서 지정해야 합니다.
적용되는 언어 바인딩이 인터페이스가 해당 언어의 구조와 어떻게 대응되는지 결정합니다.
다음 확장 속성들이 인터페이스에 적용될 수 있습니다:
[CrossOriginIsolated
],
[Exposed
],
[Global
],
[LegacyFactoryFunction
],
[LegacyNoInterfaceObject
],
[LegacyOverrideBuiltIns
],
[LegacyWindowAlias
],
[SecureContext
].
다음 확장 속성들은 부분
인터페이스에 적용될 수 있습니다:
[CrossOriginIsolated
],
[Exposed
],
[LegacyOverrideBuiltIns
],
[SecureContext
].
인터페이스는 반드시 [Exposed
] 확장 속성으로 주석
처리해야 합니다.
인터페이스 interface의 정규화된 이름은 다음과 같이 정의됩니다:
-
identifier를 interface의 식별자로 둔다.
-
interface에 [
LegacyNamespace
] 확장 속성이 있으면:-
namespace를 [
LegacyNamespace
] 확장 속성의 식별자 인자로 둔다. -
« namespace, identifier »를 U+002E (.)로 연결하여 반환한다.
-
-
identifier를 반환한다.
CallbackOrInterfaceOrMixin ::callback CallbackRestOrInterface interface InterfaceOrMixin
InterfaceOrMixin ::InterfaceRest MixinRest
InterfaceRest ::identifier Inheritance { InterfaceMembers } ;
Partial ::partial PartialDefinition
PartialDefinition ::interface PartialInterfaceOrPartialMixin PartialDictionary Namespace
PartialInterfaceOrPartialMixin ::PartialInterfaceRest MixinRest
PartialInterfaceRest ::identifier { PartialInterfaceMembers } ;
InterfaceMembers ::ExtendedAttributeList InterfaceMember InterfaceMembers ε
InterfaceMember ::PartialInterfaceMember Constructor
PartialInterfaceMembers ::ExtendedAttributeList PartialInterfaceMember PartialInterfaceMembers ε
PartialInterfaceMember ::Const Operation Stringifier StaticMember Iterable AsyncIterable ReadOnlyMember ReadWriteAttribute ReadWriteMaplike ReadWriteSetlike InheritAttribute
Inheritance ::: identifier ε
아래 IDL 프래그먼트는 상호
참조하는 두 인터페이스의 정의를 보여줍니다.
Human
과 Dog
는 모두 Animal
을 상속합니다.
이 두 인터페이스를 구현하는 객체는 name
속성을 갖게 됩니다.
[Exposed =Window ]interface Animal {attribute DOMString name ; }; [Exposed =Window ]interface Human :Animal {attribute Dog ?pet ; }; [Exposed =Window ]interface Dog :Animal {attribute Human ?owner ; };
아래 IDL 프래그먼트는 DOM 인터페이스와 콜백 인터페이스의 단순화된 정의를 보여줍니다.
[Exposed =Window ]interface Node {readonly attribute DOMString nodeName ;readonly attribute Node ?parentNode ;Node appendChild (Node newChild );undefined addEventListener (DOMString type ,EventListener listener ); };callback interface EventListener {undefined handleEvent (Event event ); };
일반 객체는 EventListener
와 같은 콜백 인터페이스를 구현할 수 있습니다:
var node= getNode(); // Node 인스턴스 얻기 var listener= { handleEvent: function ( event) { // ... } }; node. addEventListener( "click" , listener); // 동작함 node. addEventListener( "click" , function () { ... }); // 이것도 동작함
이런 객체는 Node
와 같은 인터페이스를 구현할 수는 없습니다:
var node= getNode(); // Node 인스턴스 얻기 var newNode= { nodeName: "span" , parentNode: null , appendChild: function ( newchild) { // ... }, addEventListener: function ( type, listener) { // ... } }; node. appendChild( newNode); // TypeError 예외 발생
2.3. 인터페이스 믹스인
인터페이스 믹스인은
(
interface mixin identifier { /* mixin_members... */ };
참고: 인터페이스 믹스인은 부분 인터페이스와 마찬가지로, 명세 편집의 편의를 위해 사용되어 일관된 기능 집합을 묶고, 여러 인터페이스(문서 간 포함 가능)에 포함할 수 있게 합니다. 언어 바인딩을 통해 직접 노출되도록 의도된 것이 아닙니다. § 2.3.1 믹스인 및 부분 사용에서 부분 인터페이스, 인터페이스 믹스인, 부분 인터페이스 믹스인 중 어느 것을 선택할지 설명합니다.
인터페이스 믹스인은
인터페이스 믹스인 멤버
(
이러한 상수, 일반 연산, 일반 속성, 문자열 변환자는 해당 객체가 구현할 수 있는 동작을 기술하며, 마치 이를 인터페이스에 직접 명세한 것처럼 동작합니다.
정적 속성, 정적 연산, 특수 연산, 이터러블, 비동기 이터러블, maplike, setlike 선언은 인터페이스 믹스인 선언에 포함될 수 없습니다.
인터페이스와 마찬가지로, 인터페이스 믹스인의
IDL도 부분 인터페이스
믹스인 정의(
interface mixin SomeMixin { /* mixin_members... */ };partial interface mixin SomeMixin { /* mixin_members... */ };
멤버의 등장 순서는 자바스크립트 바인딩에서 프로퍼티 열거에 영향을 줍니다.
인터페이스나 딕셔너리와 달리, 인터페이스 믹스인은 타입을 생성하지 않습니다.
이 명세에서 정의된 확장 속성 중,
[CrossOriginIsolated
],
[Exposed
], [SecureContext
]
만 인터페이스 믹스인에 적용됩니다.
includes 문은
(
interface_identifier includes mixin_identifier ;
첫 번째 식별자는 인터페이스 I를 참조해야 하며, 두 번째 식별자는 인터페이스 믹스인 M을 참조해야 합니다.
M의 각 멤버는 인터페이스 I, J, K 등 include하는 모든 인터페이스의 멤버로 간주됩니다. 즉, 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
Partial ::partial PartialDefinition
MixinRest ::mixin identifier { MixinMembers } ;
MixinMembers ::ExtendedAttributeList MixinMember MixinMembers ε
MixinMember ::Const RegularOperation Stringifier OptionalReadOnly AttributeRest
IncludesStatement ::identifier includes identifier ;
2.3.1. 믹스인 및 부분 사용
이 섹션은 참고용입니다.
인터페이스 믹스인은 속성, 상수, 연산을 여러 인터페이스에 공유할 수 있게 해줍니다. 만약 하나의 인터페이스만 확장하려는 경우라면 부분 인터페이스 사용을 고려할 수 있습니다.
예를 들면, 다음과 같이 하지 말고:
interface mixin WindowSessionStorage {readonly attribute Storage sessionStorage ; };Window includes WindowSessionStorage ;
이렇게 하세요:
partial interface Window {readonly attribute Storage sessionStorage ; };
또한, 다른 명세에서 노출하는 인터페이스 믹스인을 확장하여 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 { /* interface_members... */ };
참고: 유사한 명칭의 콜백 함수 정의도 참고하세요.
콜백 인터페이스는 정확히 하나의 일반 연산을 정의해야 합니다.
명세 저자는 콜백 인터페이스를 기존 API의 요구사항을 기술할 필요가 없는 한 정의하지 않아야 합니다. 대신 콜백 함수를 사용하는 것이 좋습니다.
EventListener
를 콜백
인터페이스로 정의한 것은,
특정 속성(여기서는 handleEvent
)을 가진 객체가 해당 인터페이스를 구현한 것으로 간주될 수 있도록 해야 하는 기존 API의 예입니다.
새로운 API나 호환성 문제가 없는 경우에는,
콜백 함수를
사용하면
자바스크립트 바인딩에서 함수 객체만 허용됩니다.
콜백 인터페이스가 상수를 선언하는 경우 반드시 [Exposed
] 확장 속성으로 주석
처리해야 합니다.
CallbackRestOrInterface ::CallbackRest interface identifier { CallbackInterfaceMembers } ;
CallbackInterfaceMembers ::ExtendedAttributeList CallbackInterfaceMember CallbackInterfaceMembers ε
CallbackInterfaceMember ::Const RegularOperation
2.5. 멤버
인터페이스, 인터페이스 믹스인, 네임스페이스는
중괄호 안에 등장하는 멤버(각각
어떤 인터페이스가 인터페이스 믹스인을 include하면, 해당 인터페이스 믹스인의 멤버들도 인터페이스의 멤버로 간주됩니다. 반면, 상속받은 인터페이스 멤버는 해당 인터페이스의 멤버로 간주하지 않습니다.
여러 멤버에 대해 정의되는 생성자 단계, getter 단계, setter 단계, 메서드 단계는 해당 인터페이스 또는 인터페이스 믹스인 위에 정의된 멤버에서 this 값을 사용할 수 있습니다. 이는 멤버가 선언된 인터페이스 타입, 혹은 멤버가 선언된 인터페이스 믹스인을 include한 타입의 IDL 값입니다.
setter 단계에서는 지정된 값도 사용할 수 있는데, 이는 해당 속성이 선언된 타입의 IDL 값입니다.
인터페이스, 인터페이스 믹스인, 콜백 인터페이스, 네임스페이스는 각각 지원하는 멤버의 종류가 다르며, § 2.2 인터페이스, § 2.3 인터페이스 믹스인, § 2.4 콜백 인터페이스, § 2.6 네임스페이스에서 설명합니다. 아래 표는 이를 요약한 참고용 표입니다:
인터페이스 | 콜백 인터페이스 | 인터페이스 믹스인 | 네임스페이스 | |
---|---|---|---|---|
상수 | ● | ● | ● | |
일반 속성 | ● | ● | 오직 읽기 전용 속성만 | |
정적 속성 | ● | |||
일반 연산 | ● | ● | ● | ● |
문자열 변환자 | ● | ● | ||
특수 연산 | ● | |||
정적 연산 | ● | |||
이터러블 선언 | ● | |||
비동기 이터러블 선언 | ● | |||
maplike 선언 | ● | |||
setlike 선언 | ● |
2.5.1. 상수
상수는
(
상수는 과거에 주로 열거형 스타일로 명명된 정수 코드를 정의하는 데 사용되었습니다. 웹 플랫폼은 문자열 사용으로 이 패턴에서 벗어나고 있습니다. 이 기능을 사용하려는 편집자는 진행하기 전에 이슈를 등록하여 논의할 것을 강력히 권고합니다.
const type constant_identifier = 42;
상수의 식별자는 동일한 인터페이스 멤버 또는 콜백 인터페이스 멤버의 식별자와 같아서는 안
됩니다(동일한 인터페이스나 콜백 인터페이스에
정의된).
또한 "length
", "name
", "prototype
"이어서는 안 됩니다.
참고: 이 세 이름은 자바스크립트 바인딩에서 인터페이스 객체에 정의된 프로퍼티 이름입니다.
상수의 타입(
상수 선언의
참고: 이 값들은(문자열, 빈 시퀀스 포함) 딕셔너리 멤버의 기본값이나 옵션 인자
기본값으로도 사용할 수 있습니다.
단, 문자열, 빈 시퀀스
불리언 리터럴 토큰 boolean
타입의
true
와 false
입니다.
-
S를 자바스크립트
NumericLiteral 로 파싱했을 때의 수학적 값을 result로 둡니다. -
해당 토큰이
float
또는unrestricted float
의 값으로 사용되면, result에 가장 가까운 IEEE 754 단정밀도 부동소수점 숫자가 값입니다. -
그 외에는
double
또는unrestricted double
의 값으로 사용되며, result에 가장 가까운 IEEE 754 배정밀도 부동소수점 숫자가 값입니다. [IEEE-754]
상수값이
- 타입
unrestricted float
, 상수값Infinity -
값은 IEEE 754 단정밀도 양의 무한대입니다.
- 타입
unrestricted double
, 상수값Infinity -
값은 IEEE 754 배정밀도 양의 무한대입니다.
- 타입
unrestricted float
, 상수값-Infinity -
값은 IEEE 754 단정밀도 음의 무한대입니다.
- 타입
unrestricted double
, 상수값-Infinity -
값은 IEEE 754 배정밀도 음의 무한대입니다.
- 타입
unrestricted float
, 상수값NaN -
값은 비트 패턴 0x7fc00000의 IEEE 754 단정밀도 NaN입니다.
- 타입
unrestricted double
, 상수값NaN -
값은 비트 패턴 0x7ff8000000000000의 IEEE 754 배정밀도 NaN입니다.
float
나 double
타입의
값으로 사용할 수 없습니다.
상수에 할당된 값의 타입 VT와 상수, 딕셔너리 멤버, 옵션 인자 자체의 타입 DT는 호환되어야 하며, DT와 VT가 동일하거나, 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. 속성
속성은 인터페이스 멤버 또는
네임스페이스 멤버로,
(
-
일반 속성은 해당 인터페이스를 구현하는 객체가 지정된 식별자의 데이터 필드 멤버를 갖도록 선언합니다.
interface interface_identifier {attribute type identifier ; }; -
정적 속성은 인터페이스를 구현하는 특정 객체와 관련되지 않은 속성을 선언할 때 사용합니다.
interface interface_identifier {static attribute type identifier ; };
속성에
속성 attr의 getter
단계는 “attr
getter 단계는 다음과 같다:”(목록) 또는 “attr
getter
단계는 다음을 수행한다”(인라인 설명)와 같은 텍스트로 소개해야 합니다.
속성 attr의 setter
단계는 “attr
setter 단계는 다음과 같다:”(목록) 또는 “attr
setter
단계는 다음을 수행한다”(인라인 설명)와 같은 텍스트로 소개해야 합니다.
참고: getter 단계를 정의할 때는 this에 암묵적으로 접근할 수 있습니다. setter 단계를 정의할 때는 this와 지정된 값에 암묵적으로 접근할 수 있습니다.
속성의 식별자는 동일한 인터페이스에 정의된 다른 인터페이스 멤버의 식별자와 같아서는 안 됩니다.
정적 속성의 식별자는 "prototype
"이면 안 됩니다.
속성의 타입은
타입 정의를 해석한 후, 속성의 타입은 다음 타입의 널 허용 또는 비허용 버전이 되어서는 안 됩니다:
-
유니온 타입에 널 허용 또는 비허용 시퀀스 타입, 딕셔너리, 레코드가 평탄화된 멤버 타입 중 하나로 포함된 경우
속성은 읽기 전용이며,
interface interface_identifier {readonly attribute type identifier ; };
타입이 프라미스 타입인 속성은 반드시 읽기 전용이어야 하며, 또한 [LegacyLenientSetter
],
[PutForwards
],
[Replaceable
],
[SameObject
]
확장 속성을 가질 수 없습니다.
읽기 전용이 아닌 일반 속성은 상위
인터페이스에서 getter를 상속받도록 선언할 수 있습니다. 이를 통해 상위 인터페이스의 읽기 전용 속성을 파생 인터페이스에서 쓰기 가능하게 만들 수 있습니다.
속성이 getter를 상속하려면 선언에
참고: 문법상
[Exposed =Window ]interface Ancestor {readonly attribute TheType theIdentifier ; }; [Exposed =Window ]interface Derived :Ancestor {inherit attribute TheType theIdentifier ; };
interface interface_identifier {stringifier attribute DOMString identifier ; };
다음 확장 속성은 일반
및 정적 속성에 적용 가능합니다:
[CrossOriginIsolated
],
[Exposed
],
[SameObject
],
[SecureContext
].
다음 확장 속성은 일반
속성에만 적용됩니다:
[LegacyLenientSetter
],
[LegacyLenientThis
],
[PutForwards
],
[Replaceable
],
[LegacyUnforgeable
].
ReadOnlyMember ::readonly ReadOnlyMemberRest
ReadOnlyMemberRest ::AttributeRest MaplikeRest SetlikeRest
ReadWriteAttribute ::AttributeRest
InheritAttribute ::inherit AttributeRest
AttributeRest ::attribute TypeWithExtendedAttributes AttributeName ;
AttributeName ::AttributeNameKeyword identifier
AttributeNameKeyword ::required
OptionalReadOnly ::readonly ε
아래 IDL 프래그먼트는 인터페이스에 속성을 선언하는 방법을 보여줍니다:
[Exposed =Window ]interface Animal { // 임의의 문자열 값으로 설정 가능한 단순 속성.readonly attribute DOMString name ; // 값을 할당할 수 있는 속성.attribute unsigned short age ; }; [Exposed =Window ]interface Person :Animal { // Animal에서 getter 동작을 상속받으며, Person 설명에서 별도 명시 필요 없음.inherit attribute DOMString name ; };
2.5.3. 연산
연산은 인터페이스 멤버,
콜백 인터페이스
멤버, 네임스페이스
멤버
(
-
일반 연산은 해당 인터페이스를 구현하는 객체가 지정된 식별자의 메서드를 갖도록 선언합니다.
interface interface_identifier {return_type identifier (/* arguments... */); }; -
특수 연산은 객체 인덱싱, 문자열 변환 등 특별한 동작을 구현하는 객체에 선언할 때 사용합니다.
interface interface_identifier { /* special_keyword */return_type identifier (/* arguments... */); /* special_keyword */return_type (/* arguments... */); }; -
정적 연산은 인터페이스를 구현하는 특정 객체와 관련되지 않은 연산을 선언할 때 사용합니다.
interface interface_identifier {static return_type identifier (/* arguments... */); };
연산에 식별자가 있고
연산에 식별자가 없으면 반드시 특수 키워드를 사용하여 특수 연산으로 선언해야 합니다.
일반 연산 또는 정적 연산의 식별자는 동일한
인터페이스, 콜백 인터페이스,
네임스페이스에 정의된 상수나 속성의 식별자와 같아서는 안 됩니다.
정적 연산의 식별자는 "prototype
"이면 안 됩니다.
참고: 연산의 식별자는 동일 인터페이스의 다른 연산과 같을 수 있습니다. 이는 연산 오버로딩을 명세하는 방식입니다.
참고: 정적 연산의 식별자는 동일 인터페이스에 정의된 일반 연산의 식별자와 같을 수 있습니다.
연산의 반환 타입은 연산 선언에서 식별자
앞에 등장하는 타입(
연산의 인자(
참고: 표현력을 위해, 연산 인자의 식별자는
연산 인자의
인자 타입을 타입 정의 해석 후, 널 허용 타입(nullable type)이면, 그 내부 타입은 딕셔너리 타입일 수 없습니다.
interface interface_identifier {return_type identifier (type identifier ,type identifier /* , ... */); };
각 인자의 식별자는 동일 연산 선언 내의 다른 인자 식별자와 같아서는 안 됩니다.
각 인자는 확장 속성
리스트(
interface interface_identifier {return_type identifier ([extended_attributes ]type identifier , [extended_attributes ]type identifier /* , ... */); };
아래 IDL 프래그먼트는 인터페이스에 일반 연산을 선언하는 방법을 보여줍니다:
[Exposed =Window ]interface Dimensions {attribute unsigned long width ;attribute unsigned long height ; }; [Exposed =Window ]interface Button { // 인자를 받지 않고 불리언을 반환하는 연산.boolean 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'에 해당하는 인자를 세 개 넘김
가변 인자 함수를 지원하지 않는 언어 바인딩에서는 명시적으로 배열이나 리스트를 인자로 넘기도록 명세할 수 있습니다.
인자에
interface interface_identifier {return_type identifier (type identifier ,optional type identifier ); };
옵션 인자는 기본값도 가질 수 있습니다. 인자 식별자 뒤에 U+003D(=)와 값(
interface interface_identifier {return_type identifier (type identifier ,optional type identifier = "value"); };
boolean
타입의 옵션 인자에
인자 타입이 딕셔너리 타입 또는 유니온 타입이며, 해당 딕셔너리 타입 및 조상에 필수 멤버가 없고, 인자가 마지막이거나 뒤따르는 인자들이 모두 옵션 인자라면, 해당 인자는 옵션으로 선언되고 기본값을 지정해야 합니다.
이는 API 설계시 사용자가 딕셔너리의 기본값만 사용하고 싶을 때 빈 딕셔너리 값을 굳이 넘기지 않아도 되도록 하기 위함입니다.
대개 기본값으로
불리언 리터럴 토큰(
undefined
입니다.
옵션 인자의 타입이 열거형이면, 지정된 기본값은 반드시 해당 열거형 값 중 하나여야 합니다.
옵션 인자 기본값으로 두 토큰 값
옵션 인자 기본값으로 두 토큰 값
아래 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
딕셔너리가 되며,
caseSensitive
는
연산에 적용 가능한 확장 속성은 다음과 같습니다:
[CrossOriginIsolated
],
[Default
],
[Exposed
],
[LegacyUnforgeable
],
[NewObject
],
[SecureContext
].
연산 operation의 메서드
단계는 “operation(arg1, arg2, ...)
메서드 단계는 다음과 같다:”(목록)
또는 “operation(arg1,
arg2, ...)
메서드 단계는 다음을 수행한다”(인라인 설명)와 같은 텍스트로 소개해야 합니다.
참고: 메서드 단계를 정의할 때는 this에 암묵적으로 접근할 수 있습니다.
DefaultValue ::ConstValue string [ ] { } null undefined
Operation ::RegularOperation SpecialOperation
RegularOperation ::Type OperationRest
SpecialOperation ::Special RegularOperation
Special ::getter setter deleter
OperationRest ::OptionalOperationName ( ArgumentList ) ;
OptionalOperationName ::OperationName ε
OperationName ::OperationNameKeyword identifier
OperationNameKeyword ::includes
ArgumentList ::Argument Arguments ε
Arguments ::, Argument Arguments ε
Argument ::ExtendedAttributeList ArgumentRest
ArgumentRest ::optional TypeWithExtendedAttributes ArgumentName Default Type Ellipsis ArgumentName
ArgumentName ::ArgumentNameKeyword identifier
Ellipsis ::... ε
ArgumentNameKeyword ::attribute callback const constructor deleter dictionary enum getter includes inherit interface iterable maplike mixin namespace partial readonly required setlike setter static stringifier typedef unrestricted
2.5.3.1. toJSON
toJSON
일반 연산을 선언함으로써,
인터페이스는 해당 인터페이스를 구현하는 객체를 JSON 타입으로 변환하는 방법을 명세합니다.
toJSON
일반 연산은 이러한 용도를 위해 예약되어 있습니다.
반드시 인자를 받지 않아야 하며, JSON 타입을
반환해야 합니다.
JSON 타입은 다음과 같습니다:
-
인터페이스 타입 (자신이나 상속받은 인터페이스에
toJSON
연산이 선언된 경우),
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()
메서드 단계는 다음과 같다:
-
json을 새 맵으로둡니다.
-
각 속성 identifier attr에 대해 «"from", "to", "amount", "description"»:
-
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. 생성자 연산
인터페이스에 생성자 연산 멤버(
하나의 인터페이스에는 여러 개의 생성자 연산이 있을 수 있습니다. 각각의 생성자 연산에 대해, 지정된 인자를 넘겨 인스턴스를 생성할 방법이 제공됩니다.
생성자 연산이 인터페이스
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 ) ;
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)을 갖는다는 의미입니다. 문자열 변환자는
interface interface_identifier {stringifier ; };
인터페이스와 함께 설명되는 프로즈(prose)에서는 해당 인터페이스의 문자열 변환 동작을 정의해야 합니다.
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 ; };
따라서 문자열 변환 동작을 설명하는 프로즈가 필요합니다.
familyName
과 givenName
속성은 각각 성과 이름 개념을 나타낸다고 가정합니다.
문자열 변환 동작 단계는 다음과 같다:
이 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 | 객체가 프로퍼티 조회를 위해 인덱싱될 때 동작을 정의합니다. | |
Setter | 객체가 프로퍼티 할당 또는 생성 시 인덱싱될 때 동작을 정의합니다. | |
Deleter | 객체가 프로퍼티 삭제를 위해 인덱싱될 때 동작을 정의합니다. |
모든 언어 바인딩이 네 가지 종류의 특수 객체 동작을 모두 지원하는 것은 아닙니다. 특수 연산이 식별자 없이 선언된 경우, 해당 종류의 특수 연산을 지원하지 않는 언어 바인딩에서는 해당 기능이 제공되지 않습니다.
아래 IDL 프래그먼트는 getter와 setter가 있는 인터페이스를 정의합니다:
[Exposed =Window ]interface Dictionary {readonly attribute unsigned long propertyCount ;getter double (DOMString propertyName );setter undefined (DOMString propertyName ,double propertyValue ); };
프로퍼티 getter와 setter를 지원하지 않는 언어 바인딩에서는, Dictionary를 구현하는 객체가 해당 특별 동작을 갖지 않습니다.
특수 연산을 식별자를 사용해 정의하는 것은, 해당 특수 연산을 식별자 없이 별도의 선언으로 분리하는 것과 동등합니다. 이 방식은 인터페이스 연산의 메서드 단계를 단순화하기 위해 허용됩니다.
다음 두 인터페이스는 동등합니다:
[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가 연산에 식별자를 써서 지정된 경우, 객체를 지원되는 프로퍼티 인덱스로 인덱싱하면 해당 인덱스를 유일 인자로 넘겨 연산을 호출한 결과값이 반환된다. 만약 인덱스 프로퍼티 getter 선언에 식별자가 없다면, 인터페이스 정의에 주어진 인덱스에 대해 인덱스 프로퍼티 값 결정 방법을 기술해야 한다.
-
인덱스 프로퍼티 setter가 연산에 식별자를 써서 지정된 경우, 객체를 지원되는 프로퍼티 인덱스와 값으로 프로퍼티 할당/생성을 위해 인덱싱하면, 인덱스를 첫 번째 인자, 값을 두 번째 인자로 넘겨 연산을 호출한 것과 동일하게 동작한다. 만약 인덱스 프로퍼티 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()
연산이 존재하지 않는
항목을 조회할 때
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가 연산에 식별자를 써서 지정된 경우, 객체를 지원되는 프로퍼티 이름으로 인덱싱하면 해당 이름을 유일 인자로 넘겨 연산을 호출한 결과값이 반환된다. 만약 이름 프로퍼티 getter 선언에 식별자가 없다면, 인터페이스 정의에 주어진 이름에 대해 이름 프로퍼티 값 결정 방법을 기술해야 한다.
-
이름 프로퍼티 setter가 연산에 식별자를 써서 지정된 경우, 객체를 지원되는 프로퍼티 이름과 값으로 프로퍼티 할당/생성을 위해 인덱싱하면, 이름을 첫 번째 인자, 값을 두 번째 인자로 넘겨 연산을 호출한 것과 동일하게 동작한다. 만약 이름 프로퍼티 setter 선언에 식별자가 없다면, 인터페이스 정의에 기존 이름 프로퍼티 값 설정(기존 이름 프로퍼티 값 설정)과 새 이름 프로퍼티 값 설정(새 이름 프로퍼티 값 설정) 방법을 기술해야 한다.
-
이름 프로퍼티 deleter가 연산에 식별자를 써서 지정된 경우, 객체를 지원되는 프로퍼티 이름으로 삭제 인덱싱하면, 이름을 유일 인자로 넘겨 연산을 호출한 것과 동일하게 동작한다. 만약 이름 프로퍼티 deleter 선언에 식별자가 없다면, 인터페이스 정의에 주어진 이름에 대해 기존 이름 프로퍼티 삭제 방법을 기술해야 한다.
참고: 인덱스 프로퍼티와 마찬가지로, 이름 프로퍼티 getter, setter 또는 deleter 가 연산에 식별자를 써서 지정된 경우, 객체를 지원되지 않는 이름으로 인덱싱할 때 해당 연산을 해당 이름으로 호출하는 것과 반드시 같은 동작을 하는 것은 아니며, 실제 동작은 언어 바인딩마다 다릅니다.
2.5.7. 정적 속성 및 연산
정적 속성 및
정적 연산
은 해당 인터페이스의 특정 인스턴스가 아니라
인터페이스 자체에 연결되는 속성/연산입니다. 정적 속성과 연산은 선언에
정적 연산을 호출하거나 정적 속성을 참조하는 것이 인터페이스 인스턴스에서 가능한지는 언어 바인딩마다 다릅니다.
StaticMember ::static StaticMemberRest
StaticMemberRest ::OptionalReadOnly AttributeRest RegularOperation
아래 IDL 프래그먼트는
Circle
인터페이스에 정적 연산이 선언된 예시입니다:
[Exposed =Window ]interface Point { /* ... */ }; [Exposed =Window ]interface Circle {attribute double cx ;attribute double cy ;attribute double radius ;static readonly attribute long triangulationCount ;static Point triangulate (Circle c1 ,Circle c2 ,Circle c3 ); };
자바스크립트 바인딩에서는 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. 오버로딩
인터페이스에 정의된 일반 연산 또는 정적 연산이 동일한 종류(일반 또는 정적)의 다른 연산과 동일한 식별자를 가지면, 해당 연산은 오버로딩된 연산이라 한다. 오버로딩된 연산의 식별자가 인터페이스를 구현하는 객체에서 호출될 때, 전달된 인자의 개수와 타입에 따라 실제로 어떤 오버로딩된 연산이 호출되는지가 결정된다. 생성자 연산도 오버로딩될 수 있다. 오버로딩된 연산과 생성자가 받을 수 있는 인자에는 몇 가지 제한이 있으며, 이를 설명하기 위해 유효 오버로드 집합이라는 개념을 사용한다.
오버로딩된 연산 집합은 다음 중 하나를 만족해야 한다:
연산은 인터페이스, 부분 인터페이스, 인터페이스 믹스인, 부분 인터페이스 믹스인 정의를 넘나들어 오버로딩될 수 없다.
예를 들어, 아래의 f와 g에 대한 오버로딩은 허용되지 않는다:
[Exposed =Window ]interface A {undefined f (); };partial interface A {undefined f (double x );undefined g (); };partial interface A {undefined g (DOMString x ); };
참고로 생성자 연산과
[LegacyFactoryFunction
]
확장 속성은
부분 인터페이스 정의에는 등장할 수 없으므로,
생성자 오버로딩을 추가로 금지할 필요는 없다.
유효 오버로드 집합은
특정 연산,
생성자(생성자 연산
또는 [LegacyFactoryFunction
]),
또는 콜백 함수에 대해
허용되는 호출을 나타낸다.
유효 오버로드 집합 계산 알고리즘은 다음 네 가지 IDL 구조에 대해 동작하며, 각 구조마다
필요한 입력이 있다:
- 일반 연산의 경우
- 정적 연산의 경우
- 생성자의 경우
-
-
생성자 연산이 정의된 인터페이스
-
전달할 인자의 개수
-
- 레거시 팩토리 함수의 경우
-
-
[
LegacyFactoryFunction
] 확장 속성이 정의된 인터페이스 -
레거시 팩토리 함수의 식별자
-
전달할 인자의 개수
-
유효 오버로드 집합은 인터페이스에 지정된 오버로딩 연산과 생성자에 모호함이 있는지 판별하는 데 사용된다.
아이템들은 유효 오버로드 집합의 튜플로, (호출 객체, 타입 리스트, 옵셔널리티 리스트) 형태를 가진다. 아래에 각 아이템 설명:
-
호출 객체는 유효 오버로드 집합이 일반 연산, 정적 연산 또는 생성자 연산일 때 연산이고, 유효 오버로드 집합이 레거시 팩토리 함수일 때는 확장 속성이다.
-
타입 리스트는 IDL 타입들의 리스트이다.
-
옵셔널리티 리스트는 "required", "optional", "variadic" 중 하나의 옵셔널리티 값을 인덱스별로 가지는 리스트이다. 해당 인자가 옵션 인자인지, 가변 인자인지를 표시한다.
각 튜플은 해당 타입의 인자값 리스트로 연산, 생성자, 콜백 함수를 호출할 수 있음을 의미한다. 옵션 인자 및 가변 인자 연산/생성자 덕분에, 동일한 연산이나 생성자로 식별되는 유효 오버로드 집합 아이템이 여러 개 있을 수 있다.
-
연산 또는 레거시 팩토리 함수의 식별자는 A
-
인자 개수는 N
-
인터페이스는 I
확장 속성의 인자란, 확장 속성의 명명된 인자 리스트의 인자를 의미한다.
-
S를 순서 있는 집합으로 둔다.
-
F를 순서 있는 집합으로 둔다. 아이템은 유효 오버로드 집합 종류에 따라 다음과 같다:
- 일반 연산의 경우
-
F의 요소는 인터페이스 I에 정의된 A 식별자의 일반 연산이다.
- 정적 연산의 경우
-
F의 요소는 인터페이스 I에 정의된 A 식별자의 정적 연산이다.
- 생성자의 경우
-
F의 요소는 인터페이스 I의 생성자 연산이다.
- 레거시 팩토리 함수의 경우
-
F의 요소는 인터페이스 I에 정의된 [
LegacyFactoryFunction
] 확장 속성 중 명명된 인자 리스트의 식별자가 A인 것들이다.
-
maxarg를 F의 연산, 레거시 팩토리 함수, 콜백 함수에서 선언된 최대 인자 개수로 둔다. 가변 인자 연산 및 레거시 팩토리 함수에서, ...이 붙은 인자는 1개로 센다.
참고:
undefined f(long x, long... y);
는 인자 2개로 간주된다. -
max를 max(maxarg, N)로 둔다.
-
각 F의 연산 또는 확장 속성 X에 대해:
-
arguments를 X에 선언된 인자들의 리스트로 둔다.
-
n을 arguments의 크기로 둔다.
-
types를 타입 리스트로 둔다.
-
optionalityValues를 옵셔널리티 리스트로 둔다.
-
각 arguments의 argument에 대해:
-
types에 argument의 타입을 추가한다.
-
optionalityValues에, argument가 마지막 가변 인자면 "variadic", 옵션 인자면 "optional", 그 외는 "required"를 추가한다.
-
-
S에 (X, types, optionalityValues) 튜플을 추가한다.
-
X가 가변 인자로 선언되었다면:
-
i를 n−1로 둔다.
-
i ≥ 0인 동안:
-
-
S를 반환한다.
다음 인터페이스에 대해:
[Exposed =Window ]interface A { /* f1 */undefined f (DOMString a ); /* f2 */undefined f (Node a ,DOMString b ,double ...c ); /* f3 */undefined f (); /* f4 */undefined f (Event a ,DOMString b ,optional DOMString c ,double ...d ); };
Node
와 Event
가 서로 다른 인터페이스이며, 어떤 객체도 둘 다를 구현할 수 없다면,
식별자 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를 반환하는 경우이다.
-
한 타입이 널 허용 타입을 포함하고, 다른 타입이 널 허용 타입을 포함하거나, 유니온 타입이며 평탄화된 멤버 타입에 딕셔너리 타입이 포함되거나, 딕셔너리 타입이면, false를 반환한다.
-
두 타입 모두 유니온 타입 또는 널 허용 유니온 타입이면, 각 멤버 타입이 서로 구별 가능하면 true, 아니면 false를 반환한다.
-
한 타입이 유니온 타입 또는 널 허용 유니온 타입이면, 유니온 타입의 각 멤버 타입이 비유니온 타입과 구별 가능하면 true, 아니면 false를 반환한다.
-
각 타입의 내부 타입(주석 타입이면)과 내부 타입(그 결과가 널 허용 타입이면)을 취한 "가장 안쪽" 타입을 고려한다. 이 두 타입이 아래 표의 카테고리에 속하고, 해당 교차점에 ● 또는 지정된 조건(a, b, c, d)이 만족되면 true, 아니면 false를 반환한다.
카테고리:
- interface-like
- dictionary-like
- sequence-like
undefinedbooleannumeric typesbigintstring typesobjectsymbolinterface-likecallback functiondictionary-likeasync sequencesequence-likeundefined ● ● ● ● ● ● ● ● ● ● boolean ● ● ● ● ● ● ● ● ● ● numeric types (b) ● ● ● ● ● ● ● ● bigint ● ● ● ● ● ● ● ● string types ● ● ● ● ● (d) ● object ● symbol ● ● ● ● ● interface-like (a) ● ● ● ● callback function (c) ● ● dictionary-like ● ● ● async sequence sequence-like -
식별된 두 interface-like 타입이 서로 다르고, 어떤 플랫폼 객체도 두 타입을 모두 구현하지 않는다.
-
타입이 구별 가능하지만, 오버로딩에서 사용에 별도의 제한이 있다. 또한 이 타입의 유니온 사용에 관한 조언도 참고할 것.
-
[
LegacyTreatNonObjectAsNull
] 확장 속성이 없는 콜백 함수는 dictionary-like 카테고리 타입과 구별 가능하다. -
타입이 구별 가능하지만, ECMAScript 값 변환 시 문자열 객체는 비동기 시퀀스 타입으로 변환되지 않는다(해당 타입의 오버로드나 유니온이 있으면).
다음과 같을 때:callback interface CBIface {undefined handle (); }; [Exposed =Window ]interface Iface {attribute DOMString attr2 ; };dictionary Dict {DOMString field1 ; };CBIface
는Iface
와는 구별 가능하다(딕셔너리-like와 인터페이스-like 교차점에 ●이 있음). 하지만Dict
와는 구별 불가능하다(딕셔너리-like 교차점에 ● 없음).프라미스 타입은 위 표에 없으므로, 어떤 다른 타입과도 구별 불가능하다.
하나의 항목 이상이 주어진 효과적 오버로드 집합에 있고, 해당 항목들이 같은 타입 리스트 크기를 가진 경우, 그러한 항목들에 대해 어떤 인덱스 i가 존재해야 하며, 각 항목 쌍에 대해 인덱스 i의 타입들이 구별 가능해야 합니다. 이러한 최소 인덱스를 해당 타입 리스트 크기를 가진 효과적 오버로드 집합의 항목에 대한 구별 인자 인덱스라고 합니다.
하나의 효과적 오버로드 집합에는
같은 항목이
동일한 타입 리스트 크기를 가질 때,
하나의
항목이
bigint
인자를
구별 인자 인덱스에서 가지며, 다른 항목이 숫자 타입
인자를 동일한 구별 인자 인덱스에서 갖는 경우가 둘 이상 존재해서는 안 됩니다.
앞 예시의 유효 오버로드 집합을 생각해보자.
type list가 2, 3, 4인 아이템이 여러 개 있다.
각 type list 크기별로 구별 인자 인덱스는 0이다. Node
와
Event
가 구별 가능이기 때문이다.
아래와 같은 오버로딩은 허용되지 않는다:
[Exposed =Window ]interface B {undefined f (DOMString x );undefined f (USVString x ); };
또한, 어떤 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이다. Node
와
DOMString
이 구별 가능이기
때문이다.
그러나 이 두 오버로드의 0번째 인자 타입이 다르므로, 오버로딩은 허용되지 않는다.
2.5.8.1. 오버로딩 vs. 유니온 타입
이 섹션은 참고용입니다.
IDL 연산을 정의하는 명세에서, 오버로딩과 유니온 타입, 옵션 인자 조합이 기능적으로 겹치는 부분이 있어 보일 수 있습니다.
먼저 오버로딩은 유니온 타입이나 옵션 인자와는
동작이 다르며, 하나로 완전히 대체할 수 없다(물론 추가적인 프로즈가 있으면 가능하지만, 이는 Web IDL 타입 시스템의 목적에 어긋난다). 예를 들어 stroke()
연산이 CanvasDrawPath
인터페이스에 정의되어 있다고 하자 [HTML]:
interface CanvasDrawPathExcerpt {undefined stroke ();undefined stroke (Path2D path ); };
자바스크립트 바인딩에서는, stroke(undefined)
를 호출하면 두 번째 오버로드가 선택되며, TypeError
가 발생한다. Path2D
로
변환될 수 없기 때문이다.
하지만 연산이 옵션
인자로 하나로 합쳐진다면,
interface CanvasDrawPathExcerptOptional {undefined stroke (optional Path2D path ); };
오버로드 결정 알고리즘은 path 인자를 누락된 것으로 처리하고 예외를 발생시키지 않습니다.
참고: 이 예시에서 후자의 동작이 실제로 Web 개발자가 기대하는 것입니다. CanvasDrawPath
를 새로 설계한다면 옵션
인자로 stroke()
를 정의할 것입니다.
또한 의미적 차이도 있습니다. 유니온 타입은 "어떤 타입이든 동작이 대체로 같다"는 의미로 주로 쓰이고, 오버로딩된 연산은 C++ 등 언어의 오버로딩과 잘 대응되는 구조로, 인자 타입에 따라 동작이 크게 달라지는 경우에 더 적합합니다. 하지만 이런 경우 대부분은 혼동을 피하기 위해 연산 이름을 다르게 하는 것이 좋으며, 자바스크립트는 언어 차원의 오버로딩을 제공하지 않으므로 새로운 API에는 오버로딩은 거의 적합하지 않고, 레거시 API나 특수한 경우에만 사용됩니다.
그래도 어떤 IDL 기능을 사용할지 어려울 때 아래와 같은 권고와 예시를 참고하세요:
-
인자 타입별로 반환 타입이 다를 필요가 있는 특이한 경우에는 오버로딩이 더 표현력이 좋습니다. 이런 API 설계는 거의 바람직하지 않으며, 보통 이름이 다른 연산으로 분리하는 것이 더 낫습니다.
예를 들어
calculate()
가long
,DOMString
,CalculatableInterface
(인터페이스 타입) 중 하나를 받아, 인자 타입과 동일한 타입의 값을 반환한다면, 아래처럼 오버로딩이 더 명확하다:interface A {long calculate (long input );DOMString calculate (DOMString input );CalculatableInterface calculate (CalculatableInterface input ); };아래처럼 유니온 타입과 타입 정의를 쓰면, 반환값이 항상 input 타입과 같다는 사실이 명확히 드러나지 않는다:
typedef (long or DOMString or CalculatableInterface )Calculatable ;interface A {Calculatable calculate (Calculatable input ); };새 API라면, 오버로딩 대신 아래처럼 이름을 구체적으로 나누는 것이 더 좋습니다:
interface A {long calculateNumber (long input );DOMString calculateString (DOMString input );CalculatableInterface calculateCalculatableInterface (CalculatableInterface input ); };이렇게 하면 Web 개발자가 명확하고 혼동 없는 코드를 작성할 수 있습니다.
-
인자 타입이나 개수에 따라 의미적으로 동작이 크게 달라지면 오버로딩을 선호합니다. 단, 이 경우도 보통 이름을 분리하는 것이 좋고, 레거시 API에서 이런 패턴이 종종 보입니다.
예를 들어
supports(property, value)
와supports(conditionText)
는CSS
인터페이스에 아래처럼 정의됨 [CSS3-CONDITIONAL] [CSSOM]:partial interface CSS {static boolean supports (CSSOMString property ,CSSOMString value );static boolean supports (CSSOMString conditionText ); };옵션 인자로 IDL을 아래처럼 쓸 수도 있지만,
partial interface CSSExcerptOptional {static boolean supports (CSSOMString propertyOrConditionText ,optional CSSOMString value ); };두 버전을 비교하면, 두 개념이 첫 번째 인자에 혼합되어 있어 구분이 어렵습니다. 오버로딩을 쓰면 property가 value와 짝을 이루는지, conditionText인지 명확하게 구분할 수 있으며, 메서드 단계도 각각 독립적으로 작성할 수 있습니다.
supports(property, value)
메서드 단계:-
…
supports(conditionText)
메서드 단계:-
…
옵션 인자를 쓸 경우, 아래처럼 더 많은 반복적 설명이 필요함:
supports(propertyOrConditionText, value)
메서드 단계:-
value가 있으면:
-
property를 propertyOrConditionText로 둔다.
-
…
-
-
없으면:
-
conditionText를 propertyOrConditionText로 둔다.
-
…
-
두 오버로드가 공통분모가 거의 없다면, 오버로드 결정은 IDL에 맡기는 것이 더 낫습니다.
-
-
여러 인자에 대해 타입 조합이 자유로운 경우에는 유니온 타입이 유일한 해결책일 수 있습니다.
typedef (long long or DOMString or CalculatableInterface )SupportedArgument ;interface A {undefined add (SupportedArgument operand1 ,SupportedArgument operand2 ); };위
add()
연산을 오버로딩으로 명세하려면,interface A {undefined add (long long operand1 ,long long operand2 );undefined add (long long operand1 ,DOMString operand2 );undefined add (long long operand1 ,CalculatableInterface operand2 );undefined add (DOMString operand1 ,long long operand2 );undefined add (DOMString operand1 ,DOMString operand2 );undefined add (DOMString operand1 ,CalculatableInterface operand2 );undefined add (CalculatableInterface operand1 ,long long operand2 );undefined add (CalculatableInterface operand1 ,DOMString operand2 );undefined add (CalculatableInterface operand1 ,CalculatableInterface operand2 ); };그리고 9배의 프로즈가 필요합니다!
-
명세 작성자는 자바스크립트 바인딩에서 인자가 없을 때와
undefined 를 넘길 때를 동일하게 처리할 것을 권장합니다.아래와 같은 IDL 프래그먼트가 있다고 할 때:
interface A {undefined foo ();undefined foo (Node ?arg ); };자바스크립트 바인딩에서는
foo(undefined)
와foo(null)
모두foo(arg)
연산의 단계가 실행되고, arg는 null이 된다.foo()
만 호출하면 첫 번째 오버로드가 선택된다. 이는 많은 API 사용자에게 직관적이지 않을 수 있다. 대신 명세 작성자는 옵션 인자를 사용하여,foo()
와foo(undefined)
모두 "arg가 누락됨"으로 분류되도록 할 것을 권장한다.interface A {undefined foo (optional Node ?arg ); };일반적으로 옵션은
optional 키워드로 표현하는 것이, 오버로딩보다 더 적합하다.
위 경우에 해당하지 않으면 명세 작성자가 스타일을 선택하면 됩니다. 둘 중 어느 쪽도 의도한 동작을 충분히 표현할 수 있기 때문입니다. 단, 변환 알고리즘 및 유니온 타입, 옵션 인자의 정의가 오버로딩 결정 알고리즘보다 구현과 이해가 쉽고, 자바스크립트 바인딩에 더 적합한 API를 만드는 경우가 많다. 특별한 이유가 없다면 유니온 타입, 옵션 인자를 기본 선택으로 삼길 권장한다.
명세는 필요하다면 유니온 타입과 오버로딩을 혼합해 사용할 수도 있다.
2.5.9. 이터러블 선언
인터페이스는 이터러블로 선언될 수 있으며,
이는 인터페이스 본문에 이터러블
선언(
interface interface_identifier {iterable <value_type >;iterable <key_type ,value_type >; };
인터페이스를 이터러블로 구현한 객체는 값을 시퀀스로 얻을 수 있도록 반복(iterate)할 수 있다.
참고: 자바스크립트 바인딩에서는 이터러블 인터페이스의 인터페이스 프로토타입 객체에
entries
, forEach
,
keys
, values
, %Symbol.iterator%
프로퍼티가 있다.
타입 파라미터가 하나면 값 이터레이터이며, 해당 타입의 값을 제공한다. 타입 파라미터가 둘이면 쌍 이터레이터이며, 값 쌍을 제공한다.
값 쌍은 키 타입과 값 타입이 주어졌을 때 두 개의 구조체 아이템으로 이루어진다:
값 이터레이터는 반드시 인덱스 프로퍼티를 지원하는 인터페이스에만 선언될 수 있다. 값 이터레이터의 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
메서드를 가진 이터레이터 객체를 반환한다. keys
와 entries
메서드는 각각 session 객체의 username, username/Session
객체 쌍을 반복한다. %Symbol.iterator%
메서드도 있어서 SessionManager
를 for..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 usernameof 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. 비동기 이터러블 선언
인터페이스는
비동기 이터러블
선언
(
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)해서 얻을 수 있다.
타입 파라미터가 하나면 값 비동기 이터러블 선언이며, 해당 타입의 값을 비동기로 제공한다. 두 개면 쌍 비동기 이터러블 선언이며, 값 쌍을 비동기로 제공한다.
인자가 있다면, 비동기 이터러블 선언의 인자(
%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()
이 호출될 때 동작을 커스터마이즈할 수
있다. 이는 break
나 return
으로 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의 비동기 이터레이터 초기화 단계:
iterator의 현재 상태를 "아직 시작하지 않음"으로 설정한다.
SessionManager manager와 비동기 이터레이터 iterator에 대해 다음 반복 결과 얻기:
promise를 새 Promise로 둔다.
key를 다음 값으로 둔다(없으면 null):
- 만약 iterator의 현재 상태가 "아직 시작하지 않음"이라면
manager의 열린 세션 중 username이 가장 작은 값(사전순)
- 그 외
manager의 열린 세션 중 iterator의 현재 상태보다 큰 username 중 가장 작은 값(사전순)
참고: iterator의 현재 상태가 이미 열린 세션에 없을 수도 있다.
key가 null이면:
promise를 반복 종료로 resolve한다.
그 외:
session을 key에 대응하는
Session
객체로 둔다.promise를 (username, session)로 resolve한다.
iterator의 현재 상태를 username으로 설정한다.
promise를 반환한다.
자바스크립트 바인딩에서 SessionManager
인터페이스의 인터페이스 프로토타입
객체에는 values
메서드가 있고,
이 함수는 호출 시 다음 값을 반환하는 next
메서드를 가진 비동기 이터레이터 객체를 반환한다. keys
와
entries
메서드는 각각 session 객체의 username, username/Session
객체 쌍을 반복한다.
%Symbol.asyncIterator%
메서드도 있어서 SessionManager
를 for 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 usernameof 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 선언
(
interface interface_identifier {readonly maplike <key_type ,value_type >;maplike <key_type ,value_type >; };
maplike로 선언된 인터페이스를 구현하는 객체는, 처음에는 비어 있고, 키–값 쌍의 순서 있는 map을 나타내며, 이를 해당 객체의 map 엔트리라고 한다. 키와 값의 타입은 maplike 선언의 꺾쇠 괄호에 지정된다. 키는 반드시 고유해야 한다.
명세 작성자는 map 엔트리의 내용을 수정할 수 있으며, 이는 자바스크립트 코드에서 객체의 내용에 자동으로 반영된다.
maplike 인터페이스는 언어 바인딩에 적절한 map 엔트리 질의 API를 지원한다.
참고: 자바스크립트 바인딩에서는 map 엔트리와 상호작용하는 API는 자바스크립트
Map
객체와 유사하다. 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
ReadWriteMaplike ::MaplikeRest
MaplikeRest ::maplike < TypeWithExtendedAttributes , TypeWithExtendedAttributes > ;
이 명세에서 정의된 확장 속성은 maplike 선언에 적용되지 않는다.
예시 추가 필요.
2.5.12. Setlike 선언
인터페이스는 setlike로 선언될 수 있으며,
이는 인터페이스 본문에 setlike 선언
(
interface interface_identifier {readonly setlike <type >;setlike <type >; };
setlike로 선언된 인터페이스를 구현하는 객체는, 처음에는 비어 있고, 값의 순서 있는 집합을 나타내며, 이를 해당 객체의 set 엔트리라고 한다. 값의 타입은 setlike 선언의 꺾쇠 괄호에 지정된다. 값은 반드시 고유해야 한다.
명세 작성자는 set 엔트리의 내용을 수정할 수 있으며, 이는 자바스크립트 코드에서 객체의 내용에 자동으로 반영된다.
setlike 인터페이스는 언어 바인딩에 적절한 set 엔트리 질의 API를 지원한다.
참고: 자바스크립트 바인딩에서는 set 엔트리와 상호작용하는 API는 자바스크립트
Set
객체와 유사하다. 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
ReadWriteSetlike ::SetlikeRest
SetlikeRest ::setlike < TypeWithExtendedAttributes > ;
이 명세에서 정의된 확장 속성은 setlike 선언에 적용되지 않는다.
예시 추가 필요.
2.6. 네임스페이스
네임스페이스란, 전역 싱글턴과
관련 동작을 선언하는 정의(
namespace identifier { /* namespace_members... */ };
네임스페이스는
네임스페이스 멤버들의 명세(
인터페이스와 마찬가지로, 네임스페이스의 IDL도
부분 네임스페이스
정의(
namespace SomeNamespace { /* namespace_members... */ };partial namespace SomeNamespace { /* namespace_members... */ };
참고: 부분 인터페이스 정의처럼, 부분 네임스페이스 정의는 명세 편집을 돕기 위한 것으로, 네임스페이스 정의를 문서의 여러 섹션 또는 여러 문서에 걸쳐 분리해 기술할 수 있게 해줍니다.
멤버가 등장하는 순서는 JavaScript 바인딩에서 프로퍼티 열거에 영향을 미칩니다.
인터페이스나 딕셔너리와 다르게, 네임스페이스는 타입을 생성하지 않습니다.
이 명세에서 정의된 확장 속성 중, [CrossOriginIsolated
],
[Exposed
],
[SecureContext
]만
네임스페이스에 적용할 수 있습니다.
네임스페이스는 반드시 [Exposed
] 확장 속성으로
어노테이트해야 합니다.
Partial ::partial PartialDefinition
Namespace ::namespace identifier { NamespaceMembers } ;
NamespaceMembers ::ExtendedAttributeList NamespaceMember NamespaceMembers ε
NamespaceMember ::RegularOperation readonly AttributeRest Const
namespace VectorUtils {readonly attribute Vector unit ;double dotProduct (Vector x ,Vector y );Vector crossProduct (Vector x ,Vector y ); };
자바스크립트 구현에서는 전역 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 identifier { /* dictionary_members... */ };
딕셔너리 인스턴스는 언어별 표현(예: 해당하는 자바스크립트 객체)에 대한 참조를 유지하지 않는다. 예를 들어, 딕셔너리를 연산에서 반환하면, 현재 딕셔너리 값으로부터 새로운 자바스크립트 객체가 생성된다. 반대로 연산에서 딕셔너리를 인자로 받을 경우, 전달된 자바스크립트 값으로부터 딕셔너리로 한 번만 변환이 수행된다. 딕셔너리를 수정해도 해당 자바스크립트 객체에는 반영되지 않고, 그 반대도 마찬가지다.
딕셔너리는 다른 딕셔너리를 상속하도록 정의할 수 있다. 딕셔너리의 식별자 뒤에 콜론과 식별자가 오면, 해당 식별자는 상속받는 딕셔너리를 식별한다. 반드시 딕셔너리를 식별해야 한다.
딕셔너리의 상속 계층에 순환 구조가 있으면 안 된다. 즉, 딕셔너리 A가 자기 자신을 상속하거나, B를 상속하면서 B가 다시 A를 상속하는 방식은 금지된다.
dictionary Base { /* dictionary_members... */ };dictionary Derived :Base { /* dictionary_members... */ };
딕셔너리 D의 상속된 딕셔너리들은 D가 직접 또는 간접적으로 상속받는 모든 딕셔너리 집합을 의미한다. D가 다른 딕셔너리를 상속하지 않으면 집합은 비어 있다. 그렇지 않으면, D가 상속한 딕셔너리 E와 E의 상속된 딕셔너리들이 모두 포함된다.
딕셔너리 멤버는 필수로 지정될 수 있다. 이 경우, 해당 멤버에 값을 제공하지 않으면 언어별 값에서 딕셔너리로 변환할 때 오류가 발생한다. 필수가 아닌 멤버는 옵션이다.
딕셔너리 멤버를 필수로 지정하는 것은, 언어별 딕셔너리 표현(예: 연산 인자로 자바스크립트 값을 전달할 때)에서만 효과가 있다. 이외의 경우, 즉 딕셔너리를 반환 타입으로만 사용하는 경우 등에는 멤버를 옵션으로 남겨두는 것이 좋다.
타입 D의 딕셔너리 값에는, D와 D의 상속된 딕셔너리들에 정의된 모든 딕셔너리 멤버에 대한 엔트리가 있을 수 있다. 필수 또는 기본값이 지정된 멤버는 반드시 엔트리가 존재한다. 그 외 멤버의 엔트리는 존재할 수도 있고, 아닐 수도 있다.
자바스크립트 바인딩에서는, 딕셔너리 멤버에 해당하는 프로퍼티 값이
연산 인자 기본값과 마찬가지로,
boolean
타입 딕셔너리 멤버의 기본값으로
문자열 키를 가진 순서 있는 map은, 모든 엔트리가 딕셔너리 D의 딕셔너리 멤버에 대응하고, 타입이 맞고, 필수 또는 기본값 멤버에 대한 엔트리가 모두 존재하면 암묵적으로 D 타입의 딕셔너리 값으로 간주될 수 있다.
dictionary Descriptor {DOMString name ;sequence <unsigned long >serviceIdentifiers ; };
Descriptor
딕셔너리는 다음과 같이 생성할 수 있다:
-
identifiers를 « 1, 3, 7 »로 둔다.
-
«[ "name" → "test", "serviceIdentifiers" → identifiers ]»를 반환한다.
각 딕셔너리
멤버(
딕셔너리 멤버의 타입이 typedef 해석 후 널 허용 타입이면, 내부 타입이 딕셔너리 타입이면 안 된다.
dictionary identifier {type identifier ; };
옵션 딕셔너리 멤버의
식별자 뒤에 U+003D(=)와 값(
dictionary identifier {type identifier = "value"; };
불리언 리터럴 토큰(
딕셔너리 멤버 타입이 열거형이면, 기본값은 반드시 열거형의 값 중 하나여야 한다.
딕셔너리 멤버 타입 앞에
dictionary identifier {required type identifier ; };
딕셔너리 멤버의 타입에는 해당 딕셔너리가 포함되면 안 된다. 타입이 딕셔너리 D를 포함한다는 것은 다음 중 하나라도 참이면 성립한다:
-
타입이 D이다.
-
타입이 D를 상속하는 딕셔너리이다.
-
타입이 유니온 타입이며, 멤버 타입 중 하나가 D를 포함한다.
-
타입이 딕셔너리이고, 그 멤버 또는 상속 멤버의 타입 중 D를 포함하는 것이 있다.
-
타입이
record<K, V>
이고, V가 D를 포함한다.
인터페이스와 마찬가지로, 딕셔너리의 IDL도 부분 딕셔너리 정의(
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
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
정의에서 기본값이 있다고 간주하고 따로
생략 처리 문구를 넣지 않아도 된다.
strokePattern
과 position
생략 시는 drawRectangle
에서 명시적으로 처리해야 한다.
2.8. 예외
예외란 오류를 나타내는 객체 타입으로,
구현체에서 throw 하거나 값처럼 다룰 수 있다. Web IDL에는 명세에서 연산, 속성 등에 참조 또는 throw할 수 있는 여러 기본 예외가 정의되어 있다. 인터페이스에서 DOMException
을
상속하여 커스텀 예외 타입도 정의할 수 있다.
단순 예외는 다음 타입 중 하나로 식별된다:
-
EvalError
-
RangeError
-
ReferenceError
-
TypeError
-
URIError
이들은 JavaScript의 에러 객체와 대응한다
(단, SyntaxError
와 Error
는
제외됨; 각각 JS 파서와 저자 용도로 예약되어 있음). 각 단순 예외의 의미는 JavaScript 명세의 대응 에러 객체와 같다.
두 번째 예외 종류는 DOMException
으로,
발생한 오류에 대해 name으로
프로그래밍적으로 상세 정보를 제공한다.
name 값은 아래 DOMException
이름 테이블에서 선정된다.
DOMException
은
인터페이스 타입이므로 IDL에서 타입으로 사용할 수
있다. 예를 들어 연산의 DOMException
반환 타입으로 선언할 수 있지만,
예외는 반환이 아니라 throw하는 것이므로 이런 패턴은 바람직하지 않다.
세 번째 예외 종류는 DOMException
을
상속한 인터페이스이다.
이들은 더 복잡하므로 § 2.8.2 DOMException 파생 인터페이스에서 따로 설명한다.
단순 예외는
타입 이름을 제공해 생성할 수 있다. DOMException
은
name과 함께 제공하여 생성한다.
예외는 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
파생 인터페이스
예외가 DOMException
의 name으로 제공되는 정보 외에, 추가로 프로그래밍적으로 조회 가능한 정보를 담아야 할 때,
명세 작성자는 DOMException
를 상속하는 인터페이스를 만들 수 있다.
이런 인터페이스는 개발자가 예측 가능한 형태로 다룰 수 있도록 다음 규칙을 따라야 한다:
-
인터페이스의 식별자는 반드시
Error
로 끝나야 하며,DOMException
이름 테이블에 있는 이름이면 안 된다. -
생성자 연산의 첫 번째 인자는 옵션
DOMString
타입의 message이며, 기본값은 빈 문자열이어야 하고, 인스턴스의 message를 message로 설정해야 한다. -
생성자 딕셔너리의 멤버와 동일한 이름을 가진 읽기 전용 속성을 가지며, 생성자 연산에서 받은 값을 반환해야 한다.
-
직렬화 가능한 객체여야 하며, 직렬화 단계와 역직렬화 단계에서 추가 정보가 보존되어야 한다.
이 요구로 인해, 이런 인터페이스의 상속된 code
프로퍼티는 항상 0을 반환한다.
DOMException
파생 인터페이스를 생성하거나 throw하려면, 해당 인터페이스 식별자와 추가 정보가 필요하다.
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
인스턴스는
requested와 quota라는 두 개의 숫자 또는 null 값을 가지며, 최초 값은 모두 null이다.
new QuotaExceededError(message, options)
생성자 단계:
-
options["
quota
"]가 있으면:-
options["
quota
"]가 0보다 작으면RangeError
를 throw한다.
-
-
options["
requested
"]가 있으면:-
options["
requested
"]가 0보다 작으면RangeError
를 throw한다.
-
-
this의 quota와 requested가 모두 null이 아니고, requested가 quota보다 작으면
RangeError
를 throw한다.
quota
getter는 this의 quota를 반환한다.
requested
getter는 this의 requested를 반환한다.
QuotaExceededError
인터페이스는
DOMException
의 code
getter를 상속받으며, 항상 22를
반환한다. 하지만 이 값에 의존하는 것은 권장되지 않는다(QuotaExceededError
와 DOMException
모두에서). 대신 name
getter를 사용하는 것이 더 낫다.
QuotaExceededError
객체는 직렬화 가능한
객체이다.
-
DOMException
의 직렬화 단계를 value, serialized에 대해 실행한다. -
serialized.[[Quota]]를 value의 quota로 설정한다.
-
serialized.[[Requested]]를 value의 requested로 설정한다.
-
DOMException
의 역직렬화 단계를 serialized, value에 대해 실행한다. -
value의 quota를 serialized.[[Quota]]로 설정한다.
-
value의 requested를 serialized.[[Requested]]로 설정한다.
QuotaExceededError
를 생성하거나 throw할 때, requested와 quota가 모두 null이 아니면서 requested가 quota보다 작으면 안 된다.
2.9. 열거형
열거형이란, DOMString
값이
속성에 할당되거나 연산에 인자로 전달될 때, 가능한 값을 제한하는 데 사용할 수 있다.
enum identifier {"enum" ,"values" /* , ... */ };
열거형 값은
쉼표로 구분된
열거형 값은 모두 소문자로 하고, 여러 단어는 대시(-)로 구분하거나 아예 구분하지 않는 것이 강력히 권장된다.
특별한 이유가 없으면 다른 명명 규칙을 사용하지 말 것. 예를 들어, 객체 생성 의미의 값은
"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 identifier =return_type (/* arguments... */);
참고: 유사 이름의 콜백 인터페이스도 참고하세요.
등호 왼쪽의 식별자가 콜백 함수 이름이며,
오른쪽의 반환 타입과 인자 목록(
콜백 함수에 적용 가능한 확장 속성:
[LegacyTreatNonObjectAsNull
].
CallbackOrInterfaceOrMixin ::callback CallbackRestOrInterface interface InterfaceOrMixin
CallbackRest ::identifier = Type ( ArgumentList ) ;
아래 IDL 프래그먼트는 연산이 완료될 때 사용자 정의 함수를 호출하는 API의 콜백 함수를 정의한 예시입니다.
callback AsyncOperationCallback =undefined (DOMString status ); [Exposed =Window ]interface AsyncOperations {undefined performOperation (AsyncOperationCallback whenFinished ); };
자바스크립트 바인딩에서는 함수 객체가 연산 인자로 전달된다.
var ops= getAsyncOperations(); // AsyncOperations 인스턴스 얻기 ops. performOperation( function ( status) { window. alert( "Operation finished, status is " + status+ "." ); });
2.11. 타입 정의(typedef)
타입 정의(typedef)란,
typedef type identifier ;
새 이름을 부여받는
타입은
이 명세에서 정의된 확장 속성은 타입 정의에 적용되지 않습니다.
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
,
double
및
unrestricted double
.
원시 타입은
bigint
,
boolean
과
숫자 타입입니다.
문자열 타입은
DOMString
,
모든 열거형 타입,
ByteString
및 USVString
입니다.
버퍼 타입은
ArrayBuffer
및 SharedArrayBuffer
입니다.
타입 배열 타입은
Int8Array
,
Int16Array
,
Int32Array
,
Uint8Array
,
Uint16Array
,
Uint32Array
,
Uint8ClampedArray
,
BigInt64Array
,
BigUint64Array
,
Float16Array
,
Float32Array
,
그리고
Float64Array
입니다.
버퍼 뷰 타입은
DataView
와
타입 배열 타입입니다.
object
타입,
모든 인터페이스 타입, 그리고
모든 콜백 인터페이스 타입은 객체 타입으로 불립니다.
언어 바인딩별 타입에서 IDL 타입으로 변환하여 연산을 호출하거나 속성에 값을 할당하는 경우, 필요한 모든 변환은 연산 또는 속성 할당의 기능이 실행되기 전에 수행됩니다. 변환이 불가능하면 연산은 실행되지 않거나 속성이 갱신되지 않습니다. 일부 언어 바인딩에서는 타입 변환이 예외를 발생시킬 수 있으며, 이 경우 예외는 연산 실행 또는 속성 할당을 시도한 코드에 전달됩니다.
Type ::SingleType UnionType Null
TypeWithExtendedAttributes ::ExtendedAttributeList Type
SingleType ::DistinguishableType any PromiseType
UnionType ::( UnionMemberType or UnionMemberType UnionMemberTypes )
UnionMemberType ::ExtendedAttributeList DistinguishableType UnionType Null
UnionMemberTypes ::or UnionMemberType UnionMemberTypes ε
DistinguishableType ::PrimitiveType Null StringType Null identifier Null sequence < TypeWithExtendedAttributes > Null async_sequence < TypeWithExtendedAttributes > Null object Null symbol Null BufferRelatedType Null FrozenArray < TypeWithExtendedAttributes > Null ObservableArray < TypeWithExtendedAttributes > Null RecordType Null undefined Null
PrimitiveType ::UnsignedIntegerType UnrestrictedFloatType boolean byte octet bigint
UnrestrictedFloatType ::unrestricted FloatType FloatType
FloatType ::float double
UnsignedIntegerType ::unsigned IntegerType IntegerType
IntegerType ::short long OptionalLong
OptionalLong ::long ε
StringType ::ByteString DOMString USVString
PromiseType ::Promise < Type >
RecordType ::record < StringType , TypeWithExtendedAttributes >
Null ::? ε
2.13.1. any
any
타입은
모든 다른 non-union 타입의 합집합입니다.
any
타입은
각 값이 특정 non-any
타입과 연결되어 있다는 점에서 discriminated union 타입과 유사합니다.
예를 들어, any
타입의 한
값은
unsigned long
150이고,
또 다른 값은 long
150입니다.
이 둘은 서로 다른 값입니다.
any
값의 특정 타입은 특정 타입이라고 합니다.
(union 타입의 값도
특정 타입을 가집니다.)
2.13.2. undefined
undefined
타입은 고유한 값을 하나만 가집니다.
undefined
상수 값은 IDL에서
undefined
타입은 어떤 경우에도(연산, 콜백 함수, 생성자 연산 등) 인자 타입이나,
딕셔너리 멤버 타입(직접
또는 union 내)으로 사용해서는 안 됩니다.
대신 옵션 인자나,
non-필수 딕셔너리 멤버를 사용하세요.
참고: 이 값은 이전에는 void
로 표기되었으며,
사용 방식이 더 제한적이었습니다.
2.13.3. boolean
boolean
상수 값은
IDL에서
2.13.4. byte
byte
타입은
8비트 부호 있는 정수와 대응됩니다.
byte
상수 값은
IDL에서
2.13.5. octet
octet
타입은
8비트 부호 없는 정수와 대응됩니다.
octet
상수 값은
IDL에서
2.13.6. short
short
타입은
16비트 부호 있는 정수와 대응됩니다.
short
상수 값은
IDL에서
2.13.7. unsigned short
unsigned short
타입은 16비트 부호 없는 정수와 대응됩니다.
unsigned short
상수 값은 IDL에서
2.13.8. long
long
타입은
32비트 부호 있는 정수와 대응됩니다.
long
상수 값은
IDL에서
2.13.9. unsigned long
unsigned long
타입은 32비트 부호 없는 정수와 대응됩니다.
unsigned long
상수 값은 IDL에서
2.13.10. long long
long long
타입은 64비트 부호 있는 정수와 대응됩니다.
long long
상수 값은 IDL에서
2.13.11. unsigned long long
unsigned long long
타입은 64비트 부호 없는 정수와 대응됩니다.
unsigned long long
상수 값은 IDL에서
2.13.12. float
float
타입은
부동소수점 숫자 타입으로,
유한한 단정밀도 32비트 IEEE 754 부동소수점 숫자 집합에 대응합니다. [IEEE-754]
float
상수 값은
IDL에서
32비트 부동소수점 타입을 특별히 써야 할 이유가 없다면,
double
을
float
대신 사용하는
것이 좋습니다. double
이 표현할
수 있는 값 집합이 JavaScript Number와 더 유사하기 때문입니다.
2.13.13. unrestricted float
unrestricted float
타입은 부동소수점 숫자 타입으로,
모든 가능한 단정밀도 32비트 IEEE 754 부동소수점 값(유한, 무한 및 NaN)을 포함합니다. [IEEE-754]
unrestricted float
상수 값은 IDL에서
2.13.14. double
double
타입은 부동소수점 숫자 타입으로,
유한한 배정밀도 64비트 IEEE 754 부동소수점 숫자 집합에 대응합니다. [IEEE-754]
double
상수 값은 IDL에서
2.13.15. unrestricted double
unrestricted double
타입은 부동소수점 숫자 타입으로,
모든 가능한 배정밀도 64비트 IEEE 754 부동소수점 값(유한, 무한 및 NaN)을 포함합니다. [IEEE-754]
unrestricted double
상수 값은 IDL에서
2.13.16. bigint
bigint
타입은 범위가 제한되지 않은 임의의 정수 타입입니다.
bigint
상수 값은 IDL에서
2.13.17. DOMString
참고: DOMString
타입의 값이 아닙니다.
DOMString
,
즉 IDL에서 DOMString?
을 사용해야 합니다.
참고: DOMString
값에는 매치되지 않는 서로게이트 코드 포인트가 포함될 수 있습니다. 이를 원하지
않는 경우 USVString
을
사용하세요.
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
상수 값을 표현할 방법이 없습니다.
모든 객체 참조와 object?
를 사용하세요.
2.13.21. symbol
symbol
타입은 모든 가능한 심볼 값 집합에 대응합니다. 심볼 값은 불투명하며, object
값은 아니지만 고유성(자기 자신과만 같음)을 가집니다.
IDL에서는 symbol
상수 값을 표현할 방법이 없습니다.
2.13.22. 인터페이스 타입
식별자가 인터페이스를 지정하면, 해당 인터페이스를 구현하는 non-null 객체 참조의 집합을 타입으로 참조합니다.
인터페이스 타입의 IDL 값은 객체 참조로 표현됩니다.
특정 인터페이스 타입에 대한 상수 객체 참조 값을 IDL에서 표현할 방법은 없습니다.
해당 인터페이스를 구현하는 객체 참조와
2.13.23. 콜백 인터페이스 타입
식별자가 콜백 인터페이스를 지정하면, 모든 가능한 non-null 객체 참조 집합을 타입으로 참조합니다.
콜백 인터페이스 타입의 IDL 값은 객체 참조와 콜백 컨텍스트의 튜플로 표현됩니다. 콜백 컨텍스트는 언어 바인딩별 값이며, 객체 참조를 IDL 값으로 변환할 때의 실행 컨텍스트 정보를 저장하는 데 사용됩니다.
참고: 자바스크립트 객체에서는 콜백 컨텍스트에 Object 값이 IDL 콜백 인터페이스 타입 값으로 변환될 때의 incumbent settings object 참조가 저장됩니다. § 3.2.16 Callback interface types 참고.
특정 콜백 인터페이스 타입에 대한 상수 객체 참조 값을 IDL에서 표현할 방법은 없습니다.
모든 객체 참조와
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?
널 허용 타입은 기존 타입(이를
내부 타입이라 함)에서
-
any
, -
다른 널 허용 타입,
-
자체가 널 허용 타입을 포함하거나, 평탄화된 멤버 타입에 딕셔너리 타입이 있는 유니온 타입.
참고: 딕셔너리 타입은 일반적으로 널 허용이 가능하지만, 연산 인자나 딕셔너리 멤버 타입으로는 허용되지 않습니다.
널 허용 타입 상수 값은 IDL에서 내부 타입 상수 값과 동일하게 표현하거나
예를 들어, boolean?
으로 표기합니다:
[Exposed =Window ]interface NetworkFetcher {undefined get (optional boolean ?areWeThereYet =false ); };
다음 인터페이스에는 두 개의 속성이 있습니다. 하나는 DOMString
또는
Node
객체 참조 또는
[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 타입의
인스턴스입니다.
K는 DOMString
,
USVString
,
또는 ByteString
중 하나여야 합니다.
순서가 있는 맵의 리터럴 문법도, 맵이 레코드로 간주된다는 게 문맥에서 명확하다면 레코드 표현에 사용할 수 있습니다. 하지만 IDL 프래그먼트 내에 상수 레코드 값을 표현하는 방법은 없습니다.
레코드는 항상 값으로 전달됩니다. 레코드가 어떤 객체로 표현되는 언어 바인딩에서는, 레코드를 플랫폼 객체에 전달해도 해당 객체에 레코드 참조가 남지 않습니다. 마찬가지로 플랫폼 객체에서 반환된 레코드도 복사본이며, 이를 수정해도 플랫폼 객체에는 영향을 미치지 않습니다.
어떤 순서가 있는 맵도, 모든 엔트리의 키가 K 타입이고 값이 V
타입이면 암묵적으로 record<K, V>
로 간주할 수 있습니다.
2.13.31. 프라미스 타입 — Promise<T>
프라미스 타입은 파라미터화된 타입으로, 값이 비동기 작업의 결과를 나중에 받을 수 있는 “자리 표시자” 객체 참조입니다. 자세한 프라미스 객체 의미는 JavaScript 명세 section 25.4 참고.
프라미스 타입은 널 허용이 아니지만, T는 널 허용일 수 있습니다.
IDL에서는 프라미스 값을 표현할 방법이 없습니다.
2.13.32. 유니온 타입
유니온 타입은 값 집합이 두 개 이상의
타입 값 집합의 합집합이 되는 타입입니다. 유니온 타입(
예를 들어 (Node or DOMString)
또는 (double or sequence<double>)
처럼 쓸 수 있습니다. 유니온
타입 전체에 (Node or DOMString)?
처럼 표기합니다.
유니온 타입의 멤버 타입은 중첩된 유니온 타입 안까지 내려가지 않습니다. 예를 들어
(double or (sequence<long> or Event) or (Node or DOMString)?)
의 멤버 타입은
double
, (sequence<long> or Event)
, (Node or DOMString)?
입니다.
any
타입처럼, 유니온 타입 값도 특정 타입을 가지며, 이는 해당 값과 일치하는 멤버 타입입니다.
평탄화된 멤버 타입은 (어노테이트된 타입 포함) 다음과 같이 결정합니다:
참고: 예를 들어, 유니온 타입
(Node or (sequence<long> or Event) or (XMLHttpRequest or DOMString)? or sequence<(sequence<double> or NodeList)>)
의
평탄화된 멤버 타입은 Node
,
sequence<long>
, Event
, XMLHttpRequest
, DOMString
,
sequence<(sequence<double> or NodeList)>
입니다.
널 허용 멤버 타입 개수는 유니온 타입에서 다음과 같이 결정합니다:
-
T를 유니온 타입으로 둔다.
-
n을 0으로 초기화한다.
-
T의 각 멤버 타입 U에 대해:
-
U가 널 허용 타입이면:
-
n을 n+1로 한다.
-
U를 그 내부 타입으로 둔다.
-
-
U가 유니온 타입이면:
-
m을 U의 널 허용 멤버 타입 개수로 둔다.
-
n을 n+m로 한다.
-
-
-
n을 반환한다.
any
타입은 유니온 멤버 타입으로 사용해서는 안 됩니다.
널 허용 멤버 타입 개수는 반드시 0 또는 1이어야 하고, 1인 경우 유니온 타입의 평탄화된 멤버 타입에 딕셔너리 타입이 포함되어 있으면 안 됩니다.
널 허용 타입을 포함한다란 다음 중 하나면 참입니다:
-
그 타입이 널 허용 타입이거나,
-
어노테이트 타입이고 내부 타입이 널 허용 타입이거나,
-
유니온 타입이고 널 허용 멤버 타입 개수가 1인 경우.
유니온 타입의 모든 평탄화된 멤버 타입 쌍(T, U)은 구분 가능해야 합니다.
bigint
와 숫자 타입의 유니온을 만들 수 있습니다. 하지만 이는 일반적으로 NumberFormat처럼 값을 계산이 아닌 포맷에 사용하는 인터페이스에서만 써야
합니다. 숫자 타입 값을 bigint
로 변환해 처리하면 정밀도
문제가 생길 수 있습니다. 이 기능을 쓰기 전에 반드시 이슈를
등록하세요.
undefined를 포함한다란 다음 중 하나면 참입니다:
-
그 타입이
undefined
이거나, -
널 허용 타입이고 내부 타입이 undefined를 포함하는 경우,
-
어노테이트 타입이고 내부 타입이 undefined를 포함하는 경우,
-
유니온 타입이고 멤버 타입 중 하나가 undefined를 포함하는 경우.
유니온 타입의 상수 값은 각 멤버 타입의 상수 값과 동일하게 표현됩니다.
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. 주석 타입
특정 확장 속성을 기존 타입에 지정하면 추가 타입을 만들 수 있습니다. 이러한 타입을 주석 타입이라 하며, 이들이 주석을 다는 타입을 내부 타입이라 합니다.
아래 확장 속성들이 타입에 적용 가능합니다:
[AllowResizable
],
[AllowShared
],
[Clamp
],
[EnforceRange
],
그리고
[LegacyNullToEmptyString
].
-
extended attributes를 새로운 빈 집합으로 둔다.
-
type이
TypeWithExtendedAttributes 생성식 일부에 등장하면, 그 생성식의ExtendedAttributeList 에 있는 확장 속성을 모두 extended attributes에 추가한다. -
type이 유니온 타입 U의 멤버 타입이면, U에 연관된 확장 속성을 모두 extended attributes에 추가한다.
-
type이
Type 생성식에 등장하고, 그 생성식이Argument 생성식 바로 내부에 있다면, 해당ExtendedAttributeList 에 타입 적용 가능 확장 속성이 있으면 그걸 extended attributes에 추가한다.[
Exposed =Window ]interface I {undefined f ([XAttr ]long attrib ); };이 예시는 [
XAttr
]이 타입 적용 가능일 때만 해당 단계 예시입니다. 아니라면 [XAttr
]은 인자에 적용되고 타입에는 적용되지 않습니다. -
type이
Type 생성식에 등장하고, 그 생성식이DictionaryMember 생성식 바로 내부에 있다면, 해당ExtendedAttributeList 에 타입 적용 가능 확장 속성이 있으면 그걸 extended attributes에 추가한다.dictionary D { [XAttr ]long member ; };이 예시는 [
XAttr
]이 타입 적용 가능일 때만 해당 단계 예시입니다. 아니라면 [XAttr
]은 딕셔너리 멤버에 적용되고 타입에는 적용되지 않습니다. -
type이 typedef이면, 그 새 이름을 부여받는 타입에 연관된 확장 속성을 추가한다.
-
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 속성 타입으로만 사용해야 합니다.
[Exposed =Window ]interface PersonalPreferences {readonly attribute FrozenArray <DOMString >favoriteColors ;attribute FrozenArray <DOMString >favoriteFoods ;undefined randomizeFavoriteColors (); };
이 속성들의 동작 정의 예시:
각PersonalPreferences
는 favorite colors(FrozenArray
<DOMString
>)를 갖고, 초기값은 « "purple
", "aquamarine
" »로 불변 배열 생성 결과입니다.각
PersonalPreferences
는 favorite foods(FrozenArray
<DOMString
>)도 갖고, 초기값은 빈 리스트로 불변 배열 생성 결과입니다.
favoriteColors
getter 단계는 this의 favorite colors를 반환합니다.
favoriteFoods
getter 단계는 this의 favorite foods를 반환합니다.
favoriteFoods
setter 단계는 this의 favorite foods를 지정 값으로 설정합니다.
randomizeFavoriteColors()
메서드 단계는:
FrozenArray<T> 값은 참조이므로, 시퀀스 타입처럼 값으로 전달되는 리스트와는 다릅니다.
IDL에서는 불변 배열 상수 값을 표현할 방법이 없습니다.
2.13.36. 관찰 배열 타입 — ObservableArray<T>
관찰 배열 타입은 파라미터화된 타입으로, 값이 T 타입 객체의 변경 가능한 리스트와, 저자 코드가 리스트를 수정할 때 실행되는 동작을 결합한 객체 참조입니다.
파라미터화 타입 T는 딕셔너리 타입, 시퀀스 타입, 레코드 타입, 관찰 배열 타입이 될 수 없습니다. 하지만 T는 널 허용일 수 있습니다.
시퀀스 타입과 불변 배열 타입처럼, 관찰 배열 타입도 자바스크립트 배열 타입을 감싸며 추가 의미를 부여합니다.
관찰 배열 타입은 인터페이스에 정의된 일반 속성 타입으로만 사용해야 합니다.
관찰 배열 속성에는 명세 저자가 다음 알고리즘을 정의할 수 있습니다:
-
인덱스 값 설정 알고리즘 — 관찰 배열에 설정될 IDL 값과 그 인덱스를 받음;
-
인덱스 값 삭제 알고리즘 — 관찰 배열에서 삭제될 IDL 값과 그 인덱스를 받음.
이 두 알고리즘은 모두 선택적이며, 정의되지 않으면 기본 동작은 아무것도 하지 않는 것입니다. 두 알고리즘 모두 예외를 throw할 수 있습니다(예: 값이 잘못된 경우 거부).
자바스크립트 코드가 기존 인덱스에 새 값을 설정하면, 먼저 인덱스 값 삭제 알고리즘이 실행되어 기존 값을 삭제하고, 그 다음 인덱스 값 설정 알고리즘이 새 값을 설정합니다.
관찰 배열 타입인 일반 속성마다 백킹 리스트가 있으며, 이는 리스트로, 초깃값은 빈 리스트입니다. 명세 저자는 백킹 리스트 내용을 수정할 수 있고, 이는 자바스크립트에서 관찰 배열 내용에도 즉시 반영됩니다. 마찬가지로 자바스크립트 코드가 관찰 배열을 수정하면 인덱스 값 설정, 인덱스 값 삭제 알고리즘을 거쳐 백킹 리스트에도 반영됩니다.
IDL에서는 관찰 배열 상수 값을 표현할 방법이 없습니다.
[Exposed =Window ]interface Building {attribute ObservableArray <Employee >employees ; };
이 속성의 동작 정의 예시:
Building
의employees
속성에 대해 인덱스 값 설정 알고리즘(인자: employee, index):
employee가 오늘 건물 출입 불가이면 "
NotAllowedError
"DOMException
을 throw.index가 200 이상이면
QuotaExceededError
를 throw하고, quota는 200, requested는 index로 설정.employee를 업무에 투입!
Building
의employees
속성에 대해 인덱스 값 삭제 알고리즘(인자: employee, index):
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. employeesinstanceof Array); console. assert( Array. isArray( building. employees)); console. assert( building. employees. constructor === Array); // JSON.stringify에도 배열로 취급됨! (바깥 [] 참조.) console. assert( JSON. stringify( building. employees) === `[{}]` );
2.14. 확장 속성
확장 속성은
주석(annotation)으로서
정의,
주석 타입,
인터페이스 멤버,
인터페이스 믹스인 멤버,
콜백 인터페이스 멤버,
네임스페이스 멤버,
딕셔너리 멤버,
연산 인자에 붙을 수 있으며, 언어 바인딩이 해당 구조체를 어떻게 처리할지 제어한다.
확장 속성은
문법 기호 | 형태 | 예시 |
---|---|---|
|
인자 없음 |
[Replaceable]
|
|
인자 리스트 있음 |
현재 사용되지 않음; 과거에는 [Constructor(double x, double y)] 처럼 사용됨
|
|
이름 있는 인자 리스트 있음 |
[LegacyFactoryFunction=Image(DOMString src)]
|
|
식별자 있음 |
[PutForwards=name]
|
|
문자열 있음 |
[Reflect="popover"]
|
|
정수 있음 |
[ReflectDefault=2]
|
|
실수 있음 |
[ReflectDefault=2.0]
|
|
정수 리스트 있음 |
[ReflectRange=(2, 600)]
|
|
식별자 리스트 있음 |
[Exposed=(Window,Worker)]
|
|
와일드카드 있음 |
[Exposed=*]
|
이 현행 표준에서는 JavaScript 바인딩에 적용되는 여러 확장 속성을 정의하며, § 3.3 확장 속성에서 설명한다. 각 확장 속성 정의에는 위 다섯 가지 중 어떤 형태를 허용하는지 명시된다.
ExtendedAttributeList ::[ ExtendedAttribute ExtendedAttributes ] ε
ExtendedAttributes ::, ExtendedAttribute ExtendedAttributes ε
ExtendedAttribute ::( ExtendedAttributeInner ) ExtendedAttributeRest [ ExtendedAttributeInner ] ExtendedAttributeRest { ExtendedAttributeInner } ExtendedAttributeRest Other ExtendedAttributeRest
ExtendedAttributeRest ::ExtendedAttribute ε
ExtendedAttributeInner ::( ExtendedAttributeInner ) ExtendedAttributeInner [ ExtendedAttributeInner ] ExtendedAttributeInner { ExtendedAttributeInner } ExtendedAttributeInner OtherOrComma ExtendedAttributeInner ε
Other ::integer decimal identifier string other - -Infinity . ... : ; < = > ? * ByteString DOMString FrozenArray Infinity NaN ObservableArray Promise USVString any bigint boolean byte double false float long null object octet or optional record sequence short symbol true unsigned undefined ArgumentNameKeyword BufferRelatedType
OtherOrComma ::Other ,
IdentifierList ::identifier Identifiers
Identifiers ::, identifier Identifiers ε
IntegerList ::integer Integers
Integers ::, integer Integers ε
ExtendedAttributeNoArgs ::identifier
ExtendedAttributeArgList ::identifier ( ArgumentList )
ExtendedAttributeIdent ::identifier = identifier
ExtendedAttributeString ::identifier = string
ExtendedAttributeInteger ::identifier = integer
ExtendedAttributeDecimal ::identifier = decimal
ExtendedAttributeWildcard ::identifier = *
ExtendedAttributeIdentList ::identifier = ( IdentifierList )
ExtendedAttributeIntegerList ::identifier = ( IntegerList )
ExtendedAttributeNamedArgList ::identifier = identifier ( ArgumentList )
3. 자바스크립트 바인딩
이 절에서는 § 2 인터페이스 정의 언어에 정의된 IDL로 작성된 정의들이 ECMAScript 언어 명세 [ECMA-262]에 규정된 자바스크립트의 특정 구조와 어떻게 대응되는지 설명한다.
별도 명시 없으면, 이 절에서 정의된 객체는 ECMAScript § 10.1 일반 객체 내부 메서드와 내부 슬롯에 기술된 일반 객체이며, 객체가 함수 객체라면 ECMAScript § 10.3 내장 함수 객체에 따른다.
이 절에서는 객체의 내부 메서드와 내부 슬롯 일부를 재정의할 수 있다. 다른 현행 표준 또한 인터페이스의 인스턴스인 플랫폼 객체의 내부 메서드나 내부 슬롯 정의를 재정의할 수 있다. 이렇게 의미가 변경된 객체는 특이 객체 규칙에 따라 다뤄져야 한다.
자바스크립트 객체의 내부 메서드를 재정의하는 것은 저수준 작업이며,
일반 객체와 다르게 동작할 수 있으므로, 보안이나 호환성 등 꼭 필요한 경우에만 써야 한다.
현재 HTMLAllCollection
및 Location
인터페이스 정의에 사용됨. [HTML]
별도 명시 없으면, 이 절 및 다른 현행 표준에서 정의된 특이 객체(Exotic Object)는 일반 객체와 동일한 내부 슬롯을 가지며, 별도 정의가 없는 모든 내부 메서드는 일반 객체와 동일하다.
별도 명시 없으면, 이 절에서 정의된 객체의 [[Extensible]] 내부 슬롯 값은
별도 명시 없으면, 이 절에서 정의된 객체의 [[Prototype]] 내부 슬롯 값은 %Object.prototype%
이다.
이 절에서 설명하는 일부 객체는 클래스
문자열을 가진다.
클래스 문자열은 Object.prototype.toString
의 반환 문자열에 포함되는 값이다.
객체가 클래스 문자열 classString을 가지면, 생성 시점에 해당 객체는
%Symbol.toStringTag%
심볼 이름의 프로퍼티를 가져야 하며, PropertyDescriptor{[[Writable]]:
이 절의 알고리즘은 ECMAScript § 5.2 알고리즘 규칙(단계와 하위 단계, 수학 연산 등) 및 ECMA-262의 다른 부분에서 정의된 추상 연산·표기법을 따른다.
알고리즘에서
throw SomethingError
라고 하면, 이는 현재 realm에서 새로운 자바스크립트
SomethingError
객체를 생성해 throw하는 것을 의미하며, ECMA-262 알고리즘과 동일하다.
알고리즘 단계에서 다른 알고리즘이나 추상 연산을 호출하고, 그 과정에서 예외가 명시적으로 처리되지 않는 경우, 예외가 발생하면 알고리즘 실행은 중단되고 예외가 호출자에게 전달된다.
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 반환 iframeinstanceof w. Node; // false 반환 iframeinstanceof w. Object; // false 반환 iframe. appendChildinstanceof Function; // true 반환 iframe. appendChildinstanceof 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 타입의 합집합이므로, 모든 자바스크립트 값 타입에 대응될 수 있다.
자바스크립트 값 V를 IDL 값으로
변환해 IDL any
값으로 만드는 알고리즘:
-
V가
undefined 이면, 고유한undefined
IDL 값을 반환한다. -
V가
null 이면,null object?
참조를 반환한다. -
V가 숫자이면, V를 unrestricted double로 변환한 결과를 반환한다.
-
V가 BigInt이면, V를 bigint로 변환한 결과를 반환한다.
-
V가 문자열이면, V를 DOMString으로 변환한 결과를 반환한다.
-
V가 심볼이면, V를 symbol로 변환한 결과를 반환한다.
IDL any
값은
자바스크립트 값으로 변환될 때,
해당 IDL any
값의 특정 타입에 대해 아래 절에서 설명한 변환 규칙을 따른다.
3.2.2. undefined
자바스크립트 값 V를 IDL 값으로 변환해
undefined
값으로 만들 때는,
V를 무시하고 고유한 undefined
값을 반환한다.
고유한 IDL undefined
값은 자바스크립트 값으로 변환될 때 자바스크립트
3.2.3. boolean
자바스크립트 값 V를 IDL 값으로
변환해 boolean
값으로 만드는
알고리즘:
IDL boolean
값
true
는 자바스크립트
값으로 변환될 때 자바스크립트 false
는 자바스크립트
3.2.4. 정수 타입
이 절에서 사용하는 수학 연산은, ECMAScript § 5.2 알고리즘 규칙에 정의된 것 포함, 수학적 실수에 대한 정확한 수학적 결과를 의미한다.
즉, x가 Number 값일 때, “x에 대해 연산한다”는 것은 “x와 동일한 수치 값을 가진 수학적 실수에 대해 연산한다”의 약어이다.
3.2.4.1. byte
자바스크립트 값 V를 IDL 값으로
변환해 byte
값으로 만드는 알고리즘:
-
x를 ConvertToInt(V, 8, "
signed
") 결과로 둔다. -
x와 동일한 수치 값을 나타내는 IDL
byte
값을 반환한다.
IDL byte
값을 자바스크립트 값으로 변환한 결과는,
해당 IDL byte
값과 동일한 수치 값을 가진 Number이다.
Number 값은 [−128, 127] 범위의 정수다.
3.2.4.2. octet
자바스크립트 값 V를 IDL 값으로
변환해 octet
값으로 만드는 알고리즘:
-
x를 ConvertToInt(V, 8, "
unsigned
") 결과로 둔다. -
x와 동일한 수치 값을 나타내는 IDL
octet
값을 반환한다.
IDL octet
값을 자바스크립트 값으로 변환한 결과는,
해당 IDL octet
값과 동일한 수치 값을 가진
Number이다.
Number 값은 [0, 255] 범위의 정수다.
3.2.4.3. short
자바스크립트 값 V를 IDL 값으로
변환해 short
값으로 만드는 알고리즘:
-
x를 ConvertToInt(V, 16, "
signed
") 결과로 둔다. -
x와 동일한 수치 값을 나타내는 IDL
short
값을 반환한다.
IDL short
값을 자바스크립트 값으로 변환한 결과는,
해당 IDL short
값과 동일한 수치 값을 가진
Number이다.
Number 값은 [−32768, 32767] 범위의 정수다.
3.2.4.4. unsigned short
자바스크립트 값 V를 IDL 값으로
변환해 unsigned short
값으로 만드는
알고리즘:
-
x를 ConvertToInt(V, 16, "
unsigned
") 결과로 둔다. -
x와 동일한 수치 값을 나타내는 IDL
unsigned short
값을 반환한다.
IDL unsigned short
값을 자바스크립트 값으로 변환한 결과는,
해당 IDL unsigned short
값과 동일한
수치 값을 가진 Number이다.
Number 값은 [0, 65535] 범위의 정수다.
3.2.4.5. long
자바스크립트 값 V를 IDL 값으로
변환해 long
값으로 만드는 알고리즘:
-
x를 ConvertToInt(V, 32, "
signed
") 결과로 둔다. -
x와 동일한 수치 값을 나타내는 IDL
long
값을 반환한다.
IDL long
값을 자바스크립트 값으로 변환한 결과는,
해당 IDL long
값과 동일한 수치 값을 가진 Number이다.
Number 값은 [−2147483648, 2147483647] 범위의 정수다.
3.2.4.6. unsigned long
자바스크립트 값 V를 IDL 값으로
변환해 unsigned long
값으로 만드는 알고리즘:
-
x를 ConvertToInt(V, 32, "
unsigned
") 결과로 둔다. -
x와 동일한 수치 값을 나타내는 IDL
unsigned long
값을 반환한다.
IDL unsigned long
값을 자바스크립트 값으로 변환한 결과는,
해당 IDL unsigned long
값과 동일한
수치 값을 가진 Number이다.
Number 값은 [0, 4294967295] 범위의 정수다.
3.2.4.7. long long
자바스크립트 값 V를 IDL 값으로
변환해 long long
값으로 만드는
알고리즘:
-
x를 ConvertToInt(V, 64, "
signed
") 결과로 둔다. -
x와 동일한 수치 값을 나타내는 IDL
long long
값을 반환한다.
IDL long long
값을 자바스크립트 값으로 변환한 결과는,
해당 long long
값에 가장 가까운 Number
값이다. 두 값이 동일하게 가까울 경우 유효숫자가 짝수인 값을 선택한다.
long long
이 [−253 + 1,
253 − 1] 범위에 있으면 Number가 동일한 값을 정확히 표현할 수 있다.
3.2.4.8. unsigned long long
자바스크립트 값 V를 IDL 값으로
변환해 unsigned long long
값으로
만드는 알고리즘:
-
x를 ConvertToInt(V, 64, "
unsigned
") 결과로 둔다. -
x와 동일한 수치 값을 나타내는 IDL
unsigned long long
값을 반환한다.
IDL unsigned long long
값을 자바스크립트 값으로 변환한 결과는,
해당 unsigned long long
값에
가장 가까운 Number 값이다. 두 값이 동일하게 가까울 경우 유효숫자가 짝수인 값을 선택한다.
unsigned long long
이
253 − 1 이하이면 Number가 동일한 값을 정확히 표현할 수 있다.
3.2.4.9. 추상 연산
ConvertToInt(V, bitLength, signedness):
-
bitLength가 64이면:
-
upperBound를 253 − 1로 둔다.
-
signedness가 "
unsigned
"면 lowerBound를 0으로 둔다. -
그 외에는 lowerBound를 −253 + 1로 둔다.
참고: 이렇게 하면 [
EnforceRange
] 또는 [Clamp
] 확장 속성이 연관된long long
타입이 자바스크립트 Number 타입에서 모호하지 않은 정수로 표현될 수 있다.
-
-
그 외에 signedness가 "
unsigned
"면:-
lowerBound를 0으로 둔다.
-
upperBound를 2bitLength − 1로 둔다.
-
-
그 외에는:
-
lowerBound를 -2bitLength − 1로 둔다.
-
upperBound를 2bitLength − 1 − 1로 둔다.
-
-
x를 ToNumber(V) 결과로 둔다.
-
x가 −0이면 x를 +0으로 설정한다.
-
변환 대상 IDL 타입이 [
EnforceRange
] 확장 속성과 연관되어 있으면:-
x가
NaN , +∞, −∞이면 throwTypeError
. -
x를 IntegerPart(x)로 설정.
-
x < lowerBound 또는 x > upperBound면 throw
TypeError
. -
x를 반환.
-
-
x가
NaN 이 아니고 변환 대상 IDL 타입이 [Clamp
] 확장 속성과 연관되어 있으면: -
x가
NaN , +0, +∞, −∞이면 +0을 반환. -
x를 IntegerPart(x)로 설정.
-
x를 x modulo 2bitLength로 설정.
-
signedness가 "
signed
"이고 x ≥ 2bitLength − 1이면 x − 2bitLength를 반환. -
그 외에는 x를 반환.
3.2.5. float
자바스크립트 값 V를 IDL 값으로
변환해 float
값으로 만드는 알고리즘:
IDL float
값을 자바스크립트 값으로 변환한 결과는,
해당 IDL float
값과 동일한 수치 값을 가진
Number이다.
3.2.6. unrestricted float
자바스크립트 값 V를 IDL 값으로
변환해 unrestricted float
값으로
만드는 알고리즘:
-
x를 ToNumber(V) 결과로 둔다.
-
x가
NaN 이면 IEEE 754 NaN 값(bit 패턴 0x7fc00000)과 대응되는 IDLunrestricted float
값을 반환. -
S를 유한 IEEE 754 단정밀도 부동소수점 값 집합(−0 제외)에 2128, −2128 두 특수값을 추가한 집합으로 둔다.
-
y를 x에 가장 가까운 S 내 값으로 두고, 동일하게 가까울 경우 유효숫자가 짝수인 값을 선택한다. (2128, −2128도 짝수 유효숫자로 간주.)
-
y가 2128이면 +∞를 반환.
-
y가 −2128이면 −∞를 반환.
-
y가 +0이고 x가 음수면 −0을 반환.
-
y를 반환.
참고: 자바스크립트
IDL unrestricted float
값을
자바스크립트 값으로 변환한 결과는 Number:
-
해당 값이 NaN이면 Number 값도
NaN 이다. -
그 외에는 해당 IDL
unrestricted float
값과 동일한 수치 값을 가진 Number이다.
3.2.7. double
자바스크립트 값 V를 IDL 값으로
변환해 double
값으로 만드는 알고리즘:
IDL double
값을 자바스크립트 값으로 변환한 결과는,
해당 double
값과 동일한 수치 값을 가진 Number이다.
3.2.8. unrestricted double
자바스크립트 값 V를 IDL 값으로
변환해 unrestricted double
값으로 만드는 알고리즘:
-
x를 ToNumber(V) 결과로 둔다.
-
x가
NaN 이면 IEEE 754 NaN 값(bit 패턴 0x7ff8000000000000)과 대응되는 IDLunrestricted double
값을 반환. -
x와 동일한 수치 값을 나타내는 IDL
unrestricted double
값을 반환.
참고: 자바스크립트
IDL unrestricted double
값을 자바스크립트 값으로 변환한 결과는 Number:
-
해당 값이 NaN이면 Number 값도
NaN 이다. -
그 외에는 해당 IDL
unrestricted double
값과 동일한 수치 값을 가진 Number이다.
3.2.9. bigint
자바스크립트 값 V를 IDL 값으로
변환해 bigint
값으로 만드는 알고리즘:
IDL bigint
값을 자바스크립트 값으로 변환한 결과는 BigInt:
-
해당 IDL
bigint
값과 동일한 수치 값을 가진BigInt
값을 반환.
3.2.10. DOMString
자바스크립트 값 V를 IDL 값으로
변환해 DOMString
값으로 만드는
알고리즘:
-
V가
null 이고, 변환 대상 IDL 타입이 [LegacyNullToEmptyString
] 확장 속성과 연관되어 있으면, 빈 문자열을 나타내는DOMString
값을 반환한다. -
x를 ToString(V) 결과로 둔다.
-
x와 동일한 코드 유닛 시퀀스를 나타내는 IDL
DOMString
값을 반환한다.
IDL DOMString
값을 자바스크립트 값으로 변환한 결과는,
해당 DOMString
과 동일한 코드 유닛 시퀀스를 나타내는 String 값이다.
3.2.11. ByteString
자바스크립트 값 V를 IDL 값으로
변환해 ByteString
값으로
만드는 알고리즘:
-
x를 ToString(V) 결과로 둔다.
-
x와 길이가 같고 각 요소 값이 x의 해당 요소와 동일한 IDL
ByteString
값을 반환.
IDL ByteString
값을 자바스크립트 값으로 변환한 결과는,
해당 ByteString
과 길이가 같고 각 요소 값이
ByteString의 해당 요소와 동일한 String 값이다.
3.2.12. USVString
자바스크립트 값 V를 IDL 값으로
변환해 USVString
값으로 만드는
알고리즘:
-
string을 자바스크립트 문자열 변환을 통해 스칼라 값 시퀀스로 변환한 결과인 IDL
USVString
값을 반환.
IDL USVString
값 S를
자바스크립트 값으로 변환한 결과는 S
자체다.
3.2.13. object
IDL object
값은 자바스크립트 Object 값으로 표현된다.
자바스크립트 값 V를 IDL 값으로
변환해 object
값으로 만드는 알고리즘:
IDL object
값을 자바스크립트 값으로 변환한 결과는,
해당 object
가 참조하는 동일 객체를 나타내는 Object
값이다.
3.2.14. symbol
IDL symbol
값은 자바스크립트 Symbol 값으로 표현된다.
symbol
값으로 만드는 알고리즘:
-
V가 Symbol이 아니면 throw
TypeError
. -
V와 동일 심볼을 참조하는 IDL
symbol
값을 반환.
IDL symbol
값을 자바스크립트 값으로 변환한 결과는,
해당 symbol
과 동일 심볼을 참조하는 Symbol 값이다.
3.2.15. 인터페이스 타입
IDL 인터페이스 타입 값은 자바스크립트 Object 값(함수 객체 포함)으로 표현된다.
자바스크립트 값 V를 IDL 값으로 변환해 인터페이스 타입 값으로 만드는 알고리즘(I는 해당 인터페이스):
IDL 인터페이스 타입 값을 자바스크립트 값으로 변환한 결과는, 해당 인터페이스 타입 값이 참조하는 동일 객체를 나타내는 Object 값이다.
3.2.16. 콜백 인터페이스 타입
IDL 콜백 인터페이스 타입 값은 자바스크립트 Object 값(함수 객체 포함)으로 표현된다.
자바스크립트 값 V를 IDL 값으로 변환해 콜백 인터페이스 타입 값으로 만드는 알고리즘:
-
V를 참조하고, incumbent settings object를 콜백 컨텍스트로 하는 IDL 콜백 인터페이스 타입 값을 반환.
IDL 콜백 인터페이스 타입 값을 자바스크립트 값으로 변환한 결과는, 해당 콜백 인터페이스 타입 값이 참조하는 동일 객체를 나타내는 Object 값이다.
3.2.17. 딕셔너리 타입
IDL 딕셔너리 타입 값은 자바스크립트 Object 값으로 표현된다. 객체(또는 프로토타입 체인)상의 프로퍼티가 딕셔너리 멤버에 대응한다.
자바스크립트 값 jsDict를 IDL 값으로 변환해 딕셔너리 타입 값으로 만드는 알고리즘(D는 해당 딕셔너리 타입):
-
idlDict를 순서가 있는 맵의 빈 맵으로 둔다(타입 D의 딕셔너리).
-
dictionaries를 D와 D의 모든 상속 딕셔너리를 가장 덜 파생된 것부터 가장 많이 파생된 것까지 포함하는 리스트로 둔다.
-
dictionaries의 각 dictionary에 대해, 순서대로:
-
dictionary에 선언된 각 딕셔너리 멤버 member에 대해, 사전순으로:
-
key를 member의 식별자로 둔다.
-
jsDict가
undefined 나null 이면:-
jsMemberValue를
undefined 로 둔다.
-
-
그 외에는,
-
jsMemberValue를 Get(jsDict, key) 결과로 둔다.
-
-
jsMemberValue가
undefined 가 아니면: -
그 외에 jsMemberValue가
undefined 이고 member에 기본값이 있으면:-
idlMemberValue를 member의 기본값으로 둔다.
-
Set idlDict[key] = idlMemberValue로 한다.
-
-
그 외에 jsMemberValue가
undefined 이고 member가 필수면TypeError
를 throw.
-
-
-
idlDict를 반환.
참고: 자바스크립트 객체에서 딕셔너리 멤버 조회 순서는 객체의 프로퍼티 열거 순서와 반드시 같지 않다.
IDL 딕셔너리 값 V를 자바스크립트 값으로 변환해 Object 값으로 만드는 알고리즘(D는 해당 딕셔너리):
-
O를 OrdinaryObjectCreate(
%Object.prototype%
)로 둔다. -
dictionaries를 D와 D의 모든 상속 딕셔너리를 가장 덜 파생된 것부터 가장 많이 파생된 것까지 포함하는 리스트로 둔다.
-
dictionaries의 각 dictionary에 대해, 순서대로:
-
O를 반환.
3.2.18. 열거형 타입
IDL 열거형 타입은 자바스크립트 String 값으로 표현된다.
자바스크립트 값 V를 IDL 값으로 변환해 열거형 타입 값으로 만드는 방법(E는 해당 열거형):
IDL 열거형 타입 값을 자바스크립트 값으로 변환한 결과는, 해당 열거형 값과 동일한 코드 유닛 시퀀스를 나타내는 String 값이다.
3.2.19. 콜백 함수 타입
IDL 콜백 함수 타입은 자바스크립트 함수
객체로 표현된다. 단, [LegacyTreatNonObjectAsNull
]이
붙은 경우에는 아무 객체나 될 수 있다.
자바스크립트 값 V를 IDL 값으로 변환해 콜백 함수 타입 값으로 만드는 알고리즘:
-
IsCallable(V)이
false 이고, 변환 대상이 [LegacyTreatNonObjectAsNull
]이 붙은 nullable 콜백 함수 타입 속성에 할당되는 경우가 아니면 throwTypeError
. -
V가 참조하는 동일 객체를 참조하고, incumbent settings object를 콜백 컨텍스트로 하는 IDL 콜백 함수 타입 값을 반환.
IDL 콜백 함수 타입 값을 자바스크립트 값으로 변환한 결과는, 해당 콜백 함수 타입 값이 참조하는 동일 객체를 나타내는 값이다.
3.2.20. 널 허용 타입 — T?
IDL 널 허용 타입 값은
내부 IDL 타입에 대응되는 자바스크립트 타입 값 또는 자바스크립트
자바스크립트 값 V를 IDL 값으로
변환해 널 허용 타입 T?
값으로 만드는 방법(T는 내부 타입):
-
V가 객체가 아니고 변환 대상이 [
LegacyTreatNonObjectAsNull
]이 붙은 널 허용 콜백 함수 타입 속성에 할당되는 경우면,null 을 반환. -
그 외에 V가
undefined 이고, T가 undefined 포함이면, 고유한undefined
값을 반환. -
그 외에 V가
null 또는undefined 이면null 을 반환. -
그 외에는 T 타입의 변환 규칙으로 V를 변환한 결과를 반환.
IDL 널 허용 타입 값을 자바스크립트 값으로 변환한 결과는:
-
값이
null 이면 자바스크립트 값도null 이다. -
그 외에는 내부 타입 변환 규칙에 따라 변환한 결과이다.
3.2.21. 시퀀스 — sequence<T>
IDL sequence<T> 값은 자바스크립트 Array 값으로 표현된다.
자바스크립트 값 V를 IDL 값으로 변환해 sequence<T> 값으로 만드는 방법:
sequence<T> 타입의 IDL 시퀀스 값 S를 자바스크립트 Array 객체로 변환하는 방법:
-
n을 S의 길이로 둔다.
-
A를
[]
식으로 생성한 새 Array 객체로 둔다. -
i를 0으로 초기화.
-
i < n 동안:
-
V를 S의 인덱스 i의 값으로 둔다.
-
E를 V를 자바스크립트 값으로 변환한 결과로 둔다.
-
P를 ToString(i) 결과로 둔다.
-
CreateDataPropertyOrThrow(A, P, E)을 수행.
-
i를 i + 1로 설정.
-
-
A를 반환.
3.2.21.1. 이터러블에서 시퀀스 생성하기
이터러블 iterable과 이터레이터 getter method가 주어졌을 때, sequence<T> 타입의 IDL 값을 생성하려면 다음 단계를 수행한다:
-
iteratorRecord를 ? GetIteratorFromMethod(iterable, method)로 설정한다.
-
i를 0으로 초기화한다.
-
반복한다
-
next를 ? IteratorStepValue(iteratorRecord)로 설정한다.
-
next가
done 이면, i 길이의 sequence<T> 타입의 IDL 시퀀스 값을 반환한다. 이때 인덱스 j의 요소 값은 Sj이다. -
Si를 next를 T 타입의 IDL 값으로 변환한 결과로 초기화한다.
-
i를 i + 1로 설정한다.
-
다음 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 값은 다음 struct의 items로 표현된다:
-
object, JavaScript 값
-
method, JavaScript 값
-
type, "
sync
" 또는 "async
"
-
V가 Object가 아니면, TypeError를
throw
한다. -
method를 ? GetMethod(obj,
%Symbol.asyncIterator%
)로 설정한다. -
method가
undefined 일 경우:-
syncMethod를 ? GetMethod(obj,
%Symbol.iterator%
)로 설정한다. -
IDL async sequence 값을 반환한다. object는 V, method는 syncMethod, type은 "
sync
"로 설정된다.
-
-
IDL async sequence 값을 반환한다. object는 V, method는 method, type 은 "
async
"로 설정된다.
3.2.22.1. 비동기 시퀀스 반복
비동기 시퀀스는 직접적으로 반복되지 않는다. 대신 먼저 열어서 비동기 이터레이터를 생성한다. 비동기 이터레이터는 비동기적으로 반복하여 값을 생성할 수 있다.
비동기 이터레이터들은 구조체이며, 다음 항목들을 가진다:
-
underlying record, Iterator Record
-
type parameter, 비동기 이터레이터가 생성하는 값의 타입을 나타내는 IDL 타입
비동기 시퀀스 열기를 위해
async_sequence<T>
sequence에 대해:
-
iterator를 ? GetIteratorFromMethod(sequence의 object, sequence의 method)로 설정한다.
-
sequence의 type이 "
sync
"이면, iterator를 CreateAsyncFromSyncIterator(iterator)로 설정한다. -
비동기 이터레이터 값을 반환하는데, underlying record는 iterator로, type parameter는 T로 설정한다.
비동기 이터레이터의 다음 값 구하기를 위해 비동기 이터레이터 iterator에 대해:
-
nextResult를 IteratorNext(iterator의 underlying record)로 설정한다.
-
nextResult가 abrupt completion이면, 거부된 프라미스 nextResult.[[Value]]를 반환한다.
-
nextPromise를 해결된 프라미스 nextResult.[[Value]]로 설정한다.
-
nextPromise에 대해 반응한 결과를 반환하는데, 이때 iterResult를 인자로 한다:
-
done을 ? IteratorComplete(iterResult)로 설정한다.
-
done이 true이면:
-
반복 종료를 반환한다.
-
-
그 외의 경우:
-
V를 ? IteratorValue(iterResult)로 설정한다.
-
value를 변환 V를 iterator의 type parameter 타입의 IDL 값으로 변환한 결과로 설정한다.
-
value를 반환한다.
-
비동기 이터레이터 닫기를 위해
async iterator<T>
iterator,
ECMAScript 값 reason과 함께:
-
iteratorRecord를 iterator의 underlying record로 설정한다.
-
iteratorObj를 iteratorRecord.[[Iterator]]로 설정한다.
-
returnMethod를 GetMethod(iteratorObj, "
return
")로 설정한다. -
returnMethod가 abrupt completion이면, 거부된 프라미스 returnMethod.[[Value]]를 반환한다.
-
returnResult를 Call(returnMethod.[[Value]], iteratorObj, « reason »)로 설정한다.
-
returnResult가 abrupt completion이면, 거부된 프라미스 returnResult.[[Value]]를 반환한다.
-
returnPromise를 해결된 프라미스 returnResult.[[Value]]로 설정한다.
-
returnPromise에 대해 반응한 결과를 반환하는데, returnPromiseResult를 인자로 한다:
concatN
은 operation이며, 비동기 시퀀스에서 생성된 모든 문자열을 연결한 값을 프라미스로 반환한다. 이 연결은 비동기
시퀀스가 maxN개의 문자열을 생성하면 중단되고 이터레이터를 닫는다.
interface I { Promise<DOMString> concatN(async_sequence<DOMString> strings, unsigned long maxN); };
concatN(sequence, maxN)
메서드 단계:
-
promise를 새로운 프라미스로 설정한다.
-
result를 빈 문자열로 설정한다.
-
n을 0으로 설정한다.
-
iterator를 비동기 시퀀스 열기의 결과로 sequence에 대해 생성한다.
-
step을 비동기 시퀀스를 처리할 단계들의 시퀀스로 설정한다:
-
next를 비동기 이터레이터의 다음 값 구하기의 결과로 iterator에 대해 얻는다.
-
반응하여 next를 처리한다:
-
next가 값 v로 이행되었다면:
-
next가 r로 거부되었다면, reject하여 promise를 r로 거부한다.
-
-
-
step을 호출한다.
-
promise를 반환한다.
3.2.23. 레코드 — record<K, V>
IDL record<K, V> 값은 자바스크립트 객체 값으로 표현됩니다.
자바스크립트 값 O는 변환되어
IDL
record<K, V>
값으로 처리됩니다. 다음과 같은 절차를 따릅니다:
-
result를
record<K, V>
의 새로운 빈 인스턴스로 설정합니다. -
keys를 ? O.[[OwnPropertyKeys]]()로 설정합니다.
-
각 keys의 key에 대해:
-
desc를 ? O.[[GetOwnProperty]](key)로 설정합니다.
-
desc가
undefined 가 아니고, desc.[[Enumerable]]가true 일 경우:-
typedKey를 key IDL 값으로 변환 하여 타입 K로 처리합니다.
-
typedValue를 value IDL 값으로 변환 하여 타입 V로 처리합니다.
-
result[typedKey]에 typedValue를 설정합니다.
참고: K가
USVString
이고 key에 짝이 없는 대리문자가 포함된 경우, typedKey가 이미 result에 있을 수 있습니다.
-
-
-
result를 반환합니다.
IDL
record<…>
값 D는
변환되어
자바스크립트 값으로 다음과 같이 처리됩니다:
-
result를 OrdinaryObjectCreate(
%Object.prototype%
)의 결과로 설정합니다. -
각 D의 key → value 쌍에 대해:
-
jsKey를 key 자바스크립트 값으로 변환합니다.
-
jsValue를 value 자바스크립트 값으로 변환합니다.
-
created를 ! CreateDataProperty(result, jsKey, jsValue)의 결과로 설정합니다.
-
Assert: created는
true 입니다.
-
-
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>
값으로 처리됩니다. 절차는 다음과 같습니다:
-
promiseCapability를 ? NewPromiseCapability(
%Promise%
)로 설정합니다. -
? Call(promiseCapability.[[Resolve]],
undefined , « V »)를 수행합니다. -
promiseCapability를 반환합니다.
IDL promise 타입 값을 자바스크립트 값으로 변환한 결과는, 해당 레코드가 표현하는 [[Promise]] 필드의 값입니다.
3.2.24.1. Promise 생성 및 조작
새로운 promise 생성을
Promise<T>
타입으로 realm realm에서 생성하려면, 다음 단계를 수행합니다:
-
constructor를 realm.[[Intrinsics]].[[
%Promise%
]]로 설정합니다. -
? NewPromiseCapability(constructor)를 반환합니다.
해결된 promise 생성을
Promise<T>
타입으로 x (타입 T의 값)와 함께 realm realm에서 생성하려면, 다음 단계를 수행합니다:
-
value를 자바스크립트 값으로 변환한 x의 결과로 설정합니다.
-
constructor를 realm.[[Intrinsics]].[[
%Promise%
]]로 설정합니다. -
promiseCapability를 ? NewPromiseCapability(constructor)로 설정합니다.
-
! Call(promiseCapability.[[Resolve]],
undefined , « value »)를 수행합니다. -
promiseCapability를 반환합니다.
거부된 promise 생성을
Promise<T>
타입으로 reason r (자바스크립트 값)과 함께 realm realm에서 생성하려면, 다음 단계를 수행합니다:
-
constructor를 realm.[[Intrinsics]].[[
%Promise%
]]로 설정합니다. -
promiseCapability를 ? NewPromiseCapability(constructor)로 설정합니다.
-
! Call(promiseCapability.[[Reject]],
undefined , « r »)를 수행합니다. -
promiseCapability를 반환합니다.
resolve를
Promise<T>
p에 x (타입 T의 값)로 하려면, 다음 단계를 수행합니다:
-
x가 주어지지 않았다면,
undefined
값으로 설정합니다. -
value를 자바스크립트 값으로 변환한 x의 결과로 설정합니다.
T가 undefined
인 경우, x 인자는 생략할 수 있으므로 더 간단한 "resolve p" 사용이 가능합니다.
reject를
Promise<T>
p에 reason r (자바스크립트 값)으로 하려면, 다음 단계를 수행합니다:
react를
Promise<T>
promise에 대해, promise가 이행되거나 거부되었을 때 수행할 1~2개의 단계 집합을 받아, 다음 단계를 수행합니다:
-
onFulfilledSteps를 다음 단계로 설정합니다. 인자로 V를 받습니다:
-
value를 IDL 값으로 변환한 V (타입 T)로 설정합니다.
-
promise가 이행되었을 때 실행할 단계가 있다면, result를 해당 단계를 수행한 결과로 설정합니다. T가
undefined
가 아니면 value를 인자로 전달합니다. 그렇지 않으면 result를 value로 설정합니다. -
result를 자바스크립트 값으로 변환하여 반환합니다.
-
-
onFulfilled를 CreateBuiltinFunction(onFulfilledSteps, « »)로 설정합니다:
-
onRejectedSteps를 다음 단계로 설정합니다. 인자로 R를 받습니다:
-
reason를 IDL 값으로 변환한 R (타입
any
)로 설정합니다. -
promise가 거부되었을 때 실행할 단계가 있다면, result를 해당 단계를 수행한 결과로 설정합니다. 그렇지 않으면 result를 거부된 promise 생성 reason으로 설정합니다.
-
result를 자바스크립트 값으로 변환하여 반환합니다.
-
-
onRejected를 CreateBuiltinFunction(onRejectedSteps, « »)로 설정합니다:
-
constructor를 promise.[[Promise]].[[Realm]].[[Intrinsics]].[[
%Promise%
]]로 설정합니다. -
newCapability를 ? NewPromiseCapability(constructor)로 설정합니다.
참고: 모든 호출자가 반환된
Promise
를 사용할 필요는 없습니다. 구현체는 newCapability 생성 생략을 고려할 수 있습니다. -
PerformPromiseThen(promise.[[Promise]], onFulfilled, onRejected, newCapability)를 수행합니다.
-
newCapability를 반환합니다.
참고: 이 알고리즘은
promise.then()
메서드와 매우 유사하게 동작합니다.
특히, 단계에서 U 타입이나
Promise<U>
값을 반환하는 경우,
이 알고리즘 역시
Promise<U>
를 반환합니다.
어떤 단계 이행 시 수행를
Promise<T>
promise가 이행될 때, 타입 T 값을 받는 단계 steps로 다음을 수행합니다:
-
react를 promise에 대해 호출한 결과를 반환합니다:
-
promise가 값 v로 이행되었다면:
-
steps를 v로 수행합니다.
-
-
어떤 단계 거부 시 수행를
Promise<T>
promise가 거부될 때, 자바스크립트 값을 받는 단계 steps로 다음을 수행합니다:
-
react를 promise에 대해 호출한 결과를 반환합니다:
-
promise가 reason r로 거부되었다면:
-
steps를 r로 수행합니다.
-
-
모두 대기(wait for all)를
list 타입인
Promise<T>
값 promises에 대해,
list 타입
T 값을 받는 성공 단계 successSteps와
거부 reason any
값을 받는 실패
단계 failureSteps로 다음을 수행합니다:
-
fullfilledCount를 0으로 설정합니다.
-
rejected를 false로 설정합니다.
-
rejectionHandlerSteps를 다음 단계로 설정합니다. 인자로 arg를 받습니다:
-
rejected가 true이면 이 단계들을 중단합니다.
-
rejected를 true로 설정합니다.
-
failureSteps를 arg로 수행합니다.
-
-
rejectionHandler를 CreateBuiltinFunction(rejectionHandlerSteps, « »)로 설정합니다:
-
total을 promises의 size로 설정합니다.
-
total이 0이면:
-
마이크로태스크 큐에 successSteps를 « »로 수행하도록 추가합니다.
-
반환합니다.
-
-
index를 0으로 설정합니다.
-
result를 list 타입으로, total 개의 null 값으로 초기화합니다.
-
각 promises의 promise에 대해:
-
promiseIndex를 index로 설정합니다.
-
fulfillmentHandler를 다음 단계로 설정합니다. 인자로 arg를 받습니다:
-
result[promiseIndex]에 arg를 설정합니다.
-
fullfilledCount를 fullfilledCount+1로 설정합니다.
-
fullfilledCount가 total과 같으면, successSteps를 result로 수행합니다.
-
-
fulfillmentHandler를 CreateBuiltinFunction(fulfillmentHandler, « »)로 설정합니다:
-
PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler)를 수행합니다.
-
index를 index+1로 설정합니다.
-
모두 기다리는 promise 얻기를
list 타입
Promise<T>
값 promises와
realm realm에 대해 얻으려면, 다음 단계를 수행합니다:
-
promise를 새로운 promise 생성으로
Promise<sequence<T>>
타입으로 realm에서 생성합니다. -
successSteps를 다음 단계로 설정합니다. 인자로 results를 받습니다:
-
resolve promise를 results로 수행합니다.
-
-
failureSteps를 다음 단계로 설정합니다. 인자로 reason을 받습니다:
-
reject promise 를 reason으로 수행합니다.
-
-
모두 대기(wait for all)를 promises와 successSteps, failureSteps로 수행합니다.
-
promise를 반환합니다.
이 정의는 여러 promise의 결과를 집계한 뒤, 그 결과로 또 다른 promise를 생성하고 싶을 때 유용합니다. JavaScript의
Promise.all()
과 같은 방식입니다. 또 다른 promise를 생성할 필요가 없다면 모두 대기(waiting for all)가 더 적합할 수 있습니다.
Promise<T>
promise의
promise.[[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 ); };
validatedDelay
연산은 delay 함수와 유사하지만, 인자를
검증합니다.
이 예시는 비동기 작업을 시작하기 전에 즉시 실패를 알릴 때 rejected promise를 어떻게 사용하는지 보여줍니다.
interface I {Promise <undefined >validatedDelay (unrestricted double ms ); };
validatedDelay(ms)
메서드 단계:
-
taskSource를 적절한 태스크 소스로 설정한다.
-
ms가 NaN이면 거부된 promise
TypeError
를 realm에서 반환한다. -
ms < 0이면 거부된 promise
RangeError
를 realm에서 반환한다. -
p를 새로운 promise로 realm에서 생성한다.
-
다음 단계를 병렬로 실행한다:
-
p를 반환한다.
addDelay
는 연산이며, promise가 settle된 후 반환 promise가 settle되기까지 추가 밀리초
지연을 제공합니다.
interface I {Promise <any >addDelay (Promise <any >promise ,unrestricted double ms ); };
addDelay(ms, promise)
메서드 단계:
-
taskSource를 적절한 태스크 소스로 설정한다.
-
ms가 NaN이면 ms를 +0으로, 아니면 ms와 +0 중 더 큰 값으로 ms를 설정한다.
-
p를 새로운 promise로 realm에서 생성한다.
-
React를 promise에 대해 수행한다:
-
p를 반환한다.
environment.ready
는 특성(attribute)이며, 환경(예: DOM 문서)의 일부가 "준비됨" 상태가 되었음을 알립니다.
환경 비동기성을 표현하는 방법을 보여줍니다.
interface Environment {readonly attribute Promise <undefined >ready ; };
모든 Environment
객체는 ready promise를 가져야 하며,
이 값은
Promise<undefined>
이다.
ready
특성 getter 단계:
-
this의 ready promise를 반환한다.
Environment
객체를 realm realm에서 생성하려면, 다음 단계를 수행합니다:
-
taskSource를 적절한 태스크 소스로 설정한다.
-
environment를 새로운
Environment
객체로 realm에서 생성한다. -
environment의 ready promise를 새로운 promise로 realm에서 설정한다.
-
다음 단계를 병렬로 실행한다:
-
비동기 작업 수행.
-
environment가 정상적으로 ready가 되면, 태스크 큐에 등록하여 taskSource에 resolve environment의 ready promise를 수행한다.
-
environment가 ready가 되지 못하면, 태스크 큐에 등록하여 taskSource에 reject environment의 ready promise를 "
NetworkError
"DOMException
으로 거부한다.
-
-
environment를 반환한다.
addBookmark
는 연산이며, 사용자에게 현재 웹페이지를 북마크에 추가해달라고 요청합니다.
실제 디자인 작업에서 파생된 예시로,
환경 비동기성과 즉시 거부를 다루는 현실적인 시나리오를 보여줍니다.
interface I {Promise <undefined >addBookmark (); };
addBookmark()
메서드 단계:
-
taskSource를 적절한 태스크 소스로 설정한다.
-
이 메서드가 명시적 사용자 동작의 결과로 호출되지 않았다면, 거부된 promise를 "
SecurityError
"DOMException
으로 반환한다. -
문서의 동작 모드가 standalone이면 거부된 promise를 "
NotSupportedError
"DOMException
으로 반환한다. -
promise를 새로운 promise로 생성한다.
-
info를 웹 애플리케이션의 메타데이터를 얻은 결과로 설정한다.
-
다음 단계를 병렬로 실행한다:
-
info를 활용하여, 사용자 에이전트별 방식으로 최종 사용자가 북마크 추가 여부를 선택하도록 한다.
-
최종 사용자가 북마크 추가 요청을 중단(예: ESC 키, 취소 버튼 등)하면, 태스크 큐에 등록하여 taskSource에 reject promise를 "
AbortError
"DOMException
으로 수행한다.
-
-
-
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)
메서드 단계:
-
responsePromises를 « »로 설정한다.
-
각 urls의 url에 대해:
-
p를 모두 기다리는 promise 얻기로 responsePromises에 대해 호출한 결과로 설정한다.
-
p를 반환한다.
3.2.25. Union 타입
IDL union 타입 값은 해당 union의 멤버 타입에 해당하는 자바스크립트 값으로 표현됩니다.
자바스크립트 값 V를 IDL union 타입 값으로 변환하려면 다음과 같이 합니다:
-
union 타입이 undefined를 포함하고 V가
undefined 라면, 고유한undefined
값을 반환합니다. -
union 타입이 nullable 타입을 포함하고 V가
null 또는undefined 라면, IDL 값null 을 반환합니다. -
types를 union 타입의 평탄화된 멤버 타입으로 설정합니다.
-
V가
null 또는undefined 라면:-
types에 dictionary 타입이 포함되어 있다면, V를 해당 dictionary 타입으로 변환한 결과를 반환합니다.
-
-
V가 플랫폼 객체라면:
-
types에 interface 타입이 포함되어 있고 V가 이를 구현한다면, V 객체를 참조하는 IDL 값을 반환합니다.
-
types에
object
가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.
-
-
V가 Object이며, [[ArrayBufferData]] 내부 슬롯이 있고, IsSharedArrayBuffer(V)가 false라면:
-
types에
ArrayBuffer
가 포함되어 있다면, V를ArrayBuffer
로 변환한 결과를 반환합니다. -
types에
object
가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.
-
-
V가 Object이며, [[ArrayBufferData]] 내부 슬롯이 있고, IsSharedArrayBuffer(V)가 true라면:
-
types에
SharedArrayBuffer
가 포함되어 있다면, V를SharedArrayBuffer
로 변환한 결과를 반환합니다. -
types에
object
가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.
-
-
V가 Object이며, [[TypedArrayName]] 내부 슬롯이 있다면:
-
types에 typed array 타입이 포함되어 있고, 해당 타입 이름이 V의 [[TypedArrayName]] 내부 슬롯의 값과 같다면, V를 해당 타입으로 변환한 결과를 반환합니다.
-
types에
object
가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.
-
-
IsCallable(V)가 true라면:
-
types에 callback function 타입이 포함되어 있다면, V를 해당 callback function 타입으로 변환한 결과를 반환합니다.
-
types에
object
가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.
-
-
V가 Object라면:
-
types에 async sequence 타입이 포함되어 있다면
-
types에 string 타입이 포함되어 있지 않거나, V에 [[StringData]] 내부 슬롯이 없다면,
-
asyncMethod를 ? GetMethod(V,
%Symbol.asyncIterator%
)로 설정합니다. -
asyncMethod가
undefined 가 아니면, IDL async sequence 값을 반환합니다. object는 V, method는 syncMethod, type은 "async
"로 설정합니다. -
syncMethod를 ? GetMethod(V,
%Symbol.iterator%
)로 설정합니다. -
syncMethod가
undefined 가 아니면, IDL async sequence 값을 반환합니다. object는 V, method는 syncMethod, type은 "sync
"로 설정합니다.
-
-
-
types에 sequence 타입이 포함되어 있다면
-
method를 ? GetMethod(V,
%Symbol.iterator%
)로 설정합니다. -
method가
undefined 가 아니면, 해당 타입의 시퀀스 생성 결과를 V와 method로 반환합니다.
-
-
types에 frozen array 타입이 포함되어 있다면
-
method를 ? GetMethod(V,
%Symbol.iterator%
)로 설정합니다. -
method가
undefined 가 아니면, 해당 타입의 frozen array 생성 결과를 V와 method로 반환합니다.
-
-
types에 dictionary 타입이 포함되어 있다면, V를 해당 dictionary 타입으로 변환한 결과를 반환합니다.
-
types에 record 타입이 포함되어 있다면, V를 해당 record 타입으로 변환한 결과를 반환합니다.
-
types에 callback interface 타입이 포함되어 있다면, V를 해당 callback interface 타입으로 변환한 결과를 반환합니다.
-
types에
object
가 포함되어 있다면, V 객체를 참조하는 IDL 값을 반환합니다.
-
-
V가 Boolean 타입이라면:
-
V가 Number 타입이라면:
-
types에 numeric 타입이 포함되어 있다면, V를 해당 numeric 타입으로 변환한 결과를 반환합니다.
-
-
V가 BigInt 타입이라면:
-
types에 numeric 타입과
bigint
가 포함되어 있다면, V를 해당 numeric 타입 또는bigint
로 변환한 결과를 반환합니다. -
types에 numeric 타입이 포함되어 있다면, V를 해당 numeric 타입으로 변환한 결과를 반환합니다.
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 타입 값은 해당하는 자바스크립트 클래스의 객체로 표현되며, 다음의 추가적인 제약이 있습니다.
-
타입이 [
AllowResizable
] 또는 [AllowShared
] 확장 어트리뷰트와 연관되지 않은 경우라면, 자바스크립트ArrayBuffer
객체 V에서만 지원되며, IsResizableArrayBuffer(V)가 false여야 합니다. -
타입이 [
AllowResizable
] 확장 어트리뷰트와 연관되고, [AllowShared
] 확장 어트리뷰트와는 연관되지 않은 경우, 자바스크립트ArrayBuffer
객체만 지원합니다. -
타입이 [
AllowShared
] 확장 어트리뷰트와 연관되고, [AllowResizable
] 확장 어트리뷰트와는 연관되지 않은 경우, 자바스크립트ArrayBuffer
및SharedArrayBuffer
객체 V에서만 지원되며, IsResizableArrayBuffer(V)가 false여야 합니다. -
타입이 [
AllowResizable
]와 [AllowShared
] 확장 어트리뷰트 모두와 연관된 경우, 모든 자바스크립트ArrayBuffer
또는SharedArrayBuffer
객체가 지원됩니다.
자바스크립트 값 V를 IDL ArrayBuffer
값으로 변환하려면 다음 알고리즘을 실행합니다:
-
V가 객체가 아니거나, [[ArrayBufferData]] 내부 슬롯이 없으면 TypeError를 throw합니다.
-
IsSharedArrayBuffer(V)가 true이면 TypeError를 throw합니다.
-
변환 대상이 [
AllowResizable
] 확장 어트리뷰트와 연관된 타입이 아니고, IsResizableArrayBuffer(V)가 true이면 TypeError를 throw합니다. -
V와 같은 객체를 참조하는 IDL
ArrayBuffer
값을 반환합니다.
자바스크립트 값 V를 IDL SharedArrayBuffer
값으로 변환하려면 다음 알고리즘을 실행합니다:
-
V가 객체가 아니거나, [[ArrayBufferData]] 내부 슬롯이 없으면 TypeError를 throw합니다.
-
IsSharedArrayBuffer(V)가 false이면 TypeError를 throw합니다.
-
변환 대상이 [
AllowResizable
] 확장 어트리뷰트와 연관된 타입이 아니고, IsResizableArrayBuffer(V)가 true이면 TypeError를 throw합니다. -
V와 같은 객체를 참조하는 IDL
SharedArrayBuffer
값을 반환합니다.
자바스크립트 값 V를 IDL DataView
값으로 변환하려면 다음 알고리즘을 실행합니다:
-
V가 객체가 아니거나, [[DataView]] 내부 슬롯이 없으면 TypeError를 throw합니다.
-
변환 대상이 [
AllowShared
] 확장 어트리뷰트와 연관된 타입이 아니고, IsSharedArrayBuffer(V.[[ViewedArrayBuffer]])가 true이면 TypeError를 throw합니다. -
변환 대상이 [
AllowResizable
] 확장 어트리뷰트와 연관된 타입이 아니고, IsResizableArrayBuffer(V.[[ViewedArrayBuffer]])가 true이면 TypeError를 throw합니다. -
V와 같은 객체를 참조하는 IDL
DataView
값을 반환합니다.
자바스크립트 값 V를
변환하여
IDL Int8Array
,
Int16Array
,
Int32Array
,
Uint8Array
,
Uint16Array
,
Uint32Array
,
Uint8ClampedArray
,
BigInt64Array
,
BigUint64Array
,
Float16Array
,
Float32Array
,
Float64Array
값으로 변환하려면 다음 알고리즘을 실행합니다:
-
T를 변환 대상 IDL 타입으로 설정합니다.
-
V가 객체가 아니거나, [[TypedArrayName]] 내부 슬롯이 T의 이름과 같지 않으면 TypeError를 throw합니다.
-
변환 대상이 [
AllowShared
] 확장 어트리뷰트와 연관된 타입이 아니고, IsSharedArrayBuffer(V.[[ViewedArrayBuffer]])가 true이면 TypeError를 throw합니다. -
변환 대상이 [
AllowResizable
] 확장 어트리뷰트와 연관된 타입이 아니고, IsResizableArrayBuffer(V.[[ViewedArrayBuffer]])가 true이면 TypeError를 throw합니다. -
V와 같은 객체를 참조하는 타입 T의 IDL 값을 반환합니다.
ArrayBuffer
를
바이트
시퀀스
bytes와 realm realm에서 생성합니다:
-
jsArrayBuffer를 ? AllocateArrayBuffer(realm.[[Intrinsics]].[[
%ArrayBuffer%
]], bytes의 길이)로 설정합니다. -
arrayBuffer를 변환을 통해 jsArrayBuffer를
ArrayBuffer
타입의 IDL 값으로 변환합니다. -
arrayBuffer를 반환합니다.
SharedArrayBuffer
를
바이트
시퀀스 bytes와 realm realm에서 생성합니다:
-
jsSharedArrayBuffer를 ? AllocateSharedArrayBuffer(realm.[[Intrinsics]].[[
%SharedArrayBuffer%
]], bytes의 길이)로 설정합니다. -
sharedArrayBuffer를 변환을 통해 jsSharedArrayBuffer를
SharedArrayBuffer
타입의 IDL 값으로 변환합니다. -
sharedArrayBuffer를 반환합니다.
ArrayBufferView
타입 중 하나를
바이트
시퀀스 bytes와 realm realm에서 생성합니다:
-
단, 타입이
DataView
가 아니라면, bytes의 길이를 해당 타입의 요소 크기로 나눈 나머지가 0이어야 합니다. -
arrayBuffer를 생성을 통해
ArrayBuffer
로 bytes와 realm에서 생성합니다. -
jsArrayBuffer를 변환을 통해 arrayBuffer를 자바스크립트 값으로 변환합니다.
-
constructor를 realm.[[Intrinsics]]에서 생성할
ArrayBufferView
타입에 맞는 생성자로 설정합니다. -
변환을 통해 jsView를 해당 타입으로 변환한 결과를 반환합니다.
-
jsBufferSource를 변환을 통해 bufferSource를 자바스크립트 값으로 변환합니다.
-
jsArrayBuffer를 jsBufferSource로 설정합니다.
-
offset을 0으로 설정합니다.
-
length을 0으로 설정합니다.
-
jsBufferSource가 [[ViewedArrayBuffer]] 내부 슬롯을 가지면:
-
jsArrayBuffer를 jsBufferSource.[[ViewedArrayBuffer]]로 설정합니다.
-
offset을 jsBufferSource.[[ByteOffset]]로 설정합니다.
-
length을 jsBufferSource.[[ByteLength]]로 설정합니다.
-
-
그 외의 경우:
-
jsBufferSource는
ArrayBuffer
또는SharedArrayBuffer
객체여야 합니다. -
length을 jsBufferSource.[[ArrayBufferByteLength]]로 설정합니다.
-
-
IsDetachedBuffer(jsArrayBuffer)가 true면 빈 바이트 시퀀스를 반환합니다.
-
i를 범위 offset에서 offset + length − 1까지 반복하며, bytes[i − offset]에 GetValueFromBuffer(jsArrayBuffer, i, Uint8, true, Unordered)의 결과를 넣습니다.
-
bytes를 반환합니다.
-
jsBufferSource를 변환을 통해 bufferSource를 자바스크립트 값으로 변환합니다.
-
jsBufferSource가 [[ViewedArrayBuffer]] 내부 슬롯을 가지면, jsBufferSource.[[ByteLength]]를 반환합니다.
-
jsBufferSource.[[ArrayBufferByteLength]]를 반환합니다.
-
bufferSource가 버퍼 타입 인스턴스라면 bufferSource를 반환합니다.
-
jsBufferView를 IDL에서 자바스크립트 값으로 변환한 bufferSource의 결과로 설정합니다.
-
jsBuffer를 jsBufferView.[[ViewedArrayBuffer]]로 설정합니다.
-
IsSharedArrayBuffer(jsBuffer)가 false라면, 자바스크립트 값을 IDL 값으로 변환하여 jsBuffer를
ArrayBuffer
타입으로 반환합니다. -
자바스크립트 값을 IDL 값으로 변환하여 jsBuffer를
SharedArrayBuffer
타입으로 반환합니다.
-
jsArrayBuffer를 IDL에서 자바스크립트 값으로 변환한 arrayBuffer의 결과로 설정합니다.
-
단언: bytes의 길이(length) ≤ jsArrayBuffer.[[ArrayBufferByteLength]] − startingOffset.
-
범위(the range) startingOffset에서 startingOffset + bytes의 길이 − 1까지 i에 대해 SetValueInBuffer(jsArrayBuffer, i, Uint8, bytes[i - startingOffset], true, Unordered)를 수행합니다.
ArrayBufferView
view에 쓸 때, 옵셔널로
startingOffset (기본값 0)을 받을 수 있습니다:
-
jsView를 IDL에서 자바스크립트 값으로 변환한 view의 결과로 설정합니다.
-
단언: bytes의 길이 ≤ jsView.[[ByteLength]] − startingOffset.
-
단언: view가
DataView
가 아닐 경우, bytes의 길이를 modulo view의 타입의 요소 크기(element size)로 나눈 나머지가 0임을 보장합니다. -
arrayBuffer를 자바스크립트 값을 IDL 값으로 변환하여 jsView.[[ViewedArrayBuffer]]를
ArrayBuffer
타입으로 설정합니다. -
쓰기(write)를 bytes와 arrayBuffer로, startingOffset을 jsView.[[ByteOffset]] + startingOffset으로 하여 수행합니다.
SharedArrayBuffer
객체가 관련된 경우 더욱 그렇습니다.
공유되지 않은 경우, 보다 권장되는 패턴은 transfer(이전)를 먼저 수행하여
ArrayBuffer
인스턴스의 쓰기가 다른 수정과 겹치지 않도록 보장한 뒤, 필요에 따라 새 ArrayBuffer
인스턴스를 작성자 코드에 제공하는 것입니다. 또는 버퍼 소스가 가진 바이트의 복사본을 얻어
해당 바이트를 수정한 뒤, 이를 사용해 새로운 ArrayBuffer나 ArrayBufferView
를 작성자 코드에 제공할 수 있습니다.
ArrayBuffer
arrayBuffer에 대해 다음을 수행합니다:
-
jsArrayBuffer를 IDL에서 자바스크립트 값으로 변환한 arrayBuffer의 결과로 설정합니다.
-
? DetachArrayBuffer(jsArrayBuffer)를 수행합니다.
만약
jsArrayBuffer가 [[ArrayBufferDetachKey]]가 undefined가 아닌 경우,
(예: WebAssembly.Memory
의
buffer
속성값 등) 예외가 발생합니다.
[WASM-JS-API-1]
이미 detached(분리됨)된 버퍼를 detach하는 것은 아무 효과가 없습니다.
-
jsArrayBuffer를 IDL에서 자바스크립트 값으로 변환한 bufferSource의 결과로 설정합니다.
-
jsArrayBuffer가 [[ViewedArrayBuffer]] 내부 슬롯을 가진 경우, jsArrayBuffer를 jsArrayBuffer.[[ViewedArrayBuffer]]로 설정합니다.
-
IsDetachedBuffer(jsArrayBuffer)를 반환합니다.
-
jsArrayBuffer를 IDL에서 자바스크립트 값으로 변환한 bufferSource의 결과로 설정합니다.
-
jsArrayBuffer가 [[ViewedArrayBuffer]] 내부 슬롯을 가진 경우, jsArrayBuffer를 jsArrayBuffer.[[ViewedArrayBuffer]]로 설정합니다.
-
IsSharedArrayBuffer(jsArrayBuffer)가 true이면 false 반환.
-
IsDetachedBuffer(jsArrayBuffer)가 true이면 false 반환.
-
jsArrayBuffer.[[ArrayBufferDetachKey]]가
undefined 가 아니면 false 반환. -
true 반환.
ArrayBuffer
arrayBuffer를, 옵셔널하게
realm targetRealm에 이전할 때:
-
jsArrayBuffer를 IDL에서 자바스크립트 값으로 변환한 arrayBuffer의 결과로 설정합니다.
-
IsDetachedBuffer(jsArrayBuffer)가 false면, TypeError를 throw합니다.
TypeError
. -
arrayBufferData를 jsArrayBuffer.[[ArrayBufferData]]로 설정합니다.
-
arrayBufferByteLength를 jsArrayBuffer.[[ArrayBufferByteLength]]로 설정합니다.
-
? DetachArrayBuffer(jsArrayBuffer)를 수행합니다.
-
targetRealm이 없으면 targetRealm을 현재 realm으로 설정합니다.
-
jsTransferred를 ? AllocateArrayBuffer(targetRealm.[[Intrinsics]].[[
%ArrayBuffer%
]], 0)로 설정합니다. -
jsTransferred.[[ArrayBufferData]]를 arrayBufferData로 설정합니다.
-
jsTransferred.[[ArrayBufferByteLength]]를 arrayBufferByteLength로 설정합니다.
-
자바스크립트 값을 IDL 값으로 변환하여 jsTransferred를
ArrayBuffer
타입으로 반환합니다.
-
arrayBuffer가 detached(분리됨)될 수 없는 경우, 해당 알고리즘 설명 (참고)에 명시된 이유 때문입니다;
-
arrayBuffer가 이미 detached(분리됨)인 경우;
-
realm에 충분한 메모리를 할당할 수 없을 때. 일반적으로 이는 realm이 arrayBuffer가 할당된 에이전트 클러스터(agent cluster)와 다를 때만 발생합니다. 동일한 에이전트 클러스터인 경우에는 구현체가 백킹 포인터만 변경하여 더 나은 성능과 할당 없이 동일한 관찰 가능한 결과를 얻을 수 있습니다.
3.2.27. 불변 배열 — FrozenArray<T>
불변 배열 타입의 값은 불변(frozen) JavaScript Array 객체 참조로 표현됩니다.
JavaScript 값 V를 변환하여 IDL FrozenArray<T> 값으로 만드는 알고리즘:
-
values를 변환하여 V를 IDL 타입 sequence<T>으로 변환한 결과로 설정한다.
-
불변 배열 생성 알고리즘에 values를 넣어 반환한다.
불변 배열 생성 알고리즘: 타입 T의 값 시퀀스에 대해 아래 단계를 실행한다:
-
array를 IDL → JavaScript 값 변환 알고리즘으로 타입 T 값 시퀀스를 변환한 결과로 설정한다.
-
! SetIntegrityLevel(array, "
frozen
")을 수행한다. -
array를 반환한다.
IDL → JavaScript 값 변환 알고리즘 결과로 IDL FrozenArray<T> 값을 JavaScript 값으로 변환하면, 해당 IDL FrozenArray<T>이 참조하는 같은 객체를 참조하는 Object 값이 된다.
3.2.27.1. 이터러블로부터 불변 배열 생성
이터러블 iterable과 이터레이터 getter method가 주어졌을 때, IDL 타입 FrozenArray<T>를 생성하는 알고리즘:
-
values를 이터러블로부터 시퀀스 생성 알고리즘에 iterable과 method를 넣어 타입 sequence<T>로 변환한 결과로 설정한다.
-
불변 배열 생성 알고리즘에 values를 넣어 반환한다.
3.2.28. 관측 배열 — ObservableArray<T>
관측 배열 타입의 값은 observable array exotic object로 표현됩니다.
일반적인 변환 알고리즘 대신, 관측 배열 타입은 attribute getter와 attribute setter 알고리즘의 일부로 특별하게 처리됩니다.
JavaScript 바인딩에서 플랫폼 객체를 나타내는 JavaScript 객체는 backing observable array exotic object를 각 정규 attribute에 대해 관측 배열 타입에 대해 가집니다. 이는 attribute 정의 알고리즘의 일부로 생성 및 관리됩니다.
-
단언: obj는 구현한 interface에 정규 attribute attribute가 있다.
-
oa를 obj의 backing observable array exotic object로 attribute에 대해 설정한다.
-
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
]
사용에 따른
구체적인 요구 사항을 확인할 수 있습니다.
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
]
확장 어트리뷰트는
다음 경우 모두에 명시될 수 없습니다:
-
interface member와 그 interface 또는 partial interface 둘 다에;
-
interface mixin member와 그 interface mixin 또는 partial interface mixin 둘 다에;
-
namespace member와 그 namespace 또는 partial namespace 둘 다에.
참고: 이는 [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를 가질 때 - [
Exposed
] 확장 어트리뷰트가 식별자 리스트 I를 가질 때 - [
Exposed
] 확장 어트리뷰트가 와일드카드를 가질 때 -
자신의 노출 집합은
*
입니다.
[Exposed=*]
는 신중하게 사용해야 합니다.
API가 새로운 기능을 노출하지 않을 때만 적합합니다.
API가 일부 환경에서 제한되거나 비활성화될 수 있다면, 글로벌을 명시적으로 리스트하는 것이 더 바람직합니다.
노출 집합 교집합은 구성 요소 C와 interface-or-null H에 대해 다음과 같이 정의됩니다:
-
단언: C는 interface member, interface mixin member, namespace member, partial interface, partial interface mixin, partial namespace, 또는 interface mixin이다.
-
단언: H는 interface 또는 null이다.
-
H가 null이면, C의 자신의 노출 집합을 반환한다.
-
단언: C는 interface, callback interface, namespace, interface member, interface mixin member, 또는 namespace member이다.
-
H를 C가 interface mixin member일 경우 호스트 인터페이스로, 그렇지 않으면 null로 설정한다.
-
C가 interface member, interface mixin member, 또는 namespace member라면:
-
C를 interface, partial interface, interface mixin, partial interface mixin, namespace, 또는 partial namespace의 C로 설정한다.
-
C가 partial interface, partial interface mixin, 또는 partial namespace일 경우:
-
C가 interface mixin일 경우:
-
단언: C는 interface, callback interface, 또는 namespace이다.
-
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 member와
interface 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의 노출 집합은
해당 구성 요소의 자신의 노출 집합과 호스트 인터페이스의 노출 집합의 교집합이 된다.
그렇지 않으면 호스트 인터페이스의 노출 집합이 된다.
-
construct의 노출 집합이
*
가 아니고, realm.[[GlobalObject]]가 construct의 노출 집합에 포함된 interface를 구현하지 않는다면, false를 반환한다. -
realm의 설정 객체가 보안 컨텍스트가 아니고, construct가 [
SecureContext
]에서 조건부 노출됨 상태라면, false를 반환한다. -
realm의 설정 객체의 cross-origin isolated capability가 false이고, construct가 [
CrossOriginIsolated
]에서 조건부 노출됨 상태라면, false를 반환한다. -
true를 반환한다.
-
단언: construct는 interface, callback interface, namespace, interface member, interface mixin member, 또는 namespace member이다.
-
H를 construct가 interface mixin member일 경우 호스트 인터페이스로, 그렇지 않으면 null로 설정한다.
-
construct가 interface member, interface mixin member, 또는 namespace member라면:
-
exposure condition 확장 어트리뷰트가 construct에 명시되어 있으면, true를 반환한다.
-
그렇지 않으면 construct를 interface, partial interface, interface mixin, partial interface mixin, namespace, 또는 partial namespace의 construct로 설정한다.
-
-
construct가 partial interface, partial interface mixin, 또는 partial namespace일 경우:
-
exposure condition 확장 어트리뷰트가 construct에 명시되어 있으면, true를 반환한다.
-
그렇지 않으면 construct를 원래 interface, interface mixin, 또는 namespace 정의의 construct로 설정한다.
-
-
construct가 interface mixin일 경우:
-
exposure condition 확장 어트리뷰트가 construct에 명시되어 있으면, true를 반환한다.
-
그렇지 않으면 construct를 H로 설정한다.
-
-
단언: construct는 interface, callback interface, 또는 namespace이다.
-
exposure condition 확장 어트리뷰트가 construct에 명시되어 있으면, true를 반환한다.
-
그렇지 않으면 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에 해당하는 프로퍼티가 프로토타입 객체에 어떻게 반영되는지가 다른 인터페이스와 다릅니다. 구체적으로:
-
모든 이름있는 프로퍼티(named properties)는 프로토타입 체인 상의 객체(즉, named properties object)에 노출되며, 객체 자체에는 노출되지 않습니다.
-
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.indexedDB
및 window.requestAnimationFrame
이
[Global
] 확장 어트리뷰트가
interface에 사용된 경우:
-
해당 interface는 named property setter를 정의하면 안 됩니다.
-
해당 interface는 indexed property getter나 setter를 정의하면 안 됩니다.
-
해당 interface는 constructor operation을 정의하면 안 됩니다.
-
해당 interface는 [
LegacyOverrideBuiltIns
] 확장 어트리뷰트와 함께 선언하면 안 됩니다. -
해당 interface는 [
LegacyOverrideBuiltIns
] 확장 어트리뷰트를 명시한 다른 interface를 상속하면 안 됩니다. -
다른 어떤 interface도 해당 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
]
확장 어트리뷰트는 식별자를 가져야 합니다.
다음을 가정합니다:
-
A: [
PutForwards
] 확장 어트리뷰트가 나타난 attribute -
I: A가 선언된 interface
-
J: A의 타입으로 선언된 interface 타입
-
N: 확장 어트리뷰트 인자 식별자
이 경우, J에 attribute 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
]
확장 어트리뷰트는 다음 경우 모두에 명시될 수 없습니다:
-
interface member와 그 interface 또는 partial interface 둘 다에;
-
interface mixin member와 그 interface mixin 또는 partial interface mixin 둘 다에;
-
namespace member와 그 namespace 또는 partial namespace 둘 다에.
참고: [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를 가져야 합니다.
"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를
[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 네임스페이스 객체를 참고하세요.
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
"로 문자열화되지만, 이 확장 어트리뷰트가 있으면 빈 문자열로 변환됩니다.
[LegacyNullToEmptyString
]
확장 어트리뷰트는 DOMString
또는 USVString
이 아닌 타입에 연관될 수 없습니다.
참고: DOMString?
에도 [LegacyNullToEmptyString
]을
사용하면 안 됩니다.
구체적 요구사항은 § 3.2.10 DOMString에서 [LegacyNullToEmptyString
]
사용 규칙을 참고하세요.
[Exposed =Window ]interface Dog {attribute DOMString name ;attribute [LegacyNullToEmptyString ]DOMString owner ;boolean isMemberOfBreed ([LegacyNullToEmptyString ]DOMString breedName ); };
이 Dog
interface를 구현하는 JavaScript에서는,
owner
프로퍼티에 isMemberOfBreed
함수의 인자로 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 접근이 허용되어야 하는지를 결정하는 데 사용됩니다. 보안 검사는 다음 세 입력값을 사용합니다:
-
operation 호출이나 attribute 접근이 수행되는 플랫폼 객체
-
해당 operation 또는 attribute의 식별자
-
함수 객체(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”의 쌍이다. 알고리즘은 다음과 같이 동작한다:
-
maxarg를 S의 엔트리 중 가장 긴 타입 리스트의 길이로 한다.
-
n을 args의 크기로 한다.
-
argcount를 min(maxarg, n)로 초기화한다.
-
S에서 타입 리스트의 길이가 argcount가 아닌 엔트리를 모두 제거한다.
-
d를 −1로 초기화한다.
-
method를
undefined 로 초기화한다. -
S에 엔트리가 둘 이상 있으면, d를 S 엔트리의 구분 인자 인덱스로 설정한다.
-
values를 빈 리스트로 초기화한다. 각 엔트리는 IDL 값 또는 특수값 “missing”이 된다.
-
i를 0으로 초기화한다.
-
i < d 동안:
-
V를 args[i]로 한다.
-
type을 S의 엔트리 중 아무거나의 타입 리스트 i번째로 한다.
참고: 이 시점에서 S의 모든 엔트리는 i번째 타입 및 옵셔널 값이 동일하다.
-
optionality를 S의 엔트리 중 아무거나의 옵션 값 리스트 i번째로 한다.
-
optionality가 “optional”이고 V가
undefined 라면:-
i번째 인자가 기본값을 가진 경우, values에 그 기본값을 추가한다.
-
그렇지 않으면 values에 특수값 “missing”을 추가한다.
-
-
그 외의 경우 values에 V를 IDL 타입 type으로 변환한 결과를 추가한다.
-
i를 i+1로 한다.
-
-
i = d이면:
-
V를 args[i]로 한다.
참고: 이 인자가 어떤 오버로드가 선택되는지 결정하는 인자이다.
-
V가
undefined 이고 S에 옵션 값 리스트 i번째가 “optional”인 엔트리가 있으면, S의 다른 엔트리를 모두 제거한다. -
그 외의 경우 V가
null 또는undefined 이고, S에 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,-
union 타입 또는 어노테이트된 union 타입이며 nullable 타입을 포함하거나 딕셔너리 타입을 flattened members에 포함하는 경우
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 V가 플랫폼 객체이고, S에 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,
-
V가 구현한 interface 타입
-
위 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
-
그 외의 경우 V가 Object이고 [[ArrayBufferData]] internal slot이 있고, S의 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,
-
위 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 V가 Object이고 [[DataView]] internal slot이 있고, S의 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,
-
위 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 V가 Object이고 [[TypedArrayName]] internal slot이 있고, S의 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,
-
TypedArray 타입이며 이름이 V의 [[TypedArrayName]] 값과 같음
-
위 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
-
그 외의 경우 IsCallable(V)가 true이고, S에 타입 리스트 i번째가 다음 중 하나인 엔트리가 있으면,
-
위 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 V가 Object이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,
-
위 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그리고 아래가 모두 true가 아니면,
-
V가 [[StringData]] internal slot을 가짐
-
S가 타입 리스트 i번째에 아래 중 하나의 타입을 가짐
그리고 다음 단계를 수행 후,
-
method를 GetMethod(V,
%Symbol.asyncIterator%
)로 한다. -
method가
undefined 라면, method를 GetMethod(V,%Symbol.iterator%
)로 한다.
method가
undefined 가 아니면 S의 다른 엔트리를 모두 제거한다. -
그 외의 경우 V가 Object이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,
-
위 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그리고 다음 단계를 수행 후,
-
method를 GetMethod(V,
%Symbol.iterator%
)로 한다.
method가
undefined 가 아니면 S의 다른 엔트리를 모두 제거한다. -
그 외의 경우 V가 Object이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,
-
위 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 V가 Boolean이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,
-
boolean의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 V가 Number이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,
-
numeric 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 V가 BigInt이고 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,
-
bigint의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,
-
string 타입의 nullable 버전
-
내부 타입이 string 타입인 어노테이트된 타입
-
flattened member types에 string 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,
-
numeric 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,
-
boolean 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 S에 타입 리스트 i번째가 아래 중 하나인 엔트리가 있으면,
-
bigint 타입의 nullable 버전
-
내부 타입이 위 타입 중 하나인 어노테이트된 타입
-
flattened member types에 위 타입이 있는 union/nullable union/어노테이트된 union 타입
그럼 S의 다른 엔트리를 모두 제거한다.
-
그 외의 경우 S에 타입 리스트 i번째가
any
이면 S의 다른 엔트리를 모두 제거한다.
-
-
i = d이고 method가
undefined 가 아니면,-
V를 args[i]로 한다.
-
T를 S의 남은 엔트리의 타입 리스트 i번째로 한다.
-
단언: T는 sequence 타입이다.
-
values에 V와 method로 시퀀스 생성 결과를 추가한다.
-
i를 i+1로 한다.
-
-
i < argcount 동안:
-
i가 callable이 선언된 인자 수보다 작을 동안:
-
callable의 i번째 인자가 기본값을 가진 경우, values에 그 기본값을 추가한다.
-
그 외, callable의 i번째 인자가 가변 인자가 아니면, values에 특수값 “missing”을 추가한다.
-
i를 i+1로 한다.
-
-
<callable, values> 쌍을 반환한다.
오버로드 해석 알고리즘은 어떤 오버로드된 operation, 생성자 등이 호출되는지 식별하는 것과, JavaScript 인자 값을 해당하는 IDL 값으로 변환하는 두 작업을 수행합니다. 비공식적으로 작동 방식은 다음과 같습니다.
먼저, 유효한 오버로드를 선택하는 과정은 함수에 전달된 JavaScript 인자 개수를 고려하여 진행됩니다:
-
가장 긴 오버로드 인자 리스트보다 더 많은 인자가 전달된 경우, 그 초과 인자들은 무시됩니다.
-
이렇게 뒤쪽 인자들을 무시하고 나면, 정확히 그 개수의 인자를 받을 수 있는 오버로드만 고려합니다. 만약 그런 오버로드가 없다면
TypeError
가 발생합니다.
올바른 인자 개수의 오버로드 집합을 얻은 후에는, JavaScript 값들을 왼쪽부터 오른쪽으로 변환합니다. 오버로드 제약의 성질 덕분에, 이 시점에 오버로드가 여러 개 남아 있다면, 인자 리스트 중 한 위치에서 최종적으로 어떤 오버로드를 선택할지 구분하게 됩니다. 이 위치가 구분 인자 인덱스(distinguishing argument index)입니다.
먼저 구분 인자 왼쪽의 인자들을 변환합니다.(구분 인자 인덱스 왼쪽에 위치한 인자는 모든 오버로드에서 같은 타입이어야 합니다.) 그 다음, 구분 인자 인덱스에 전달된 JavaScript
값의 타입을 검사하여 어떤 IDL 타입에 대응될 수 있는지 결정합니다.
이를 통해 최종적으로 호출할 오버로드를 선택합니다. 만약 전달된 값이 TypeError
가 발생합니다.
일반적으로, 구분 인자 인덱스의 값 검사에는 부작용이 없으며, 오버로드 해석 알고리즘에서 발생하는 유일한 부작용은 JavaScript 값을 IDL 값으로 변환하는 과정에만 있습니다.
(예외적으로, 어떤 오버로드가 구분 인자 인덱스에 async sequence 타입,
sequence 타입,
또는 frozen array 타입을 가지는 경우가 있습니다.
이때는 %Symbol.asyncIterator%
/ %Symbol.iterator%
프로퍼티를 얻어 적합한 오버로드를 결정하며, 구분 인자에 대한 변환은 따로 수행한 뒤 다음 단계를 계속 진행합니다.)
이제 사용할 오버로드가 결정되었습니다. 남은 인자들은 구분 인자부터 오른쪽으로 변환하며, 앞서 초과되어 무시된 인자들은 계속 무시합니다.
optional 인자의 JavaScript 값을 해당 IDL 값으로 변환할 때,
마지막 가변 인자(variadic argument)에 해당하는 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 레거시 팩토리 함수에서 설명합니다.
jsValue를 interface 인터페이스에 대해, name 식별자와 type 타입으로 구현 객체 체크(implementation-check an object)하는 절차:
-
object를 ToObject(jsValue)로 한다.
-
object가 플랫폼 객체(platform object)라면, 보안 검사(perform a security check)를 다음과 같이 수행한다:
-
플랫폼 객체 object
-
식별자 name
-
타입 type
-
-
object가 interface를 구현(implement)하지 않으면 throw
TypeError
를 발생시킨다. -
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)된다:
-
steps를 I의 생성자 재정의 단계로 하거나, 없으면 아래 단계를 따른다:
-
args를 전달된 인자들로 한다.
-
n을 args의 크기로 한다.
-
id를 인터페이스 I의 식별자로 한다.
-
생성자에 대한 효과적 오버로드 집합을 식별자 id, 인터페이스 I, 인자 개수 n으로 계산하여 S로 한다.
-
constructor, values를 S와 args를 오버로드 해석 알고리즘에 전달한 결과로 한다.
-
object를 내부적으로 새로운 객체 생성(I 구현, realm,
NewTarget
사용) 결과로 한다. -
O를 object를 자바스크립트 값으로 변환한 결과로 한다.
-
단언: O는 I를 구현하는 객체임.
-
단언: O.[[Realm]]은 realm임.
-
O를 반환한다.
-
constructorProto를 realm.[[Intrinsics]].[[
%Function.prototype%
]]로 한다. -
I가 다른 인터페이스 P를 상속한다면, constructorProto를 P의 realm에서의 인터페이스 객체로 설정한다.
-
F를 CreateBuiltinFunction(steps, « [[Unforgeables]] », realm, constructorProto)로 한다.
-
unforgeables를 OrdinaryObjectCreate(
null )로 한다. -
정규 unforgeable 연산 정의를 I, unforgeables, realm에 대해 수행한다.
-
정규 unforgeable attribute 정의를 I, unforgeables, realm에 대해 수행한다.
-
F.[[Unforgeables]]에 unforgeables를 설정한다.
참고: 이 객체는 사용자 코드에 노출되지 않으며, 인터페이스의 unforgeable 멤버가 모두 동일한 자바스크립트 함수 객체(attribute getter, setter, operation function)를 사용하도록 보장하기 위해 존재합니다.
-
SetFunctionName(F, id)을 수행한다.
-
length를 0으로 한다.
-
I가 생성자 연산으로 선언되었다면,
-
식별자 id, I, 인자 개수 0으로 생성자에 대한 효과적 오버로드 집합을 계산하여 S로 한다.
-
length를 S 엔트리 중 가장 짧은 인자 리스트의 길이로 한다.
-
-
SetFunctionLength(F, length)을 수행한다.
-
proto를 인터페이스 프로토타입 객체 생성(I, realm) 결과로 한다.
-
DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: proto, [[Writable]]:
false , [[Enumerable]]:false , [[Configurable]]:false })를 수행한다. -
상수 정의를 I, F, realm에 대해 수행한다.
-
static attribute 정의를 I, F, realm에 대해 수행한다.
-
static 연산 정의를 I, F, realm에 대해 수행한다.
-
F를 반환한다.
3.7.2. 레거시 팩토리 함수
하나 이상의 [LegacyFactoryFunction
] 확장 어트리뷰트가 특정 식별자와 함께 존재하는 경우,
레거시 팩토리 함수가 생성됩니다.
이는 내장 함수 객체(built-in
function object)이며,
해당 [LegacyFactoryFunction
] 확장
어트리뷰트가 선언된 인터페이스를 구현하는 객체를 생성할 수 있습니다.
주어진 인터페이스 I와 식별자 id에 대한 레거시 팩토리 함수는 realm에서 다음과 같이 생성합니다:
-
steps를 다음 단계로 한다:
-
args를 전달된 인자로 한다.
-
n을 args의 크기로 한다.
-
레거시 팩토리 함수에 대해 식별자 id, 인터페이스 I, 인자 개수 n로 효과적 오버로드 집합을 계산하여 S로 한다.
-
constructor, values를 S, args를 오버로드 해석 알고리즘에 전달한 결과로 한다.
-
object를 내부적으로 새로운 객체 생성(I 구현, realm,
NewTarget
사용) 결과로 한다. -
O를 object를 자바스크립트 값으로 변환한 결과로 한다.
-
단언: O는 I를 구현하는 객체임.
-
단언: O.[[Realm]]은 realm임.
-
O를 반환한다.
-
F를 CreateBuiltinFunction(steps, « », realm)로 한다.
-
SetFunctionName(F, id)을 수행한다.
-
레거시 팩토리 함수에 대해 식별자 id, 인터페이스 I, 인자 개수 0으로 효과적 오버로드 집합을 계산하여 S로 한다.
-
length를 S 엔트리 중 가장 짧은 인자 리스트의 길이로 한다.
-
SetFunctionLength(F, length)을 수행한다.
-
proto를 인터페이스 프로토타입 객체(I, realm)로 한다.
-
DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: proto, [[Writable]]:
false , [[Enumerable]]:false , [[Configurable]]:false })를 수행한다. -
F를 반환한다.
3.7.3. 인터페이스 프로토타입 객체
모든 인터페이스에 대해 인터페이스 프로토타입 객체가 존재합니다.
해당 인터페이스가 [LegacyNoInterfaceObject
]
확장 어트리뷰트로 선언되었는지 여부와 관계없이 정의됩니다.
주어진 인터페이스 프로토타입 객체는 인터페이스 interface와 realm realm에서 다음과 같이 생성됩니다:
-
proto를 null로 한다.
-
interface가 [
Global
] 확장 어트리뷰트로 선언되고, interface가 이름있는 프로퍼티(named properties)를 지원하면, proto를 이름있는 프로퍼티 객체 생성(interface, realm) 결과로 한다. -
그 외에 interface가 다른 인터페이스를 상속하면, proto를 해당 상속 인터페이스의 realm에서의 인터페이스 프로토타입 객체로 한다.
-
그 외에 interface가
DOMException
인터페이스라면, proto를 realm.[[Intrinsics]].[[%Error.prototype%
]]로 한다. -
그 외에는 proto를 realm.[[Intrinsics]].[[
%Object.prototype%
]]로 한다. -
단언: proto는 Object이다.
-
interfaceProtoObj를 null로 한다.
-
realm의 글로벌 프로토타입 체인이 mutable라면:
-
interfaceProtoObj를 OrdinaryObjectCreate(proto)로 한다.
-
-
그 외에 interface가 [
Global
] 확장 어트리뷰트로 선언되었거나, interface가 [Global
] 확장 어트리뷰트로 선언된 인터페이스의 상속 인터페이스 집합에 포함된다면:-
interfaceProtoObj를 MakeBasicObject(« [[Prototype]], [[Extensible]] »)로 한다.
-
interfaceProtoObj.[[Prototype]]에 proto를 설정한다.
-
interfaceProtoObj의 내부 메서드를 immutable prototype exotic objects에 맞게 ECMA-262 Immutable prototype exotic objects의 정의에 따라 설정한다.
-
-
그 외에는 interfaceProtoObj를 OrdinaryObjectCreate(proto)로 한다.
-
interface에 [
Unscopable
] 확장 어트리뷰트로 선언된 멤버가 있으면:-
unscopableObject를 OrdinaryObjectCreate(null)로 한다.
-
모든 노출된 [
Unscopable
] 확장 어트리뷰트로 선언된 멤버 member에 대해:-
id를 member의 식별자로 한다.
-
CreateDataPropertyOrThrow(unscopableObject, id, true)을 수행한다.
-
-
desc를 PropertyDescriptor{[[Value]]: unscopableObject, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}로 한다.
-
DefinePropertyOrThrow(interfaceProtoObj,
%Symbol.unscopables%
, desc)을 수행한다.
-
-
interface가 [
Global
] 확장 어트리뷰트로 선언되지 않았다면:-
정규 attribute 정의를 interface, interfaceProtoObj, realm에 대해 수행한다.
-
정규 연산 정의를 interface, interfaceProtoObj, realm에 대해 수행한다.
-
이터레이션 메서드 정의를 interface, interfaceProtoObj, realm에 대해 수행한다.
-
비동기 이터레이션 메서드 정의를 interface, interfaceProtoObj, realm에 대해 수행한다.
-
-
상수 정의를 interface, interfaceProtoObj, realm에 대해 수행한다.
-
[
LegacyNoInterfaceObject
] 확장 어트리뷰트가 interface에 선언되지 않았다면:-
constructor를 realm에서의 interface 인터페이스 객체로 한다.
-
desc를 PropertyDescriptor{[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true, [[Value]]: constructor}로 한다.
-
DefinePropertyOrThrow(interfaceProtoObj, "constructor", desc)을 수행한다.
-
-
interfaceProtoObj를 반환한다.
또한 인터페이스 프로토타입 객체는 아래에서 선언적으로 프로퍼티를 추가로 갖습니다:
이러한 프로퍼티는 명령적으로 정의되어야 합니다.
[LegacyNoInterfaceObject
]
확장 어트리뷰트로 정의된 인터페이스의 인터페이스 프로토타입 객체는 접근 가능합니다.
예를 들어, 아래 IDL에서:
[Exposed =Window ,LegacyNoInterfaceObject ]interface Foo { };partial interface Window {attribute Foo foo ; };
인터페이스 객체(window.Foo
)가 존재하지 않으므로 인터페이스 프로토타입 객체를 직접 접근할 수 없지만,
Foo
의 인스턴스에서 [[GetPrototypeOf]] 내부 메서드를 호출하여
인터페이스 프로토타입 객체를 노출할 수 있습니다.
즉, Object.getPrototypeOf(window.foo)
를 통해 접근 가능합니다.
인터페이스 프로토타입 객체의 클래스 문자열(class string)은 인터페이스의 정규화된 이름(qualified name)입니다.
3.7.4. 이름있는 프로퍼티 객체
[Global
] 확장 어트리뷰트로 선언되고
이름있는 프로퍼티(named properties)를 지원하는
모든 인터페이스에 대해,
해당 인터페이스에서 이름있는 프로퍼티가 노출되는 객체가 존재하며,
이를 이름있는 프로퍼티
객체(named properties object)라 한다.
-
proto를 null로 한다.
-
interface가 다른 인터페이스를 상속하면, proto를 해당 realm에서의 인터페이스 프로토타입 객체로 한다.
-
그렇지 않으면 proto를 realm.[[Intrinsics]].[[
%Object.prototype%
]]로 한다. -
obj를 MakeBasicObject(« [[Prototype]], [[Extensible]] »)로 한다.
-
obj.[[GetOwnProperty]]를 § 3.7.4.1 [[GetOwnProperty]]에 명시된 대로 설정한다.
-
obj.[[DefineOwnProperty]]를 § 3.7.4.2 [[DefineOwnProperty]]에 명시된 대로 설정한다.
-
obj.[[Delete]]를 § 3.7.4.3 [[Delete]]에 명시된 대로 설정한다.
-
obj.[[SetPrototypeOf]]를 § 3.7.4.4 [[SetPrototypeOf]]에 명시된 대로 설정한다.
-
obj.[[PreventExtensions]]를 § 3.7.4.5 [[PreventExtensions]]에 명시된 대로 설정한다.
-
obj.[[Prototype]]에 proto를 설정한다.
-
obj를 반환한다.
참고: 이름있는 프로퍼티 객체의 [[OwnPropertyKeys]] 내부 메서드는 OrdinaryOwnPropertyKeys를 계속 사용합니다. 이는 레거시 플랫폼 객체와 다릅니다. 이름있는 프로퍼티는 “실제” own property가 아니므로 이 내부 메서드에서는 반환되지 않습니다.
이름있는 프로퍼티 객체의 클래스 문자열(class string)은
인터페이스의 식별자와 문자열 "Properties
"를 연결한 값입니다.
3.7.4.1. [[GetOwnProperty]]
이름있는 프로퍼티 객체 O의 [[GetOwnProperty]] 내부 메서드가 프로퍼티 키 P로 호출되면, 다음 단계가 수행된다:
-
A를 O의 인터페이스로 한다.
-
object를 O.[[Realm]]의 글로벌 객체로 한다.
-
단언: object는 A를 구현한다.
-
프로퍼티 이름 P와 객체 object로 이름있는 프로퍼티 가시성 알고리즘을 실행한 결과가 true라면:
-
operation을 이름있는 프로퍼티 getter를 선언한 연산으로 한다.
-
value를 초기화되지 않은 변수로 한다.
-
operation이 식별자 없이 정의되었다면, value를 인터페이스 설명에 명시된 단계를 수행하여 이름있는 프로퍼티의 값 결정(P를 이름으로 사용) 결과로 한다.
-
그 외에는 operation이 식별자로 정의되었으므로, value를 operation 설명에 명시된 단계를 수행하여 P를 유일한 인자 값으로 사용한 결과로 한다.
-
desc를 필드가 없는 새 프로퍼티 디스크립터(Property Descriptor)로 한다.
-
desc.[[Value]]를 value를 자바스크립트 값으로 변환한 결과로 설정한다.
-
A가 [
LegacyUnenumerableNamedProperties
] 확장 어트리뷰트가 선언된 인터페이스를 구현하면, desc.[[Enumerable]]를 false로, 그렇지 않으면 true로 한다. -
desc.[[Writable]]를 true, desc.[[Configurable]]를 true로 한다.
-
desc를 반환한다.
-
-
OrdinaryGetOwnProperty(O, P)를 반환한다.
3.7.4.2. [[DefineOwnProperty]]
이름있는 프로퍼티 객체의 [[DefineOwnProperty]] 내부 메서드가 호출될 때, 다음 단계가 수행됩니다:
-
false 를 반환한다.
3.7.4.3. [[Delete]]
이름있는 프로퍼티 객체의 [[Delete]] 내부 메서드가 호출될 때, 다음 단계가 수행됩니다:
-
false 를 반환한다.
3.7.4.4. [[SetPrototypeOf]]
이름있는 프로퍼티 객체 O의 [[SetPrototypeOf]] 내부 메서드가 JavaScript 값 V로 호출될 때, 다음 단계가 수행된다:
-
만약 O의 연관 realm의 글로벌 프로토타입 체인이 mutable라면, OrdinarySetPrototypeOf(O, V)를 반환한다.
-
SetImmutablePrototype(O, V)를 반환한다.
3.7.4.5. [[PreventExtensions]]
이름있는 프로퍼티 객체의 [[PreventExtensions]] 내부 메서드가 호출될 때, 다음 단계가 수행된다:
-
false 를 반환한다.
참고: 이렇게 하면 [[PreventExtensions]]가 실패하면서 이름있는 프로퍼티 객체가 확장 가능(extensible)하게 유지됩니다.
3.7.5. 상수
상수는 인터페이스 객체,
레거시 콜백 인터페이스 객체,
인터페이스 프로토타입 객체 및
인터페이스를 구현하는 단일 객체에 노출됩니다.
인터페이스가 [Global
] 확장
속성으로 선언된 경우에 해당합니다.
-
각각의 상수 const에 대해, 멤버가 definition에 속한 경우:
-
value를 IDL 값을 자바스크립트 값으로 변환한 결과로 설정합니다.
-
desc를 PropertyDescriptor{[[Writable]]:
false , [[Enumerable]]:true , [[Configurable]]:false , [[Value]]: value}로 설정합니다. -
id를 const의 식별자로 설정합니다.
-
! DefinePropertyOrThrow(target, id, desc)를 수행합니다.
3.7.6. 속성
정적
속성
은 인터페이스 객체에
노출됩니다.
일반
속성은 인터페이스 프로토타입 객체에 노출되며,
해당 속성이 위조 불가이거나
인터페이스가 [Global
] 확장
속성으로 선언된 경우,
이 경우 해당 인터페이스를 구현하는 모든 객체에 노출됩니다.
-
-
getter를 속성 getter를 생성해서 attr, definition, realm을 인자로 하여 설정합니다.
-
setter를 속성 setter를 생성해서 attr, definition, realm을 인자로 하여 설정합니다.
-
configurable를 attr가 위조 불가이면
false 로, 그렇지 않으면true 로 설정합니다. -
desc를 PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]:
true , [[Configurable]]: configurable}로 설정합니다. -
id를 attr의 식별자로 설정합니다.
-
! DefinePropertyOrThrow(target, id, desc)를 수행합니다.
-
만약 attr의 타입이 observable array type이고 타입 인자가 T라면, target의 backing observable array exotic object를 observable array exotic object 생성하기의 결과로 설정합니다. 인자는 realm, T, attr의 인덱스 값 설정 알고리즘, 인덱스 값 삭제 알고리즘입니다.
속성 getter는 다음과 같이 생성됩니다. 속성 attribute, 네임스페이스 또는 인터페이스 target, realm realm을 인자로 합니다:
-
steps를 다음 단계 시리즈로 설정합니다:
-
다음 단계를 시도합니다:
-
idlObject를 null로 설정합니다.
-
만약 target이 인터페이스이고, attribute가 일반 속성이라면:
-
jsValue를
this 값으로 설정합니다. 값이null 또는undefined 가 아니면 그대로 사용하고, 그렇지 않으면 realm의 전역 객체를 사용합니다. (전역 객체가 target을 구현하지 않거나 [LegacyLenientThis
] 가 지정되지 않았다면 이후 단계에서TypeError
를 발생시킵니다.) -
만약 jsValue가 플랫폼 객체라면, 보안 검사 수행을 jsValue, attribute의 식별자, "getter"를 인자로 하여 실행합니다.
-
만약 jsValue가 target을 구현하지 않으면:
-
만약 attribute가 [
LegacyLenientThis
] 확장 속성으로 지정되었다면,undefined 를 반환합니다.
-
-
만약 attribute의 타입이 observable array type이라면, jsValue의 backing observable array exotic object를 attribute에 대해 반환합니다.
-
idlObject를 jsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.
-
-
R을 getter 단계를 attribute에 대해 idlObject를 this로 사용하여 실행한 결과로 설정합니다.
-
IDL을 자바스크립트 값으로 변환하여 R을 attribute에 선언된 타입의 자바스크립트 값으로 반환합니다.
-
그리고 예외 E가 발생한 경우:
-
만약 attribute의 타입이 promise type이라면 ! Call(
%Promise.reject%
,%Promise%
, «E»)를 반환합니다. -
그 외의 경우 단계 종료 후 예외를 전파합니다.
-
-
F를 CreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.
-
name을 문자열 "
get
"를 attribute의 식별자 앞에 붙여서 설정합니다. -
SetFunctionName(F, name)를 수행합니다.
-
SetFunctionLength(F, 0)를 수행합니다.
-
F를 반환합니다.
속성 setter 는 다음과 같이 생성됩니다. 속성 attribute, 네임스페이스 또는 인터페이스 target, 그리고 realm realm이 주어졌을 때:
-
만약 target이 네임스페이스라면:
-
단언: attribute는 읽기 전용이다.
-
undefined 를 반환한다.
-
-
만약 attribute가 읽기 전용이고 [
LegacyLenientSetter
], [PutForwards
] 또는 [Replaceable
] 확장 속성이 없으면,undefined 를 반환한다; 속성 setter 함수는 없다. -
단언: attribute의 타입은 프라미스 타입이 아니다.
-
steps를 다음 단계 시리즈로 설정한다:
-
V를
undefined 로 설정한다. -
인자가 전달된 경우, V를 전달된 첫 번째 인자의 값으로 설정한다.
-
id를 attribute의 식별자로 설정한다.
-
idlObject를 null로 설정한다.
-
만약 attribute가 일반 속성이라면:
-
jsValue를
this 값으로 설정하며,null 이나undefined 가 아니면 그대로 사용하고, 그렇지 않으면 realm의 전역 객체를 사용한다. (전역 객체가 target을 구현하지 않거나 [LegacyLenientThis
] 가 지정되지 않았다면 이후 단계에서TypeError
를 발생시킨다.) -
jsValue가 플랫폼 객체라면, 보안 검사 수행을 jsValue, id, "setter"를 인자로 하여 실행한다.
-
validThis를 jsValue가 target을 구현하면 true, 그렇지 않으면 false로 설정한다.
-
만약 validThis가 false이고 attribute가 [
LegacyLenientThis
] 확장 속성으로 지정되지 않았다면, throw를 사용하여TypeError
를 발생시킨다. -
만약 attribute가 [
Replaceable
] 확장 속성으로 선언되었다면:-
? CreateDataPropertyOrThrow(jsValue, id, V)를 수행한다.
-
undefined 를 반환한다.
-
-
만약 validThis가 false이면
undefined 를 반환한다. -
만약 attribute가 [
LegacyLenientSetter
] 확장 속성으로 선언되었다면undefined 를 반환한다. -
만약 attribute가 [
PutForwards
] 확장 속성으로 선언되었다면: -
idlObject를 jsValue를 참조하는 IDL 인터페이스 타입 값으로 설정한다.
-
만약 attribute의 타입이 observable array type이고 타입 인자가 T라면:
-
newValues를 ECMAScript 값을 IDL 값으로 변환하여 V를 sequence<T> 타입의 IDL 값으로 설정한다.
-
oa를 idlObject의 attribute의 backing observable array exotic object로 설정한다.
-
길이 설정을 oa.[[ProxyHandler]]에 대해 0으로 한다.
-
i를 0으로 설정한다.
-
i < newValues의 크기일 동안:
-
oa.[[ProxyHandler]].[[SetAlgorithm]] 알고리즘을 newValues[i]와 i를 인자로 하여 실행한다.
-
추가 newValues[i]를 oa.[[ProxyHandler]].[[BackingList]]에 추가한다.
-
-
undefined 를 반환한다.
-
-
-
idlValue를 다음과 같이 결정한다:
- attribute의 타입이 열거형일 경우
- 그 외의 경우
- idlValue는 ECMAScript 값을 IDL 값으로 변환하여 V를 attribute 타입의 IDL 값으로 설정한다.
-
setter 단계를 attribute에 대해, idlObject를 this로, idlValue를 주어진 값으로 사용하여 수행한다.
-
undefined 를 반환한다.
-
-
F를 CreateBuiltinFunction(steps, « », realm)의 결과로 설정한다.
-
name을 문자열 "
set
"를 id 앞에 붙여서 설정한다. -
SetFunctionName(F, name)를 수행한다.
-
SetFunctionLength(F, 1)를 수행한다.
-
F를 반환한다.
참고: IDL 속성에는 단일 프로퍼티만 있지만, 접근자 프로퍼티 getter와 setter는 해당 IDL 속성에 대응하는 프로퍼티가 접근된 객체의 this 값을 전달받으므로 인스턴스별 데이터를 노출할 수 있습니다.
참고: 읽기 전용 속성
에 대응하는 프로퍼티에 값을 할당하려고 하면, 스크립트가 엄격 모드(strict mode)인지에 따라 동작이 달라집니다.
엄격 모드에서는 해당 할당이 TypeError
를 발생시키고, 엄격 모드가 아니면 할당 시도가 무시됩니다.
3.7.7. 연산(Operations)
각 인터페이스에서 정의된,
노출된 연산의 고유한 식별자마다
해당하는 프로퍼티가 존재합니다.
정적 연산은 인터페이스 객체에
노출됩니다.
일반 연산은 인터페이스 프로토타입 객체에 노출됩니다.
단, 연산이 위조 불가이거나,
인터페이스가 [Global
] 확장 속성으로
선언된 경우에는,
해당 인터페이스를 구현하는 모든 객체에 노출됩니다.
-
-
method를 연산 함수 생성하기의 결과로 op, definition, realm을 인자로 하여 설정합니다.
-
modifiable를 op가 위조 불가이면
false 로, 그렇지 않으면true 로 설정합니다. -
desc를 PropertyDescriptor{[[Value]]: method, [[Writable]]: modifiable, [[Enumerable]]:
true , [[Configurable]]: modifiable}로 설정합니다. -
id를 op의 식별자로 설정합니다.
-
! DefinePropertyOrThrow(target, id, desc)를 수행합니다.
-
id를 op의 식별자로 설정합니다.
-
steps를 다음 단계 시리즈로 설정하며, 함수 인자값 args가 주어집니다:
-
다음 단계를 시도합니다:
-
idlObject를 null로 설정합니다.
-
만약 target이 인터페이스이고, op가 정적 연산이 아니라면:
-
jsValue를
this 값으로 설정하며,null 또는undefined 가 아니면 그대로 사용하고, 그렇지 않으면 realm의 전역 객체를 사용합니다. (전역 객체가 target을 구현하지 않거나 [LegacyLenientThis
] 가 지정되지 않았다면 이후 단계에서TypeError
를 발생시킵니다.) -
만약 jsValue가 플랫폼 객체라면, 보안 검사 수행을 jsValue, id, "method"를 인자로 하여 실행합니다.
-
만약 jsValue가 인터페이스 target을 구현하지 않으면, throw를 사용하여
TypeError
를 발생시킵니다. -
idlObject를 jsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.
-
-
n을 args의 크기로 설정합니다.
-
유효 오버로드 집합 계산하기: op이 일반 연산이면 일반 연산에 대해, 정적 연산이면 정적 연산에 대해 식별자 id와 target, 인자 개수 n를 사용해 계산하여 S로 설정합니다.
-
<operation, values>를 S와 args를 오버로드 해결 알고리즘에 전달하여 얻은 결과로 설정합니다.
-
R을
null 로 설정합니다. -
그렇지 않으면 R을 메서드 단계를 operation에 대해, idlObject를 this로, values를 인자값으로 사용하여 실행한 결과로 설정합니다.
-
R을 자바스크립트 값으로 변환하여 반환합니다.
R은 op이 반환하도록 선언된 타입의 IDL 값이라고 가정합니다. [whatwg/webidl Issue #674]
-
그리고 예외 E가 발생한 경우:
-
-
F를 CreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.
-
SetFunctionName(F, id)를 수행합니다.
-
유효 오버로드 집합 계산하기: op이 일반 연산이면 일반 연산에 대해, 정적 연산이면 정적 연산에 대해 식별자 id와 target, 인자 개수 0을 사용해 계산하여 S로 설정합니다.
-
length를 S의 엔트리 중 가장 짧은 인자 리스트의 길이로 설정합니다.
-
SetFunctionLength(F, length)를 수행합니다.
-
F를 반환합니다.
3.7.7.1. 기본 연산
일반 연산이 기본 메서드 단계를 갖는다 는 그 식별자가 아래 표의 첫 번째 열에 등장하는 경우를 말합니다. 이 경우, 기본 메서드 단계는 표 두 번째 열에서 연결된 알고리즘에 따라 결정되고, 연산은 표 세 번째 열에 명시된 반환 타입을 가져야 합니다.
식별자 | 기본 메서드 단계 | 반환 타입 |
---|---|---|
"toJSON " |
기본 toJSON 단계 | object
|
일반 연산이 기본 메서드 단계를
갖지 않는다면, [Default
] 확장 속성으로
선언하면 안 됩니다.
3.7.7.1.1. 기본 toJSON 연산
기본 toJSON 단계는 인터페이스 I에 대해 다음과 같이 동작합니다:
-
map을 새로운 순서가 있는 맵으로 설정합니다.
-
상속 스택의 속성 값 수집 알고리즘을 this, stack, map과 함께 실행합니다.
-
result를 OrdinaryObjectCreate(
%Object.prototype%
)의 결과로 설정합니다. -
각 key → value에 대해 map에서:
-
k를 key 자바스크립트 값으로 변환한 결과로 설정합니다.
-
v를 value 자바스크립트 값으로 변환한 결과로 설정합니다.
-
! CreateDataPropertyOrThrow(result, k, v)를 실행합니다.
-
-
result를 반환합니다.
상속 스택의 속성 값 수집 알고리즘은, 플랫폼 객체 object, 스택 stack, 순서가 있는 맵 map이 주어졌을 때 다음과 같이 동작합니다:
-
I를 stack에서 pop한 결과로 설정합니다.
-
속성 값 수집 알고리즘을 object, I, map과 함께 실행합니다.
-
만약 stack이 비어있지 않다면, 상속 스택의 속성 값 수집 알고리즘을 object, stack, map과 함께 다시 실행합니다.
상속 스택 생성 알고리즘은 인터페이스 I에 대해 다음과 같이 동작합니다:
-
stack을 새로운 스택으로 설정합니다.
-
stack에 push하여 I를 넣습니다.
-
-
I를 그 인터페이스로 설정합니다.
-
stack에 push하여 I를 넣습니다.
-
-
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)가 있다면, 다음 특성을 가진 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 이름은 "
toString
"입니다. -
문자열화자가 인터페이스에서 위조 불가이거나, 인터페이스가 [
Global
] 확장 속성으로 선언되어 있다면, 해당 인터페이스를 구현하는 모든 객체에 프로퍼티가 존재합니다. 그렇지 않으면, 프로퍼티는 인터페이스 프로토타입 객체에 존재합니다. -
프로퍼티의 속성은 { [[Writable]]: B, [[Enumerable]]:
true , [[Configurable]]: B } 입니다. 여기서 B는 문자열화자가 인터페이스에서 위조 불가이면false , 그렇지 않으면true 입니다. -
함수 객체의
length
프로퍼티 값은 숫자0 입니다. -
함수 객체의
name
프로퍼티 값은 문자열 "toString
"입니다.
3.7.9. 이터러블 선언
-
만약 definition에 인덱스 프로퍼티 getter가 있다면:
-
DefineMethodProperty(target,
%Symbol.iterator%
,%Array.prototype.values%
, false)를 수행합니다. -
만약 definition에 값 이터레이터가 있다면:
-
! CreateDataPropertyOrThrow(target, "
entries
",%Array.prototype.entries%
)를 수행합니다. -
! CreateDataPropertyOrThrow(target, "
keys
",%Array.prototype.keys%
)를 수행합니다. -
! CreateDataPropertyOrThrow(target, "
values
",%Array.prototype.values%
)를 수행합니다. -
! CreateDataPropertyOrThrow(target, "
forEach
",%Array.prototype.forEach%
)를 수행합니다.
-
-
-
그렇지 않고 definition에 쌍 이터레이터가 있다면:
-
%Symbol.iterator%
및entries
메서드를 정의합니다:-
steps를 다음 단계 시리즈로 설정합니다:
-
F를 CreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.
-
SetFunctionName(F, "
entries
")를 수행합니다. -
SetFunctionLength(F, 0)을 수행합니다.
-
DefineMethodProperty(target,
%Symbol.iterator%
, F, false)를 수행합니다. -
! CreateDataPropertyOrThrow(target, "
entries
", F)를 수행합니다.
-
-
keys
메서드를 정의합니다:-
steps를 다음 단계 시리즈로 설정합니다:
-
F를 CreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.
-
SetFunctionName(F, "
keys
")를 수행합니다. -
SetFunctionLength(F, 0)을 수행합니다.
-
! CreateDataPropertyOrThrow(target, "
keys
", F)를 수행합니다.
-
-
values
메서드를 정의합니다:-
steps를 다음 단계 시리즈로 설정합니다:
-
F를 CreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.
-
SetFunctionName(F, "
values
")를 수행합니다. -
SetFunctionLength(F, 0)을 수행합니다.
-
! CreateDataPropertyOrThrow(target, "
values
", F)를 수행합니다.
-
-
forEach
메서드를 정의합니다:-
steps를 다음 단계 시리즈로 설정합니다. 함수 인자값 callback과 thisArg이 주어집니다:
-
jsValue가 플랫폼 객체이면 보안 검사 수행을 jsValue, "
forEach
", "method
"와 함께 실행합니다. -
idlCallback을 callback IDL 값으로 변환하여
Function
타입으로 설정합니다. -
idlObject를 jsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.
-
pairs를 idlObject의 이터레이션 할 값 쌍 목록으로 설정합니다.
-
i를 0으로 설정합니다.
-
i < pairs의 크기일 동안:
-
pair를 pairs[i]로 설정합니다.
-
콜백 함수 호출을 idlCallback에 대해 « pair의 value, pair의 key, idlObject » 와 thisArg를 콜백 this 값으로 사용하여 실행합니다.
-
pairs를 idlObject의 현재 이터레이션 할 값 쌍 목록으로 다시 설정합니다. (변경될 수 있음)
-
i를 i + 1로 설정합니다.
-
-
F를 CreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.
-
SetFunctionName(F, "
forEach
")를 수행합니다. -
SetFunctionLength(F, 1)을 수행합니다.
-
! CreateDataPropertyOrThrow(target, "
forEach
", F)를 수행합니다.
-
-
3.7.9.1. 기본 이터레이터 객체
기본 이터레이터 객체는 지정된 인터페이스, target, 이터레이션 kind에 대해 [[Prototype]] 내부 슬롯이 해당 인터페이스의 이터레이터 프로토타입 객체인 객체입니다.
기본 이터레이터 객체는 세 가지 내부 값을 가집니다:
-
target: 이터레이션할 값을 가진 객체
-
kind: 이터레이션 종류
-
index: 이터레이션할 값의 현재 인덱스
참고: 기본 이터레이터 객체는 쌍 이터레이터에만 사용됩니다. 값 이터레이터는 현재 객체의 지원하는 인덱스 프로퍼티만 이터레이션하도록 제한되어 있으므로, 표준 JavaScript Array 이터레이터 객체를 사용합니다.
참고: 기본 이터레이터 객체는
클래스 문자열을 가지지 않습니다;
Object.prototype.toString()
을 인터페이스의 기본 이터레이터 객체에 호출하면,
해당 인터페이스의 이터레이터 프로토타입 객체의 클래스 문자열이 사용됩니다.
3.7.9.2. 이터레이터 프로토타입 객체
이터레이터 프로토타입 객체는 지정된 인터페이스에 대해 쌍 이터레이터가 있는 모든 인터페이스에 존재합니다. 해당 인터페이스의 기본 이터레이터 객체의 프로토타입 역할을 합니다.
[[Prototype]] 내부 슬롯은
이터레이터 프로토타입 객체에서
%Iterator.prototype%
이어야
합니다.
-
kind 값에 따라 result를 다음과 같이 결정합니다:
- "
key
" -
-
idlKey를 pair의 key로 설정합니다.
-
key를 IDL to JS 값 변환하여 idlKey를 자바스크립트 값으로 변환한 결과로 설정합니다.
-
result는 key입니다.
-
- "
value
" -
-
idlValue를 pair의 value로 설정합니다.
-
value를 IDL to JS 값 변환하여 idlValue를 자바스크립트 값으로 변환한 결과로 설정합니다.
-
result는 value입니다.
-
- "
key+value
" -
-
idlKey를 pair의 key로 설정합니다.
-
idlValue를 pair의 value로 설정합니다.
-
key를 IDL to JS 값 변환하여 idlKey를 자바스크립트 값으로 변환한 결과로 설정합니다.
-
value를 IDL to JS 값 변환하여 idlValue를 자바스크립트 값으로 변환한 결과로 설정합니다.
-
array를 ! ArrayCreate(2)로 설정합니다.
-
! CreateDataPropertyOrThrow(array, "
0
", key)를 수행합니다. -
! CreateDataPropertyOrThrow(array, "
1
", value)를 수행합니다. -
result는 array입니다.
-
- "
-
CreateIteratorResultObject(result,
false )를 반환합니다.
이터레이터 프로토타입 객체는 next
데이터
프로퍼티를 가져야 하며
속성은 { [[Writable]]:
-
interface를 해당 이터레이터 프로토타입 객체가 존재하는 인터페이스로 설정합니다.
-
thisValue를
this 값으로 설정합니다. -
object가 플랫폼 객체이면, 보안 검사 수행을 다음 인자로 하여 실행합니다:
-
플랫폼 객체 object,
-
식별자 "
next
", -
타입 "
method
"
-
-
object가 interface의 기본 이터레이터 객체가 아니면, throw를 사용해
TypeError
를 발생시킵니다. -
index를 object의 index로 설정합니다.
-
kind를 object의 kind로 설정합니다.
-
values를 object의 target의 이터레이션 할 값 쌍 목록으로 설정합니다.
-
len을 values의 길이로 설정합니다.
-
index가 len보다 크거나 같으면, CreateIteratorResultObject(
undefined ,true )를 반환합니다. -
pair를 values의 index번째 엔트리로 설정합니다.
-
object의 index를 index + 1로 설정합니다.
-
이터레이터 결과를 pair, kind에 대해 반환합니다.
이터레이터 프로토타입 객체의 클래스 문자열은
지정된 인터페이스의 식별자와 문자열
" Iterator
"를 연결한 결과입니다.
3.7.10. 비동기 이터러블 선언
-
만약 definition에 비동기 이터러블 선언(두 종류 중 어느 것이든)이 없다면, 반환합니다.
-
단언: definition에는 인덱스 프로퍼티 getter 또는 이터러블 선언이 없습니다.
-
만약 definition에 쌍 비동기 이터러블 선언이 있다면,
%Symbol.asyncIterator%
와entries
메서드를 정의합니다:-
steps를 다음 단계 시리즈로 설정합니다. 함수 인자값 args가 주어집니다:
-
jsValue가 플랫폼 객체라면 보안 검사 수행을 jsValue, "
%Symbol.asyncIterator%
", "method
"와 함께 실행합니다. -
jsValue가 definition을 구현하지 않으면, throw 를 사용해
TypeError
를 발생시킵니다. -
idlObject를 jsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.
-
idlArgs를 비동기 이터레이터 메서드 인자 변환 알고리즘을 args와 함께 실행한 결과로 설정합니다.
-
iterator를 definition에 대해 idlObject를 target으로, "
key+value
"를 kind로, is finished를 false로 한 새 기본 비동기 이터레이터 객체로 설정합니다. -
비동기 이터레이터 초기화 단계가 존재한다면 definition, idlObject, iterator, idlArgs를 인자로 실행합니다.
-
iterator를 반환합니다.
-
F를 CreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.
-
SetFunctionName(F, "
entries
")를 수행합니다. -
SetFunctionLength(F, 0)을 수행합니다.
-
DefineMethodProperty(target,
%Symbol.asyncIterator%
, F, false)를 수행합니다. -
! CreateDataPropertyOrThrow(target, "
entries
", F)를 수행합니다.
-
-
만약 definition에 쌍 비동기 이터러블 선언이 있다면,
keys
메서드를 정의합니다:-
steps를 다음 단계 시리즈로 설정합니다. 함수 인자값 args가 주어집니다:
-
jsValue가 플랫폼 객체라면 보안 검사 수행을 jsValue, "
keys
", "method
"와 함께 실행합니다. -
jsValue가 definition을 구현하지 않으면, throw 를 사용해
TypeError
를 발생시킵니다. -
idlObject를 jsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.
-
idlArgs를 비동기 이터레이터 메서드 인자 변환 알고리즘을 args와 함께 실행한 결과로 설정합니다.
-
iterator를 definition에 대해 idlObject를 target으로, "
key
"를 kind로, is finished를 false로 한 새 기본 비동기 이터레이터 객체로 설정합니다. -
비동기 이터레이터 초기화 단계가 존재한다면 definition, idlObject, iterator, idlArgs를 인자로 실행합니다.
-
iterator를 반환합니다.
-
F를 CreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.
-
SetFunctionName(F, "
keys
")를 수행합니다. -
SetFunctionLength(F, 0)을 수행합니다.
-
! CreateDataPropertyOrThrow(target, "
keys
", F)를 수행합니다.
-
-
values
및 필요시%Symbol.asyncIterator%
메서드를 정의합니다:-
steps를 다음 단계 시리즈로 설정합니다. 함수 인자값 args가 주어집니다:
-
jsValue가 플랫폼 객체라면 보안 검사 수행을 jsValue, "
values
", "method
"와 함께 실행합니다. -
jsValue가 definition을 구현하지 않으면, throw 를 사용해
TypeError
를 발생시킵니다. -
idlObject를 jsValue를 참조하는 IDL 인터페이스 타입 값으로 설정합니다.
-
idlArgs를 비동기 이터레이터 메서드 인자 변환 알고리즘을 args와 함께 실행한 결과로 설정합니다.
-
iterator를 definition에 대해 idlObject를 target으로, "
value
"를 kind로, is finished를 false로 한 새 기본 비동기 이터레이터 객체로 설정합니다. -
비동기 이터레이터 초기화 단계가 존재한다면 definition, idlObject, iterator, idlArgs를 인자로 실행합니다.
-
iterator를 반환합니다.
-
F를 CreateBuiltinFunction(steps, « », realm)의 결과로 설정합니다.
-
SetFunctionName(F, "
values
")를 수행합니다. -
SetFunctionLength(F, 0)을 수행합니다.
-
! CreateDataPropertyOrThrow(target, "
values
", F)를 수행합니다. -
만약 definition에 값 비동기 이터러블 선언이 있다면, ! DefineMethodProperty(target,
%Symbol.asyncIterator%
, F, false)를 수행합니다.
-
-
idlArgs를 빈 리스트로 설정합니다.
-
argCount를 definition의 비동기 이터러블 선언의 인자 개수로 설정하거나, 인자 리스트가 없으면 0으로 설정합니다.
-
i를 0으로 설정합니다.
-
i < argCount일 동안:
-
만약 i ≥ args의 크기이거나, args[i]가
undefined 이면, 다음을 수행합니다:-
만약 i번째 비동기 이터러블 선언의 인자가 기본값으로 선언되어 있다면, 그 기본값을 idlArgs에 추가합니다.
-
그렇지 않으면, idlArgs에 "missing" 특수 값을 추가합니다.
-
-
그 외의 경우, idlArgs에 추가합니다. ECMAScript 값을 해당 타입의 IDL 값으로 변환하여 args[i]를 비동기 이터러블 선언의 인자 리스트 i번째 타입으로 변환한 결과를 추가합니다.
-
i를 i + 1로 설정합니다.
-
-
idlArgs를 반환합니다.
이 알고리즘은 오버로드 해결 알고리즘을 오버로드가 허용되지 않고 모든 인자가 옵션인 경우로 특화한 것입니다.
3.7.10.1. 기본 비동기 이터레이터 객체
기본 비동기 이터레이터 객체는 지정된 인터페이스, target, 이터레이션 kind에 대해 [[Prototype]] 내부 슬롯이 해당 인터페이스의 비동기 이터레이터 프로토타입 객체인 객체입니다.
기본 비동기 이터레이터 객체는 내부 값을 가집니다:
-
target: 이터레이션할 값을 가진 객체
-
kind: 이터레이션 종류
-
ongoing promise:
Promise
또는 null -
is finished: 불리언 값
참고: 기본 비동기 이터레이터 객체는
클래스 문자열을 가지지 않습니다.
Object.prototype.toString()
을
기본 비동기 이터레이터 객체에 호출하면,
해당 인터페이스의 비동기 이터레이터 프로토타입 객체의 클래스 문자열이 사용됩니다.
3.7.10.2. 비동기 이터레이터 프로토타입 객체
비동기 이터레이터 프로토타입 객체 는 지정된 인터페이스에 대해, 비동기 이터러블 선언을 가진 모든 인터페이스에 존재하는 객체입니다. 해당 인터페이스의 기본 비동기 이터레이터 객체의 프로토타입 역할을 합니다.
비동기 이터레이터 프로토타입 객체의 [[Prototype]] 내부 슬롯은
%AsyncIteratorPrototype%
이어야
합니다.
비동기 이터레이터 프로토타입 객체는
next
데이터 프로퍼티를 가져야 하며,
속성은 { [[Writable]]:
-
interface를 해당 비동기 이터레이터 프로토타입 객체가 존재하는 인터페이스로 설정합니다.
-
thisValidationPromiseCapability를 ! NewPromiseCapability(
%Promise%
)로 설정합니다. -
thisValue를
this 값으로 설정합니다. -
object를 Completion(ToObject(thisValue))로 설정합니다.
-
IfAbruptRejectPromise(object, thisValidationPromiseCapability)를 실행합니다.
-
object가 플랫폼 객체이면 보안 검사 수행을 다음 인자로 하여 실행합니다:
-
플랫폼 객체 object,
-
식별자 "
next
", -
타입 "
method
"
여기서 예외 e가 발생했다면:
-
-
object가 interface의 기본 비동기 이터레이터 객체가 아니면:
-
nextSteps를 다음 단계로 설정합니다:
-
nextPromiseCapability를 ! NewPromiseCapability(
%Promise%
)로 설정합니다. -
object의 is finished가 true라면:
-
result를 CreateIteratorResultObject(
undefined ,true )로 설정합니다. -
! Call(nextPromiseCapability.[[Resolve]],
undefined , « result »)를 실행합니다. -
nextPromiseCapability.[[Promise]]를 반환합니다.
-
-
kind를 object의 kind로 설정합니다.
-
nextPromise를 다음 이터레이션 결과 가져오기 알고리즘을 object의 target과 object에 대해 실행한 결과로 설정합니다.
-
fulfillSteps를 다음 단계로 설정합니다. next가 주어졌을 때:
-
object의 ongoing promise 를 null로 설정합니다.
-
next가 이터레이션 종료라면:
-
object의 is finished를 true로 설정합니다.
-
CreateIteratorResultObject(
undefined ,true )를 반환합니다.
-
-
그 외의 경우, interface에 쌍 비동기 이터러블 선언이 있다면:
-
그 외의 경우:
-
단언: interface에 값 비동기 이터러블 선언이 있다.
-
단언: next는 선언에 나오는 타입의 값이다.
-
value를 next 자바스크립트 값으로 변환한 결과로 설정합니다.
-
CreateIteratorResultObject(value,
false )를 반환합니다.
-
-
-
onFulfilled를 CreateBuiltinFunction(fulfillSteps, « »)로 설정합니다.
-
rejectSteps를 다음 단계로 설정합니다. reason이 주어진 경우:
-
object의 ongoing promise 를 null로 설정합니다.
-
object의 is finished를 true로 설정합니다.
-
Throw reason을 실행합니다.
-
-
onRejected를 CreateBuiltinFunction(rejectSteps, « »)로 설정합니다.
-
PerformPromiseThen(nextPromise, onFulfilled, onRejected, nextPromiseCapability)를 실행합니다.
-
nextPromiseCapability.[[Promise]]를 반환합니다.
-
-
ongoingPromise를 object의 ongoing promise로 설정합니다.
-
ongoingPromise가 null이 아니면:
-
afterOngoingPromiseCapability를 ! NewPromiseCapability(
%Promise%
)로 설정합니다. -
onSettled를 CreateBuiltinFunction(nextSteps, « »)로 설정합니다.
-
PerformPromiseThen(ongoingPromise, onSettled, onSettled, afterOngoingPromiseCapability)를 실행합니다.
-
object의 ongoing promise를 afterOngoingPromiseCapability.[[Promise]]로 설정합니다.
-
-
그 외의 경우:
-
object의 ongoing promise를 nextSteps 실행 결과로 설정합니다.
-
-
object의 ongoing promise를 반환합니다.
만약 비동기 이터레이터 리턴 알고리즘이 해당 인터페이스에 대해 정의되어 있다면,
비동기 이터레이터 프로토타입 객체는
return
데이터 프로퍼티를 가져야 하며,
속성은 { [[Writable]]:
-
interface를 해당 비동기 이터레이터 프로토타입 객체가 존재하는 인터페이스로 설정합니다.
-
returnPromiseCapability를 ! NewPromiseCapability(
%Promise%
)로 설정합니다. -
thisValue를
this 값으로 설정합니다. -
object를 Completion(ToObject(thisValue))로 설정합니다.
-
IfAbruptRejectPromise(object, returnPromiseCapability)를 실행합니다.
-
object가 플랫폼 객체이면 보안 검사 수행을 다음 인자로 하여 실행합니다:
-
플랫폼 객체 object,
-
식별자 "
return
", -
타입 "
method
"
여기서 예외 e가 발생했다면:
-
-
object가 interface의 기본 비동기 이터레이터 객체가 아니면:
-
returnSteps를 다음 단계로 설정합니다:
-
returnPromiseCapability를 ! NewPromiseCapability(
%Promise%
)로 다시 설정합니다. -
object의 is finished가 true라면:
-
result를 CreateIteratorResultObject(value,
true )로 설정합니다. -
! Call(returnPromiseCapability.[[Resolve]],
undefined , « result »)를 실행합니다. -
returnPromiseCapability.[[Promise]]를 반환합니다.
-
-
object의 is finished를 true로 설정합니다.
-
비동기 이터레이터 리턴 알고리즘을 interface, object의 target, object, value로 실행한 결과를 반환합니다.
-
-
ongoingPromise를 object의 ongoing promise로 설정합니다.
-
ongoingPromise가 null이 아니면:
-
afterOngoingPromiseCapability를 ! NewPromiseCapability(
%Promise%
)로 설정합니다. -
onSettled를 CreateBuiltinFunction(returnSteps, « »)로 설정합니다.
-
PerformPromiseThen(ongoingPromise, onSettled, onSettled, afterOngoingPromiseCapability)를 실행합니다.
-
object의 ongoing promise를 afterOngoingPromiseCapability.[[Promise]]로 설정합니다.
-
-
그 외의 경우:
-
object의 ongoing promise를 returnSteps 실행 결과로 설정합니다.
-
-
fulfillSteps를 다음 단계로 설정합니다:
-
CreateIteratorResultObject(value,
true )를 반환합니다.
-
-
onFulfilled를 CreateBuiltinFunction(fulfillSteps, « »)로 설정합니다.
-
PerformPromiseThen(object의 ongoing promise, onFulfilled,
undefined , returnPromiseCapability)를 실행합니다. -
returnPromiseCapability.[[Promise]]를 반환합니다.
비동기 이터레이터 프로토타입 객체의 클래스 문자열은
지정된 인터페이스의 식별자와 문자열
" AsyncIterator
"를 연결한 결과입니다.
3.7.11. 맵라이크(maplike) 선언
만약 인터페이스 A가 맵라이크 선언으로 선언되었다면, A의 인터페이스 프로토타입 객체에 추가 프로퍼티가 존재합니다. 이 추가 프로퍼티들은 아래 하위 섹션에서 설명합니다.
3.7.11.1. size
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 size
프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Get]]: G, [[Enumerable]]:
true , [[Configurable]]:true }이며, 여기서 G는 아래에 정의된 인터페이스의 맵 사이즈 getter입니다. -
맵 사이즈 getter는 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "size
"와 타입 "getter
"로 구현 체크를 수행합니다. -
map을 O를 참조하는 IDL 값의 맵 엔트리로 설정합니다.
-
map의 크기를 자바스크립트 값으로 변환하여 반환합니다.
함수 객체의
length
프로퍼티 값은 숫자0 입니다.함수 객체의
name
프로퍼티 값은 문자열 "get size
"입니다. -
3.7.11.2. %Symbol.iterator%
A의 인터페이스 프로토타입 객체에는
%Symbol.iterator%
심볼 이름을 가진 데이터 프로퍼티가 반드시 존재해야 하며,
속성은 { [[Writable]]: entries
프로퍼티의 함수 객체 값입니다.
key+value
", "key
", "value
")가 주어졌을 때:
-
closure를 추상 클로저(Abstract Closure)로 생성합니다. 파라미터 없이 map과 kind를 캡처하며, 호출 시 다음 단계를 수행합니다:
-
각 key → value에 대해 map에서:
-
key와 value를 각각 자바스크립트 값으로 변환합니다.
-
kind가 "
key
"이면 result를 key로 설정합니다. -
그 외 kind가 "
value
"이면 result를 value로 설정합니다. -
그 외의 경우 result를 CreateArrayFromList(« key, value »)로 설정합니다.
-
? GeneratorYield(CreateIteratorResultObject(result,
false ))를 실행합니다.
참고: map의 크기와 엔트리 순서는 Yield로 인해 이 추상 연산이 일시 중지되는 동안 변경될 수 있습니다.
-
-
undefined 를 반환합니다.
-
-
CreateIteratorFromClosure(closure, "
%MapIteratorPrototype%
",%MapIteratorPrototype%
)를 반환합니다.
3.7.11.3. entries
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 entries
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "entries
"와 타입 "method
"로 구현 체크를 수행합니다. -
map을 O를 참조하는 IDL 값의 맵 엔트리로 설정합니다.
-
map에서 kind "
key+value
"로 맵 이터레이터 생성하기의 결과를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"entries
"입니다.
3.7.11.4. keys
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 keys
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "keys
"와 타입 "method
"로 구현 체크를 수행합니다. -
map을 O를 참조하는 IDL 값의 맵 엔트리로 설정합니다.
-
map에서 kind "
key
"로 맵 이터레이터 생성하기의 결과를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"keys
"입니다.
3.7.11.5. values
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 values
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "values
"와 타입 "method
"로 구현 체크를 수행합니다. -
map을 O를 참조하는 IDL 값의 맵 엔트리로 설정합니다.
-
map에서 kind "
value
"로 맵 이터레이터 생성하기의 결과를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"values
"입니다.
3.7.11.6. forEach
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 forEach
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "forEach
"와 타입 "method
"로 구현 체크를 수행합니다. -
map을 O를 참조하는 IDL 값의 맵 엔트리로 설정합니다.
-
callbackFn을 함수에 전달된 첫 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
만약 IsCallable(callbackFn)이
false 이면, throw를 사용해TypeError
를 발생시킵니다. -
thisArg를 함수에 전달된 두 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
각 key → value에 대해 map에서:
-
jsKey와 jsValue를 각각 key와 value 자바스크립트 값으로 변환합니다.
-
-
undefined 를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"forEach
"입니다.
3.7.11.7. get
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 get
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "get
"와 타입 "method
"로 구현 체크를 수행합니다. -
map을 O를 참조하는 IDL 값의 맵 엔트리로 설정합니다.
-
keyType을 맵라이크 선언에 지정된 키 타입으로 설정합니다.
-
keyArg를 함수에 전달된 첫 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
key를 keyArg IDL 값으로 변환하여 keyType 타입의 값으로 설정합니다.
-
key가 -0이면 key를 +0으로 설정합니다.
-
만약 map[key]가 존재한다면, map[key]를 자바스크립트 값으로 변환하여 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"get
"입니다.
3.7.11.8. has
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 has
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "has
"와 타입 "method
"로 구현 체크를 수행합니다. -
map을 O를 참조하는 IDL 값의 맵 엔트리로 설정합니다.
-
keyType을 맵라이크 선언에 지정된 키 타입으로 설정합니다.
-
keyArg를 함수에 전달된 첫 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
key를 keyArg IDL 값으로 변환하여 keyType 타입의 값으로 설정합니다.
-
key가 -0이면 key를 +0으로 설정합니다.
-
만약 map[key]가 존재한다면
true 를 반환하고, 그렇지 않으면false 를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"has
"입니다.
3.7.11.9. set
만약 A가 식별자 "set
"을 가진 멤버를 선언하지 않았고,
A가 읽기-쓰기 맵라이크 선언으로 선언되었다면,
A의 인터페이스 프로토타입 객체에는 다음 특성을 가지는 set
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "set
"와 타입 "method
"로 구현 체크를 수행합니다. -
map을 O를 참조하는 IDL 값의 맵 엔트리로 설정합니다.
-
keyType을 맵라이크 선언에 지정된 키 타입으로, valueType을 값 타입으로 설정합니다.
-
keyArg를 함수에 전달된 첫 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
key를 keyArg IDL 값으로 변환하여 keyType 타입의 값으로 설정합니다.
-
key가 -0이면 key를 +0으로 설정합니다.
-
valueArg를 함수에 전달된 두 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
value를 valueArg IDL 값으로 변환하여 valueType 타입의 값으로 설정합니다.
-
Set map[key]을 value로 설정한다.
-
O를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"set
"입니다.
만약 인터페이스가 set
메서드를 선언한다면,
-0 키를 +0으로 변환해야 하며,
반드시 this를 반환해야 합니다.
3.7.11.10. delete
만약 A가 식별자 "delete
"를 가진 멤버를 선언하지 않았고,
A가 읽기-쓰기 맵라이크 선언으로 선언되었다면,
A의 인터페이스 프로토타입 객체에는 다음 특성을 가지는 delete
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "delete
"와 타입 "method
"로 구현 체크를 수행합니다. -
map을 O를 참조하는 IDL 값의 맵 엔트리로 설정합니다.
-
keyType을 맵라이크 선언에 지정된 키 타입으로 설정합니다.
-
keyArg를 함수에 전달된 첫 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
key를 keyArg IDL 값으로 변환하여 keyType 타입의 값으로 설정합니다.
-
key가 -0이면 key를 +0으로 설정합니다.
-
retVal를 map[key]가 존재하면
true 로, 그렇지 않으면false 로 설정합니다. -
제거한다 map[key].
-
retVal를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"delete
"입니다.
만약 인터페이스가 delete
메서드를 선언한다면,
-0 키를 +0으로 변환해야 하며,
키가 존재했는지를 나타내는 boolean
을
반환해야 합니다.
3.7.11.11. clear
만약 A가 식별자 "clear
"를 가진 멤버를 선언하지 않았고,
A가 읽기-쓰기 맵라이크 선언으로 선언되었다면,
A의 인터페이스 프로토타입 객체에는 다음 특성을 가지는 clear
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"clear
"입니다.
만약 인터페이스가 clear
메서드를 선언한다면,
map 엔트리 객체를 새로 만들지 않고 반드시
보존해야 하며,
undefined
를
반환해야 합니다.
3.7.12. 셋라이크(setlike) 선언
만약 인터페이스 A가 셋라이크 선언으로 선언되었다면, A의 인터페이스 프로토타입 객체에 추가 프로퍼티가 존재합니다. 이 추가 프로퍼티들은 아래 하위 섹션에서 설명합니다.
3.7.12.1. size
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 size
프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Get]]: G, [[Enumerable]]:
true , [[Configurable]]:true }이며, 여기서 G는 아래에 정의된 인터페이스의 셋 사이즈 getter입니다. -
셋 사이즈 getter는 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "size
"와 타입 "getter
"로 구현 체크를 수행합니다. -
set을 O를 참조하는 IDL 값의 셋 엔트리로 설정합니다.
-
set의 크기를 자바스크립트 값으로 변환하여 반환합니다.
함수 객체의
length
프로퍼티 값은 숫자0 입니다.함수 객체의
name
프로퍼티 값은 문자열 "get size
"입니다. -
3.7.12.2. %Symbol.iterator%
A의 인터페이스 프로토타입 객체에는
%Symbol.iterator%
심볼 이름을 가진 데이터 프로퍼티가 반드시 존재해야 하며,
속성은 { [[Writable]]: values
프로퍼티의 함수 객체 값입니다.
key+value
" 또는 "value
")가 주어졌을 때:
-
closure를 추상 클로저(Abstract Closure)로 생성합니다. 파라미터 없이 set과 kind를 캡처하며, 호출 시 다음 단계를 수행합니다:
-
각 entry에 대해 set에서:
-
entry를 자바스크립트 값으로 변환합니다.
-
kind가 "
value
"이면 result를 entry로 설정합니다. -
그 외의 경우 result를 CreateArrayFromList(« entry, entry »)로 설정합니다.
-
? GeneratorYield(CreateIteratorResultObject(result,
false ))를 실행합니다.
참고: set의 크기와 엔트리 순서는 Yield로 인해 이 추상 연산이 일시 중지된 동안 변경될 수 있습니다.
-
-
undefined 를 반환합니다.
-
-
CreateIteratorFromClosure(closure, "
%SetIteratorPrototype%
",%SetIteratorPrototype%
)를 반환합니다.
3.7.12.3. entries
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 entries
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "entries
"와 타입 "method
"로 구현 체크를 수행합니다. -
set을 O를 참조하는 IDL 값의 셋 엔트리로 설정합니다.
-
set에서 kind "
key+value
"로 셋 이터레이터 생성하기의 결과를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"entries
"입니다.
3.7.12.4. keys
A의 인터페이스 프로토타입 객체에는
keys
데이터 프로퍼티가 반드시 존재해야 하며,
속성은 { [[Writable]]: values
프로퍼티의 함수 객체 값입니다.
3.7.12.5. values
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 values
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "values
"와 타입 "method
"로 구현 체크를 수행합니다. -
set을 O를 참조하는 IDL 값의 셋 엔트리로 설정합니다.
-
set에서 kind "
value
"로 셋 이터레이터 생성하기의 결과를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"values
"입니다.
3.7.12.6. forEach
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 forEach
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "forEach
"와 타입 "method
"로 구현 체크를 수행합니다. -
set을 O를 참조하는 IDL 값의 셋 엔트리로 설정합니다.
-
callbackFn을 함수에 전달된 첫 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
만약 IsCallable(callbackFn)이
false 이면, throw를 사용해TypeError
를 발생시킵니다. -
thisArg를 함수에 전달된 두 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
각 value에 대해 set에서:
-
jsValue를 value 자바스크립트 값으로 변환한 값으로 설정합니다.
-
-
undefined 를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"forEach
"입니다.
3.7.12.7. has
A의 인터페이스 프로토타입 객체에는
다음 특성을 가지는 has
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "has
"와 타입 "method
"로 구현 체크를 수행합니다. -
set을 O를 참조하는 IDL 값의 셋 엔트리로 설정합니다.
-
valueType을 셋라이크 선언에 지정된 값 타입으로 설정합니다.
-
valueArg를 함수에 전달된 첫 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
value를 valueArg IDL 값으로 변환하여 valueType 타입의 값으로 설정합니다.
-
value가 -0이면 value를 +0으로 설정합니다.
-
만약 set이 value를 포함하면
true 를, 그렇지 않으면false 를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"has
"입니다.
3.7.12.8. add
만약 A가 식별자 "add
"를 가진 멤버를 선언하지 않았고,
A가 읽기-쓰기 셋라이크 선언으로 선언되었다면,
A의 인터페이스 프로토타입 객체에는 다음 특성을 가지는 add
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "add
"와 타입 "method
"로 구현 체크를 수행합니다. -
set을 O를 참조하는 IDL 값의 셋 엔트리로 설정합니다.
-
valueType을 셋라이크 선언에 지정된 값 타입으로 설정합니다.
-
valueArg를 함수에 전달된 첫 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
value를 valueArg IDL 값으로 변환하여 valueType 타입의 값으로 설정합니다.
-
value가 -0이면 value를 +0으로 설정합니다.
-
set에 value를 추가합니다.
-
O를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"add
"입니다.
만약 인터페이스가 add
메서드를 선언한다면,
-0 값을 +0으로 변환해야 하며,
반드시 설정된 값을 반환해야 합니다.
3.7.12.9. delete
만약 A가 식별자 "delete
"를 가진 멤버를 선언하지 않았고,
A가 읽기-쓰기 셋라이크 선언으로 선언되었다면,
A의 인터페이스 프로토타입 객체에는 다음 특성을 가지는 delete
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
-
O를
this 값으로 설정하고, A에 대해 식별자 "delete
"와 타입 "method
"로 구현 체크를 수행합니다. -
set을 O의 셋 엔트리로 설정합니다.
-
valueType을 셋라이크 선언에 지정된 값 타입으로 설정합니다.
-
valueArg를 함수에 전달된 첫 번째 인자로 설정하거나, 전달되지 않았다면
undefined 로 설정합니다. -
value를 valueArg IDL 값으로 변환하여 valueType 타입의 값으로 설정합니다.
-
value가 -0이면 value를 +0으로 설정합니다.
-
retVal를 set이 value를 포함하면
true 로, 그렇지 않으면false 로 설정합니다. -
set에서 value를 제거합니다.
-
retVal를 반환합니다.
-
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"delete
"입니다.
만약 인터페이스가 delete
메서드를 선언한다면,
-0 값을 +0으로 변환해야 하며,
값이 존재했는지를 나타내는 boolean
을
반환해야 합니다.
3.7.12.10. clear
만약 A가 식별자 "clear
"를 가진 멤버를 선언하지 않았고,
A가 읽기-쓰기 셋라이크 선언으로 선언되었다면,
A의 인터페이스 프로토타입 객체에는 다음 특성을 가지는 clear
데이터 프로퍼티가 반드시 존재해야 합니다:
-
프로퍼티의 속성은 { [[Writable]]:
true , [[Enumerable]]:true , [[Configurable]]:true }입니다. -
프로퍼티의 값은 내장 함수 객체이며, 호출 시 동작은 다음과 같습니다:
함수 객체의 length
프로퍼티 값은 숫자
함수 객체의 name
프로퍼티 값은 문자열
"clear
"입니다.
만약 인터페이스가 clear
메서드를 선언한다면,
set 엔트리 객체를 새로 만들지 않고 반드시
보존해야 하며,
undefined
를
반환해야 합니다.
3.8. 인터페이스를 구현하는 플랫폼 객체
명세서는 "object가 interface 객체이다" 등 다양한 방식으로 "object가 interface를 구현한다"는 개념을 참조할 수 있습니다.
모든 플랫폼 객체는 realm과 연관되어 있습니다. 초기 객체들도 마찬가지입니다. 이 realm은 플랫폼 객체의 [[Realm]] 슬롯에 저장됩니다. Web IDL을 사용하는 명세서는 각 플랫폼 객체가 어떤 realm(혹은 그에 대응하는 글로벌 객체)에 속하는지 명시해야 합니다. 특히, 아래 알고리즘은 새 플랫폼 객체를 전달받은 realm에 연관시킵니다.
-
인터페이스를 내부적으로 구현하는 새 객체 생성 알고리즘을 interface, realm,
undefined 로 실행한 결과를 반환합니다.
-
단언: interface는 realm에 노출되어 있다.
-
newTarget이
undefined 이면:-
prototype을 realm의 interface에 대한 인터페이스 프로토타입 객체로 설정합니다.
-
-
그 외의 경우:
-
단언: IsCallable(newTarget)가 true이다.
-
prototype이 객체가 아니면:
-
targetRealm을 ? GetFunctionRealm(newTarget)의 결과로 설정합니다.
-
prototype을 targetRealm의 interface에 대한 인터페이스 프로토타입 객체로 설정합니다.
-
-
-
slots를 « [[Prototype]], [[Extensible]], [[Realm]], [[PrimaryInterface]] »로 설정합니다.
-
interface가
DOMException
이면, [[ErrorData]]를 slots에 추가합니다. -
instance를 MakeBasicObject(slots)로 생성합니다.
-
instance.[[Realm]]에 realm을 할당합니다.
-
instance.[[PrimaryInterface]]에 interface를 할당합니다.
-
instance.[[Prototype]]에 prototype을 할당합니다.
-
interfaces를 interface의 포함된 상속 인터페이스 목록으로 설정합니다.
-
interface가 [
Global
] 확장 속성으로 선언되었다면:-
정규 연산 정의하기 알고리즘을 interface, instance, realm에 대해 실행합니다.
-
정규 속성 정의하기 알고리즘을 interface, instance, realm에 대해 실행합니다.
-
이터레이션 메서드 정의하기 알고리즘을 interface, instance, realm에 대해 실행합니다.
-
비동기 이터레이션 메서드 정의하기 알고리즘을 interface, instance, realm에 대해 실행합니다.
-
글로벌 프로퍼티 참조 정의하기 알고리즘을 instance, realm에 대해 실행합니다.
-
instance.[[SetPrototypeOf]]를 § 3.8.1 [[SetPrototypeOf]]에서 정의된 대로 설정합니다.
-
-
그 외의 경우, interfaces에 인터페이스가 있고, 인덱스 프로퍼티 지원 또는 이름 프로퍼티 지원 인터페이스가 포함되어 있다면:
-
instance.[[GetOwnProperty]]를 § 3.9.1 [[GetOwnProperty]]에서 정의된 대로 설정합니다.
-
instance.[[Set]]을 § 3.9.2 [[Set]]에서 정의된 대로 설정합니다.
-
instance.[[DefineOwnProperty]]를 § 3.9.3 [[DefineOwnProperty]]에서 정의된 대로 설정합니다.
-
instance.[[Delete]]를 § 3.9.4 [[Delete]]에서 정의된 대로 설정합니다.
-
instance.[[PreventExtensions]]를 § 3.9.5 [[PreventExtensions]]에서 정의된 대로 설정합니다.
-
instance.[[OwnPropertyKeys]]를 § 3.9.6 [[OwnPropertyKeys]]에서 정의된 대로 설정합니다.
-
-
instance를 반환합니다.
-
interfaces를 목록으로 하여, realm에 노출된 모든 인터페이스를 포함시킵니다.
-
interfaces를 정렬합니다. 만약 interfaces의 항목 A와 B에 대해, A가 상속받았다면, A의 인덱스가 B보다 높게 정렬합니다.
-
각 interface에 대해 interfaces에서:
-
interface가 [
LegacyNoInterfaceObject
] 또는 [LegacyNamespace
] 확장 속성으로 선언되지 않았다면:-
id를 interface의 식별자로 설정합니다.
-
interfaceObject를 인터페이스 객체 생성 알고리즘을 interface, id, realm에 대해 실행한 결과로 설정합니다.
-
DefineMethodProperty(target, id, interfaceObject, false)를 실행합니다.
-
interface가 [
LegacyWindowAlias
] 확장 속성으로 선언되어 있고, target이Window
인터페이스를 구현하고 있다면:-
각 [
LegacyWindowAlias
]의 식별자 id에 대해:-
DefineMethodProperty(target, id, interfaceObject, false)를 실행합니다.
-
-
-
-
interface가 [
LegacyFactoryFunction
] 확장 속성으로 선언되었다면:-
각 [
LegacyFactoryFunction
]의 식별자 id에 대해:-
legacyFactoryFunction을 레거시 팩토리 함수 생성 알고리즘을 id, interface, realm에 대해 실행한 결과로 설정합니다.
-
DefineMethodProperty(target, id, legacyFactoryFunction, false)를 실행합니다.
-
-
-
-
각 콜백 인터페이스 interface에 대해, realm에 노출되고, 상수가 정의되어 있는 경우:
-
id를 interface의 식별자로 설정합니다.
-
interfaceObject를 레거시 콜백 인터페이스 객체 생성 알고리즘을 interface, id, realm에 대해 실행한 결과로 설정합니다.
-
DefineMethodProperty(target, id, interfaceObject, false)를 실행합니다.
-
-
각 네임스페이스 namespace에 대해, realm에 노출된 경우:
-
id를 namespace의 식별자로 설정합니다.
-
namespaceObject를 네임스페이스 객체 생성 알고리즘을 namespace, realm에 대해 실행한 결과로 설정합니다.
-
DefineMethodProperty(target, id, namespaceObject, false)를 실행합니다.
-
서로 다른 플랫폼 객체가 서로 다른 글로벌 객체를 가지더라도, [[PrimaryInterface]] 내부 슬롯에 같은 인터페이스를 참조할 수 있습니다. 예를 들어, 같은 오리진의 iframe이 있고, iframe의 메서드가 메인 페이지의 같은 종류의 요소에 호출되어도 예외가 발생하지 않습니다.
인터페이스 믹스인은 구현 알고리즘 평가에 직접 참여하지 않습니다. 대신, 인터페이스 믹스인이 포함된 각 인터페이스는 믹스인의 각 멤버에 대해 자신의 "복사본"을 가지며, 해당 operation function은 수신자가 구현하는 인터페이스가 믹스인을 포함하는지 확인합니다.
플랫폼 객체가 연관된 realm은 객체 생성 후 변경될 수 있습니다. 플랫폼 객체에 연관된 realm이 변경되면, [[Prototype]] 내부 슬롯은 즉시 해당 플랫폼 객체의 새 realm의 주 인터페이스의 인터페이스 프로토타입 객체로 업데이트되어야 합니다.
또한, [Global
] 확장 속성을 가진
인터페이스를 구현하는
플랫폼 객체는 다음에서 선언적으로 프로퍼티를 얻습니다:
대신 그 프로퍼티들을 명령형으로 정의해야 합니다.
3.8.1. [[SetPrototypeOf]]
[Global] 확장 속성을 가진 인터페이스를 구현하는 플랫폼 객체 O의 [[SetPrototypeOf]] 내부 메서드가 자바스크립트 값 V로 호출될 때, 다음 단계를 수행합니다:
-
O의 연관된 realm의 글로벌 프로토타입 체인이 변경 가능 이 true이면, ? OrdinarySetPrototypeOf(O, V)를 반환합니다.
-
? 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로 호출될 때 다음과 같이 동작해야 합니다:
-
? LegacyPlatformObjectGetOwnProperty(O, P,
false )를 반환합니다.
3.9.2. [[Set]]
모든 레거시 플랫폼 객체 O의 [[Set]] 내부 메서드는 프로퍼티 이름 P, 값 V, 자바스크립트 값 Receiver로 호출될 때 다음과 같이 동작해야 합니다:
-
O와 Receiver가 같은 객체라면:
-
O가 인덱스 프로퍼티 setter가 있는 인터페이스를 구현하고, P가 배열 인덱스라면:
-
인덱스 프로퍼티 setter 호출을 O에 P와 V로 실행합니다.
-
true 를 반환합니다.
-
-
O가 이름 프로퍼티 setter가 있는 인터페이스를 구현하고, P가 문자열(String)이라면:
-
이름 프로퍼티 setter 호출을 O에 P와 V로 실행합니다.
-
true 를 반환합니다.
-
-
-
ownDesc를 ? LegacyPlatformObjectGetOwnProperty(O, P,
true )의 결과로 설정합니다. -
? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc)를 수행합니다.
3.9.3. [[DefineOwnProperty]]
레거시 플랫폼 객체 O의 [[DefineOwnProperty]] 내부 메서드는 프로퍼티 키 P와 프로퍼티 디스크립터(Property Descriptor) Desc로 호출될 때 다음 단계를 수행해야 합니다:
-
O가 인덱스 프로퍼티를 지원하고 P가 배열 인덱스라면:
-
IsDataDescriptor(Desc)의 결과가
false 라면false 를 반환합니다. -
O가 인덱스 프로퍼티 setter가 있는 인터페이스를 구현하지 않는다면
false 를 반환합니다. -
인덱스 프로퍼티 setter 호출을 O에 P와 Desc.[[Value]]로 실행합니다.
-
true 를 반환합니다.
-
-
O가 이름 프로퍼티를 지원하고, O가 [Global] 확장 속성이 있는 인터페이스를 구현하지 않으며, P가 문자열이며, P가 O의 위조 불가 프로퍼티 이름이 아니라면:
-
P가 지원되는 프로퍼티 이름이 아니면 creating을 true로, 그렇지 않으면 false로 설정합니다.
-
O가 [LegacyOverrideBuiltIns] 확장 속성이 있는 인터페이스를 구현하거나 O에 P라는 own 프로퍼티가 없다면:
-
creating이 false이고 O가 이름 프로퍼티 setter가 있는 인터페이스를 구현하지 않는다면
false 를 반환합니다. -
O가 이름 프로퍼티 setter가 있는 인터페이스를 구현한다면:
-
IsDataDescriptor(Desc)의 결과가
false 라면false 를 반환합니다. -
이름 프로퍼티 setter 호출을 O에 P와 Desc.[[Value]]로 실행합니다.
-
true 를 반환합니다.
-
-
-
-
! OrdinaryDefineOwnProperty(O, P, Desc)를 반환합니다.
3.9.4. [[Delete]]
모든 레거시 플랫폼 객체 O의 [[Delete]] 내부 메서드는 프로퍼티 이름 P로 호출될 때 다음과 같이 동작해야 합니다.
-
O가 인덱스 프로퍼티를 지원하고, P가 배열 인덱스라면:
-
index가 지원되는 프로퍼티 인덱스가 아니면
true 를 반환합니다. -
false 를 반환합니다.
-
O가 이름 프로퍼티를 지원하고, O가 [Global] 확장 속성이 있는 인터페이스를 구현하지 않으며, 이름 프로퍼티 가시성 알고리즘을 프로퍼티 이름 P와 객체 O로 호출한 결과가 true라면:
-
O가 이름 프로퍼티 deleter가 있는 인터페이스를 구현하지 않는다면
false 를 반환합니다. -
operation을 이름 프로퍼티 deleter를 선언할 때 사용한 operation으로 설정합니다.
-
operation이 식별자 없이 정의되었다면:
-
인터페이스 설명에 명시된 단계에 따라 기존 이름 프로퍼티 삭제를 P 이름으로 수행합니다.
-
해당 단계가 삭제 실패를 나타낸다면
false 를 반환합니다.
-
-
그 외의 경우, operation이 식별자와 함께 정의되었다면:
-
true 를 반환합니다.
-
-
O에 이름 P의 own 프로퍼티가 있다면:
-
그 프로퍼티가 configurable이 아니라면
false 를 반환합니다. -
그 외의 경우, O에서 해당 프로퍼티를 제거합니다.
-
-
true 를 반환합니다.
3.9.5. [[PreventExtensions]]
레거시 플랫폼 객체의 [[PreventExtensions]] 내부 메서드가 호출될 때, 다음 단계를 수행합니다:
-
false 를 반환합니다.
참고: 이렇게 하면 레거시 플랫폼 객체가 [[PreventExtensions]]가 실패하도록 만들어 계속 확장 가능하게 유지됩니다.
3.9.6. [[OwnPropertyKeys]]
이 문서는 플랫폼 객체가 인터페이스를 구현할 때 (또는 예외를 나타내는 플랫폼 객체에 대해) 전체 프로퍼티 열거 순서를 정의하지 않습니다. 그러나 레거시 플랫폼 객체에 대해서는 아래와 같이 [[OwnPropertyKeys]] 내부 메서드를 정의합니다.
레거시 플랫폼 객체 O의 [[OwnPropertyKeys]] 내부 메서드가 호출될 때, 다음 단계를 수행합니다:
-
keys를 자바스크립트 String과 Symbol 값의 빈 목록으로 생성합니다.
-
O가 인덱스 프로퍼티를 지원하면, 각 O의 지원되는 프로퍼티 인덱스 index에 대해, 숫자 오름차순으로 append ! ToString(index)을 keys에 추가합니다.
-
O가 이름 프로퍼티를 지원하면, 각 O의 지원되는 프로퍼티 이름 P 중 이름 프로퍼티 가시성 알고리즘에 따라 visible한 것에 대해, append P를 keys에 추가합니다.
-
각 O의 own 프로퍼티 키 중 String 타입 P에 대해, 프로퍼티 생성 시간 오름차순으로 append P를 keys에 추가합니다.
-
각 O의 own 프로퍼티 키 중 Symbol 타입 P에 대해, 프로퍼티 생성 시간 오름차순으로 append P를 keys에 추가합니다.
-
단언: keys에는 중복 항목이 없다.
-
keys를 반환합니다.
3.9.7. 추상 연산
프로퍼티 이름 P가 배열 인덱스인지 판단하기 위해, 다음 알고리즘을 적용한다:
-
P가 문자열이 아니면
false 를 반환합니다. -
index를 CanonicalNumericIndexString(P)의 결과로 설정합니다.
-
index가
undefined 이면false 를 반환합니다. -
IsInteger(index)가
false 이면false 를 반환합니다. -
index가 −0이면
false 를 반환합니다. -
index < 0이면
false 를 반환합니다. -
index ≥ 232 − 1이면
false 를 반환합니다.참고: 232 − 1은 자바스크립트에서 허용되는 최대 배열 길이입니다.
-
true 를 반환합니다.
이름 프로퍼티
가시성 알고리즘은 주어진 이름 프로퍼티가 객체에 노출되는지 판별할 때 사용합니다.
일부 이름 프로퍼티는 [LegacyOverrideBuiltIns
]
확장 속성에
따라 객체에 노출되지 않을 수 있습니다.
프로퍼티 이름 P 및 객체 O에 대해 알고리즘은 다음과 같이 동작합니다:
-
P가 O의 지원되는 프로퍼티 이름이 아니면 false를 반환합니다.
-
O에 P라는 own 프로퍼티가 있으면 false를 반환합니다.
참고: 이는 O에 위조 불가 프로퍼티가 있는 경우도 포함합니다. 실제로 이런 프로퍼티는 객체가 지원되는 프로퍼티 이름을 갖기 전에 항상 설정되며, 일단 설정되면 해당 이름 프로퍼티는 더 이상 노출되지 않습니다.
-
O가 [
LegacyOverrideBuiltIns
] 확장 속성이 있는 인터페이스를 구현한다면 true를 반환합니다. -
prototype을 O.[[GetPrototypeOf]]()로 설정합니다.
-
prototype이 null이 아닐 때까지 반복:
-
prototype이 이름 프로퍼티 객체가 아니고, prototype에 P라는 own 프로퍼티가 있으면 false를 반환합니다.
-
prototype을 prototype.[[GetPrototypeOf]]()로 갱신합니다.
-
-
true를 반환합니다.
이 알고리즘은 이름 프로퍼티를 가진 객체의 프로퍼티 해석 순서가 다음과 같이 이루어지도록 보장합니다:
-
인덱스 프로퍼티.
-
own 프로퍼티(위조 불가 속성과 연산 포함).
-
[
LegacyOverrideBuiltIns
]이 지정된 경우:-
이름 프로퍼티.
-
프로토타입 체인에서 오는 프로퍼티.
-
-
[
LegacyOverrideBuiltIns
]이 없는 경우:-
프로토타입 체인에서 오는 프로퍼티.
-
이름 프로퍼티.
-
플랫폼 객체 O에서 프로퍼티 이름 P와 자바스크립트 값 V로 인덱스 프로퍼티 setter 호출을 하려면 다음 단계를 수행합니다:
-
index가 지원되는 프로퍼티 인덱스가 아니면 creating을 true로, 그렇지 않으면 false로 설정합니다.
-
operation을 인덱스 프로퍼티 setter를 선언한 operation으로 설정합니다.
-
T를 operation의 두 번째 인자의 타입으로 설정합니다.
-
value를 V를 T 타입의 IDL 값으로 변환한 결과로 설정합니다.
-
operation이 식별자 없이 정의되어 있다면:
-
creating이 true이면 인터페이스 설명에 따라 새 인덱스 프로퍼티 값 설정 단계(인덱스 index, 값 value)를 수행합니다.
-
그 외의 경우(creating이 false) 인터페이스 설명에 따라 기존 인덱스 프로퍼티 값 설정 단계(인덱스 index, 값 value)를 수행합니다.
-
-
그 외의 경우, operation이 식별자와 함께 정의되어 있다면 메서드 단계를 operation에 대해 O를 this로, 인자값 « index, value »로 실행합니다.
플랫폼 객체 O에서 프로퍼티 이름 P와 자바스크립트 값 V로 이름 프로퍼티 setter 호출을 하려면 다음 단계를 수행합니다:
-
creating을 P가 지원되는 프로퍼티 이름이 아니면 true로, 그렇지 않으면 false로 설정합니다.
-
operation을 이름 프로퍼티 setter를 선언한 operation으로 설정합니다.
-
T를 operation의 두 번째 인자의 타입으로 설정합니다.
-
value를 V를 T 타입의 IDL 값으로 변환한 결과로 설정합니다.
-
operation이 식별자 없이 정의되어 있다면:
-
creating이 true이면 인터페이스 설명에 따라 새 이름 프로퍼티 값 설정 단계(P, value)를 수행합니다.
-
그 외의 경우(creating이 false) 인터페이스 설명에 따라 기존 이름 프로퍼티 값 설정 단계(P, value)를 수행합니다.
-
-
그 외의 경우, operation이 식별자와 함께 정의되어 있다면 메서드 단계를 operation에 대해 O를 this로, 인자값 « P, value »로 실행합니다.
LegacyPlatformObjectGetOwnProperty 추상 연산은 객체 O, 프로퍼티 이름 P, 불리언 ignoreNamedProps 값을 받아 다음 단계를 수행합니다:
-
O가 인덱스 프로퍼티를 지원하고, P가 배열 인덱스라면:
-
index가 지원되는 프로퍼티 인덱스라면:
-
operation을 인덱스 프로퍼티 getter를 선언한 operation으로 설정합니다.
-
value를 초기화되지 않은 변수로 설정합니다.
-
operation이 식별자 없이 정의되어 있다면 value를 인터페이스 설명에 따라 인덱스 프로퍼티 값 결정(index)의 결과로 설정합니다.
-
그 외의 경우, operation이 식별자와 함께 정의되어 있다면 value를 메서드 단계를 operation에 대해 O를 this로, 인자값 « index »로 실행한 결과로 설정합니다.
-
desc를 필드가 없는 새로운 프로퍼티 디스크립터(Property Descriptor)로 생성합니다.
-
desc.[[Value]]를 value를 자바스크립트 값으로 변환한 결과로 설정합니다.
-
O가 인덱스 프로퍼티 setter가 있는 인터페이스를 구현하면 desc.[[Writable]]을
true 로, 그렇지 않으면false 로 설정합니다. -
desc.[[Enumerable]] 및 desc.[[Configurable]]을
true 로 설정합니다. -
desc를 반환합니다.
-
-
ignoreNamedProps를 true로 설정합니다.
-
O가 이름 프로퍼티를 지원하고, ignoreNamedProps가 false이면:
-
이름 프로퍼티 가시성 알고리즘을 프로퍼티 이름 P와 객체 O로 실행한 결과가 true이면:
-
operation을 이름 프로퍼티 getter를 선언한 operation으로 설정합니다.
-
value를 초기화되지 않은 변수로 설정합니다.
-
operation이 식별자 없이 정의되어 있다면 value를 인터페이스 설명에 따라 이름 프로퍼티 값 결정(P)의 결과로 설정합니다.
-
그 외의 경우, operation이 식별자와 함께 정의되어 있다면 value를 메서드 단계를 operation에 대해 O를 this로, 인자값 « P »로 실행한 결과로 설정합니다.
-
desc를 필드가 없는 새로운 프로퍼티 디스크립터(Property Descriptor)로 생성합니다.
-
desc.[[Value]]를 value를 자바스크립트 값으로 변환한 결과로 설정합니다.
-
O가 이름 프로퍼티 setter가 있는 인터페이스를 구현하면 desc.[[Writable]]을
true 로, 그렇지 않으면false 로 설정합니다. -
O가 [
LegacyUnenumerableNamedProperties
] 확장 속성이 있는 인터페이스를 구현하면 desc.[[Enumerable]]을false 로, 그렇지 않으면true 로 설정합니다. -
desc.[[Configurable]]을
true 로 설정합니다. -
desc를 반환합니다.
-
-
-
OrdinaryGetOwnProperty(O, P)를 반환합니다.
3.10. 관찰 가능한 배열 이그조틱 객체
관찰 가능한
배열 이그조틱 객체는 자바스크립트의
프록시(Proxy) 이그조틱 객체의 한 종류로,
이 절에서 정의된 프록시 트랩을 사용해 생성됩니다. 자바스크립트 명세는
프록시 이그조틱 객체가 Array
인스턴스를 프록시 대상으로 가질 때 특별 처리를 포함하므로,
관찰 가능한 배열
타입이 자바스크립트 코드에 이러한 특별 처리가 유지된 채 노출되도록 하기 위해 이렇게 정의합니다.
관찰 가능한 배열 이그조틱 객체의 프록시 트랩은 일반 Array
인스턴스의 불변성 외에도 다음의 불변성을 보장합니다:
-
배열에 구멍(hole)이 없이, 0부터
observableArray.length
− 1 사이 모든 프로퍼티가 지정된 Web IDL 타입에 호환되는 값으로 채워집니다. 해당 범위를 벗어나는 배열 인덱스 프로퍼티는 존재하지 않습니다. -
중요한 프로퍼티의 프로퍼티 디스크립터는 기본 설정에서 변경될 수 없습니다. 인덱스 프로퍼티는 항상 configurable, enumerable, writable 데이터 프로퍼티로 유지되고,
length
프로퍼티는 non-configurable, non-enumerable, writable 데이터 프로퍼티로 유지됩니다. -
Object.preventExtensions()
등으로 배열에 추가 프로퍼티가 추가되는 것을 막을 수 없습니다.
-
innerArray를 ! ArrayCreate(0)로 생성합니다.
-
handler를 OrdinaryObjectCreate(
null , « [[Type]], [[SetAlgorithm]], [[DeleteAlgorithm]], [[BackingList]] »)로 생성합니다. -
handler.[[Type]]에 T를 할당합니다.
-
handler.[[SetAlgorithm]]에 setAlgorithm을 할당합니다.
-
handler.[[DeleteAlgorithm]]에 deleteAlgorithm을 할당합니다.
-
defineProperty를 CreateBuiltinFunction(§ 3.10.1 defineProperty의 단계, « », realm)로 생성합니다.
-
! CreateDataPropertyOrThrow(handler, "
defineProperty
", defineProperty)를 실행합니다. -
deleteProperty를 CreateBuiltinFunction(§ 3.10.2 deleteProperty의 단계, « », realm)로 생성합니다.
-
! CreateDataPropertyOrThrow(handler, "
deleteProperty
", deleteProperty)를 실행합니다. -
get를 CreateBuiltinFunction(§ 3.10.3 get의 단계, « », realm)로 생성합니다.
-
! CreateDataPropertyOrThrow(handler, "
get
", get)를 실행합니다. -
getOwnPropertyDescriptor를 CreateBuiltinFunction(§ 3.10.4 getOwnPropertyDescriptor의 단계, « », realm)로 생성합니다.
-
! CreateDataPropertyOrThrow(handler, "
getOwnPropertyDescriptor
", getOwnPropertyDescriptor)를 실행합니다. -
has를 CreateBuiltinFunction(§ 3.10.5 has의 단계, « », realm)로 생성합니다.
-
! CreateDataPropertyOrThrow(handler, "
has
", has)를 실행합니다. -
ownKeys를 CreateBuiltinFunction(§ 3.10.6 ownKeys의 단계, « », realm)로 생성합니다.
-
! CreateDataPropertyOrThrow(handler, "
ownKeys
", ownKeys)를 실행합니다. -
preventExtensions를 CreateBuiltinFunction(§ 3.10.7 preventExtensions의 단계, « », realm)로 생성합니다.
-
! CreateDataPropertyOrThrow(handler, "
preventExtensions
", preventExtensions)를 실행합니다. -
set를 CreateBuiltinFunction(§ 3.10.8 set의 단계, « », realm)로 생성합니다.
-
! CreateDataPropertyOrThrow(handler, "
set
", set)를 실행합니다. -
! ProxyCreate(innerArray, handler)를 반환합니다.
3.10.1. defineProperty
defineProperty
프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P,
descriptorObj가 주어진 경우):
-
handler를
this 값으로 설정합니다. -
descriptor를 ! ToPropertyDescriptor(descriptorObj)로 설정합니다.
-
P가 "length"이면:
-
IsAccessorDescriptor(descriptor) 값이
true 이면false 를 반환합니다. -
descriptor.[[Configurable]]가 존재하고 값이
true 이면false 를 반환합니다. -
descriptor.[[Enumerable]]가 존재하고 값이
true 이면false 를 반환합니다. -
descriptor.[[Writable]]가 존재하고 값이
false 이면false 를 반환합니다. -
descriptor.[[Value]]가 존재하면 길이 설정 알고리즘을 handler, descriptor.[[Value]]로 실행한 결과를 반환합니다.
-
true 를 반환합니다.
-
-
P가 배열 인덱스이면:
-
IsAccessorDescriptor(descriptor) 값이
true 이면false 를 반환합니다. -
descriptor.[[Configurable]]가 존재하고 값이
false 이면false 를 반환합니다. -
descriptor.[[Enumerable]]가 존재하고 값이
false 이면false 를 반환합니다. -
descriptor.[[Writable]]가 존재하고 값이
false 이면false 를 반환합니다. -
descriptor.[[Value]]가 존재하면 인덱스 값 설정 알고리즘을 handler, P, descriptor.[[Value]]로 실행한 결과를 반환합니다.
-
true 를 반환합니다.
-
-
? O.[[DefineOwnProperty]](P, descriptor)를 반환합니다.
3.10.2. deleteProperty
deleteProperty
프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P가 주어진 경우):
3.10.3.
get
get
프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P, Receiver가 주어진 경우):
3.10.4. getOwnPropertyDescriptor
getOwnPropertyDescriptor
프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P가 주어진 경우):
-
handler를
this 값으로 설정합니다. -
length를 handler.[[BackingList]]의 크기로 설정합니다.
-
P가 "length"이면 ! FromPropertyDescriptor(PropertyDescriptor{[[Configurable]]:
false , [[Enumerable]]:false , [[Writable]]:true , [[Value]]: length })를 반환합니다. -
P가 배열 인덱스이면
-
index ≥ length이면
undefined 를 반환합니다. -
jsValue를 변환 하여 얻은 handler.[[BackingList]][index]의 JavaScript 값으로 한다.
-
위 단계는 절대 예외를 발생시키지 않습니다.
-
FromPropertyDescriptor(PropertyDescriptor{[[Configurable]]:
true , [[Enumerable]]:true , [[Writable]]:true , [[Value]]: jsValue })를 반환합니다.
-
FromPropertyDescriptor(? O.[[GetOwnProperty]](P))를 반환합니다.
3.10.5.
has
has
프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P가 주어진 경우):
3.10.6.
ownKeys
ownKeys
프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O가 주어진 경우):
3.10.7. preventExtensions
preventExtensions
프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해):
-
false 를 반환합니다.
3.10.8.
set
set
프록시 트랩의 단계(관찰 가능한 배열 이그조틱 객체에 대해, O, P, V,
Receiver가 주어진 경우):
3.10.9. 추상 연산
-
uint32Len ≠ numberLen이면
RangeError
예외를 throw합니다. -
oldLen을 handler.[[BackingList]]의 크기로 설정합니다.
-
uint32Len > oldLen이면
false 를 반환합니다. -
indexToDelete를 oldLen − 1로 설정합니다.
-
While indexToDelete ≥ uint32Len 동안:
-
handler.[[DeleteAlgorithm]] 알고리즘 단계를 handler.[[BackingList]][indexToDelete]와 indexToDelete로 실행합니다.
-
handler.[[BackingList]]의 마지막 아이템을 제거합니다.
-
indexToDelete를 indexToDelete − 1로 설정합니다.
-
-
true 를 반환합니다.
-
oldLen을 handler.[[BackingList]]의 크기로 설정합니다.
-
index > oldLen이면
false 를 반환합니다. -
idlValue를 V를 handler.[[Type]] 타입의 IDL 값으로 변환한 결과로 설정합니다.
-
index < oldLen이면:
-
handler.[[DeleteAlgorithm]] 알고리즘 단계를 handler.[[BackingList]][index]와 index로 실행합니다.
-
-
handler.[[SetAlgorithm]] 알고리즘 단계를 idlValue와 index로 실행합니다.
-
index = oldLen이면 idlValue를 handler.[[BackingList]]에 추가합니다.
-
그 외의 경우, handler.[[BackingList]][index]를 idlValue로 설정합니다.
-
true 를 반환합니다.
3.11. 콜백 인터페이스
§ 2.12 인터페이스를 구현하는 객체에서 설명한 것처럼, 콜백 인터페이스는 스크립트에서 임의의 자바스크립트 객체로 구현될 수 있습니다. 아래의 경우들은 주어진 객체에서 콜백 인터페이스의 연산이 어떻게 호출되는지 설명합니다:
-
객체가 호출 가능(callable)하면, 연산의 구현체는 그 호출 가능한 객체 자체입니다.
-
그 외의 경우, 연산의 구현체는 객체의 내부 [[Get]] 메서드를 연산의 식별자를 프로퍼티 이름으로 하여 호출한 결과를 호출하는 것입니다.
자바스크립트 객체는 해당 객체가 콜백 인터페이스를 구현하는 것으로 간주되기 위해 그 인터페이스에 선언된 상수에 해당하는 프로퍼티를 가질 필요가 없습니다.
Web IDL 인자 리스트란 각 값이 IDL 값이거나 “누락(missing)”이라는 특수 값(선택적 인자가 누락됨을 나타냄)인 값 목록(list)입니다.
-
jsArgs를 빈 목록으로 생성합니다.
-
i를 0으로 설정합니다.
-
count를 0으로 설정합니다.
-
i < args의 크기인 동안:
-
args[i]가 특수 값 “missing”이면, jsArgs에
undefined 를 추가합니다. -
그 외의 경우, args[i]는 IDL 값입니다:
-
convertResult를 args[i]를 자바스크립트 값으로 변환한 결과로 설정합니다. 예외가 발생하면 다시 throw합니다.
-
convertResult를 jsArgs에 추가합니다.
-
count를 i + 1로 설정합니다.
-
-
i를 i + 1로 설정합니다.
-
-
jsArgs를 count 개의 항목만 남도록 잘라냅니다.
-
jsArgs를 반환합니다.
사용자 객체의 연산 호출하기: 콜백 인터페이스 타입 값 value, 연산 이름 opName, Web IDL 인자 리스트 args, 선택적 콜백 this 값 thisArg가 주어졌을 때, 다음 단계를 수행합니다. 이 단계들은 IDL 값을 반환하거나 예외를 throw합니다.
-
completion을 초기화되지 않은 변수로 설정합니다.
-
thisArg가 주어지지 않았다면 thisArg를
undefined 로 설정합니다. -
O를 value에 해당하는 자바스크립트 객체로 설정합니다.
-
realm을 O의 연결된 realm으로 설정합니다.
-
relevant settings를 realm의 설정 객체(settings object)로 설정합니다.
-
stored settings를 value의 콜백 컨텍스트로 설정합니다.
-
스크립트 실행 준비를 relevant settings로 실행합니다.
-
콜백 실행 준비를 stored settings로 실행합니다.
-
X를 O로 설정합니다.
-
IsCallable(O)가 false이면:
-
getResult를 Completion(Get(O, opName))로 설정합니다.
-
getResult가 비정상 완료(abrupt completion)이면, completion에 getResult를 할당하고 return 단계로 점프합니다.
-
X를 getResult.[[Value]]로 설정합니다.
-
IsCallable(X)가
false 이면, completion을 Completion Record { [[Type]]: throw, [[Value]]: 새로 생성된TypeError
객체, [[Target]]: 빈 값 }로 설정하고 return 단계로 점프합니다. -
thisArg를 O로 설정합니다(주어진 값을 덮어씀).
-
-
jsArgs를 args를 자바스크립트 인자 리스트로 변환한 결과로 설정합니다. 변환 중 예외 발생 시, completion을 예외를 나타내는 completion 값으로 설정하고 return 단계로 점프합니다.
-
callResult를 Completion(Call(X, thisArg, jsArgs))로 설정합니다.
-
callResult가 비정상 완료(abrupt completion)이면 completion에 callResult를 할당하고 return 단계로 점프합니다.
-
completion을 callResult.[[Value]]를 연산의 반환 타입과 동일한 타입의 IDL 값으로 변환한 결과로 설정합니다. 변환 중 예외 발생 시 completion을 예외를 나타내는 completion 값으로 설정합니다.
-
Return: 이 시점에서 completion은 IDL 값이거나 비정상 완료임.
-
콜백 실행 후 정리(clean up)를 stored settings로 실행합니다.
-
스크립트 실행 후 정리(clean up)를 relevant settings로 실행합니다.
-
completion이 IDL 값이면 completion을 반환합니다.
-
completion이 비정상 완료이고, 연산이 반환 타입이 프라미스 타입이 아닌 경우, completion.[[Value]]를 throw합니다.
-
rejectedPromise를 ! Call(
%Promise.reject%
,%Promise%
, «completion.[[Value]]»)로 설정합니다. -
rejectedPromise를 연산의 반환 타입으로 변환한 결과를 반환합니다.
-
3.11.1. 레거시 콜백 인터페이스 객체
특정 콜백 인터페이스가 특정 realm에 노출되고, 해당 인터페이스에 상수가 정의되어 있다면, 대응하는 프로퍼티가 그 realm의 글로벌 객체에 존재합니다. 프로퍼티 이름은 해당 콜백 인터페이스의 식별자이며, 그 값은 레거시 콜백 인터페이스 객체입니다.
특정 콜백 인터페이스에 대한 레거시 콜백 인터페이스 객체는 내장 함수 객체입니다. 해당 객체에는 그 인터페이스에 정의된 상수에 대응하는 프로퍼티가 있습니다. 자세한 내용은 § 3.7.5 상수 참고.
참고: 레거시 콜백
인터페이스 객체는 함수 객체이므로,
typeof
연산자를 적용하면 "function"이 반환됩니다.
특정 콜백 인터페이스 interface에 대해, 식별자 id와 realm realm이 주어졌을 때, 레거시 콜백 인터페이스 객체 생성 알고리즘은 다음과 같습니다:
-
steps를 다음 단계로 설정합니다:
-
TypeError 예외를 throw합니다.
-
-
F를 CreateBuiltinFunction(steps, « », realm)으로 생성합니다.
-
SetFunctionName(F, id)를 수행합니다.
-
SetFunctionLength(F, 0)를 수행합니다.
-
상수 정의를 interface, F, realm에 대해 수행합니다.
-
F를 반환합니다.
3.12. 콜백 함수 호출하기
자바스크립트 호출 가능(callable) 객체가 콜백 함수 값으로 사용될 때는, 콜백 인터페이스 값의 연산을 호출하는 방식(이전 섹션 참조)과 유사하게 호출됩니다.
콜백 함수 타입 값
callable을 Web IDL 인자 리스트 args, 예외 동작
exceptionBehavior("report
" 또는 "rethrow
")와 선택적 콜백 this
값 thisArg로 콜백 함수 호출하기:
다음 단계를 수행합니다. 이 단계는 IDL 값을 반환하거나 예외를 throw합니다.
exceptionBehavior 인자는 callable의 반환 타입이 프라미스 타입이 아닐 때만 제공되어야 하며, callable의 반환 타입이 undefined
또는 any
가 아니라면
반드시 "rethrow
"여야 합니다.
rethrow
"가 공급된 것으로 간주해야 합니다.
-
completion을 초기화되지 않은 변수로 설정합니다.
-
thisArg가 주어지지 않았다면 thisArg를
undefined 로 설정합니다. -
F를 callable에 해당하는 자바스크립트 객체로 설정합니다.
-
IsCallable(F)가
false 이면:-
참고: 이것은 콜백 함수가 [
LegacyTreatNonObjectAsNull
] 특성이 붙은 attribute에서 온 경우에만 발생할 수 있습니다. -
undefined 를 콜백 함수의 반환 타입으로 변환한 결과를 반환합니다.
-
-
realm을 F의 연결된 realm으로 설정합니다.
-
relevant settings를 realm의 설정 객체로 설정합니다.
-
stored settings를 callable의 콜백 컨텍스트로 설정합니다.
-
스크립트 실행 준비를 relevant settings로 실행합니다.
-
콜백 실행 준비를 stored settings로 실행합니다.
-
jsArgs를 args를 자바스크립트 인자 리스트로 변환한 결과로 설정합니다. 변환 중 예외가 발생하면 completion을 예외를 나타내는 completion 값으로 설정하고 return 단계로 점프합니다.
-
callResult를 Completion(Call(F, thisArg, jsArgs))로 설정합니다.
-
callResult가 비정상 완료(abrupt completion)이면 completion을 callResult로 설정하고 return 단계로 점프합니다.
-
completion을 callResult.[[Value]]를 callable의 반환 타입과 동일한 타입의 IDL 값으로 변환한 결과로 설정합니다. 변환 중 예외가 발생하면 completion을 예외를 나타내는 completion 값으로 설정합니다.
-
Return: 이 시점에서 completion은 IDL 값이거나 비정상 완료입니다.
-
콜백 실행 후 정리(clean up)를 stored settings로 실행합니다.
-
스크립트 실행 후 정리(clean up)를 relevant settings로 실행합니다.
-
completion이 IDL 값이면 completion을 반환합니다.
-
exceptionBehavior가 "
rethrow
"이면 completion.[[Value]]를 throw합니다. -
그 외 exceptionBehavior가 "
report
"일 경우: -
rejectedPromise를 ! Call(
%Promise.reject%
,%Promise%
, «completion.[[Value]]»)로 설정합니다. -
rejectedPromise를 콜백 함수의 반환 타입으로 변환한 결과를 반환합니다.
-
일부 콜백 함수는 생성자(constructor)로 사용될 수 있습니다. 이런 콜백 함수는 프라미스 타입 반환 타입을 갖지 않아야 합니다.
콜백 함수 타입 값 callable을 Web IDL 인자 리스트 args로 콜백 함수 생성자 호출을 하려면 다음 단계를 수행합니다. 이 단계는 IDL 값을 반환하거나 예외를 throw합니다.
-
completion을 초기화되지 않은 변수로 설정합니다.
-
F를 callable에 해당하는 자바스크립트 객체로 설정합니다.
-
IsConstructor(F)가
false 이면TypeError
예외를 throw합니다. -
realm을 F의 연결된 realm으로 설정합니다.
-
relevant settings를 realm의 설정 객체로 설정합니다.
-
stored settings를 callable의 콜백 컨텍스트로 설정합니다.
-
스크립트 실행 준비를 relevant settings로 실행합니다.
-
콜백 실행 준비를 stored settings로 실행합니다.
-
jsArgs를 args를 자바스크립트 인자 리스트로 변환한 결과로 설정합니다. 변환 중 예외가 발생하면 completion을 예외를 나타내는 completion 값으로 설정하고 return 단계로 점프합니다.
-
callResult를 Completion(Construct(F, jsArgs))로 설정합니다.
-
callResult가 비정상 완료(abrupt completion)이면 completion을 callResult로 설정하고 return 단계로 점프합니다.
-
completion을 callResult.[[Value]]를 callable의 반환 타입과 동일한 타입의 IDL 값으로 변환한 결과로 설정합니다. 변환 중 예외가 발생하면 completion을 예외를 나타내는 completion 값으로 설정합니다.
-
Return: 이 시점에서 completion은 IDL 값이거나 비정상 완료입니다.
-
콜백 실행 후 정리(clean up)를 stored settings로 실행합니다.
-
스크립트 실행 후 정리(clean up)를 relevant settings로 실행합니다.
-
completion이 비정상 완료이면 completion.[[Value]]를 throw합니다.
-
completion을 반환합니다.
-
3.13. 네임스페이스
특정 네임스페이스가 특정 realm에 노출되는 경우, 해당 realm의 글로벌 객체에 대응하는 프로퍼티가 존재합니다. 프로퍼티 이름은 네임스페이스의 식별자이고, 값은 네임스페이스 객체라 부르는 객체입니다.
네임스페이스 객체의 특성은 § 3.13.1 네임스페이스 객체에서 설명합니다.
3.13.1. 네임스페이스 객체
특정 네임스페이스 namespace와 realm realm에 대해 네임스페이스 객체는 다음과 같이 생성됩니다:
-
namespaceObject를 OrdinaryObjectCreate(realm.[[Intrinsics]].[[
%Object.prototype%
]])로 생성합니다. -
정규 속성 정의 알고리즘을 namespace, namespaceObject, realm에 대해 실행합니다.
-
정규 연산 정의 알고리즘을 namespace, namespaceObject, realm에 대해 실행합니다.
-
상수 정의 알고리즘을 namespace, namespaceObject, realm에 대해 실행합니다.
-
각 노출된 인터페이스 interface 중, [
LegacyNamespace
] 확장 속성이 있고, 그 인자가 namespace의 식별자인 경우:-
id를 interface의 식별자로 설정합니다.
-
interfaceObject를 인터페이스 객체 생성 알고리즘을 interface, id, realm에 대해 실행한 결과로 설정합니다.
-
DefineMethodProperty(namespaceObject, id, interfaceObject, false)를 실행합니다.
-
-
namespaceObject를 반환합니다.
네임스페이스 객체의 class string은 네임스페이스의 식별자입니다.
3.14. 예외
3.14.1.
DOMException
커스텀 바인딩
자바스크립트 바인딩에서는 DOMException
의
인터페이스 프로토타입 객체의 [[Prototype]] 내부 슬롯은 %Error.prototype% 내재 객체로 설정됩니다(추상 연산 인터페이스 프로토타입 객체 생성에 따라).
또한 [[ErrorData]] 슬롯을 가지며, 모든 내장 예외와 같습니다.
추가적으로, 구현체가 네이티브 Error
객체에 특수 기능이나 비표준 프로퍼티(예: stack
프로퍼티)를 제공한다면, 해당 기능도 DOMException
객체에도 노출되어야 합니다.
3.14.2. 예외 객체
단순 예외는 해당 타입의 네이티브 자바스크립트 객체로 표현됩니다.
DOMException
은
플랫폼 객체로 표현되며,
DOMException
인터페이스를 구현합니다.
3.14.3. 예외 생성 및 throw
-
message를 예외 상황에 적합한 구현체 정의(implementation-defined) 메시지로 설정합니다. 호출 명세가 구현체가 메시지를 구성하는 데 참고할 수 있는 정보를 포함할 수 있습니다.
구현체는 민감하거나 보안 정보가 누출되지 않도록 주의해야 합니다. 예를 들어 크로스 오리진 프레임의 URL, 사용자를 식별할 수 있는 정보 등이 포함되지 않아야 합니다.
-
args를 « message »로 설정합니다.
-
constructor를 현재 realm.[[Intrinsics]].[[%T%]]로 설정합니다.
DOMException
의
예외 생성 알고리즘(name:
name):
-
단언: name이
DOMException
이름 테이블에 포함되어 있다. -
ex를 new
DOMException
으로 현재 realm에서 생성합니다. -
ex의 name을 name으로 설정합니다.
-
ex의 message를 예외 상황에 적합한 구현체 정의 메시지로 설정합니다. 호출 명세가 구현체가 메시지를 구성하는 데 참고할 수 있는 정보를 포함할 수 있습니다.
구현체는 민감하거나 보안 정보가 누출되지 않도록 주의해야 합니다. 예를 들어 크로스 오리진 프레임의 URL, 사용자를 식별할 수 있는 정보 등이 포함되지 않아야 합니다.
-
ex를 반환합니다.
DOMException
파생 인터페이스의 예외 생성
알고리즘(type: type, 추가 초기화 지침 포함):
-
ex를 new type 인터페이스의 인스턴스로 현재 realm에서 생성합니다.
-
ex의 name을 type으로 설정합니다.
-
ex의 message를 예외 상황에 적합한 구현체 정의 메시지로 설정합니다. 호출 명세가 구현체가 메시지를 구성하는 데 참고할 수 있는 정보를 포함할 수 있습니다.
구현체는 민감하거나 보안 정보가 누출되지 않도록 주의해야 합니다. 예를 들어 크로스 오리진 프레임의 URL, 사용자를 식별할 수 있는 정보 등이 포함되지 않아야 합니다.
-
호출자가 기술한 추가 초기화 작업을 ex에 대해 수행합니다.
-
ex를 반환합니다.
위 알고리즘들은 예외를 나타내는 객체가 함수 객체에서 전파될 때 해당 함수 객체의 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 객체 myMUinstanceof Object; // true otherMUinstanceof Object; // false otherMUinstanceof otherWindow. Object; // true try { otherMU. doComputation. call( myMU, - 1 ); } catch ( e) { console. assert( ! ( einstanceof DOMException)); console. assert( einstanceof otherWindow. DOMException); }
3.14.4. 예외 처리
별도로 명시되지 않는 한, 본 문서의 요구사항에 따라 자바스크립트 런타임 의미론이 호출되고 예외가 throw되어 종료될 때, 해당 예외는 호출자에게 전파되어야 하며, 호출자에서 잡히지 않으면 그 상위 호출자에게 계속 전파되어야 합니다.
문서 규약에 따라, 본 문서에서 명세된 알고리즘은 throw된 예외를 가로채거나, 예외가 throw된 경우의 정확한 처리 단계를 명시하거나, 비정상 완료(abrupt completion)을 명시적으로 처리할 수 있습니다.
다음 IDL 조각(fragment)은
두 인터페이스와 하나의 예외를 정의합니다.
ExceptionThrower
의 valueOf
속성은
값을 얻으려 할 때마다 예외를 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
타입은 ArrayBuffer
나
SharedArrayBuffer
([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 bindingconstructor (optional DOMString = "",
message optional DOMString = "Error");
name readonly attribute DOMString name ;readonly attribute DOMString message ;readonly attribute unsigned short code ;const unsigned short INDEX_SIZE_ERR = 1;const unsigned short = 2;
DOMSTRING_SIZE_ERR const unsigned short HIERARCHY_REQUEST_ERR = 3;const unsigned short WRONG_DOCUMENT_ERR = 4;const unsigned short INVALID_CHARACTER_ERR = 5;const unsigned short = 6;
NO_DATA_ALLOWED_ERR const unsigned short NO_MODIFICATION_ALLOWED_ERR = 7;const unsigned short NOT_FOUND_ERR = 8;const unsigned short NOT_SUPPORTED_ERR = 9;const unsigned short INUSE_ATTRIBUTE_ERR = 10;const unsigned short INVALID_STATE_ERR = 11;const unsigned short SYNTAX_ERR = 12;const unsigned short INVALID_MODIFICATION_ERR = 13;const unsigned short NAMESPACE_ERR = 14;const unsigned short INVALID_ACCESS_ERR = 15;const unsigned short = 16;
VALIDATION_ERR const unsigned short TYPE_MISMATCH_ERR = 17;const unsigned short SECURITY_ERR = 18;const unsigned short NETWORK_ERR = 19;const unsigned short ABORT_ERR = 20;const unsigned short URL_MISMATCH_ERR = 21;const unsigned short QUOTA_EXCEEDED_ERR = 22;const unsigned short TIMEOUT_ERR = 23;const unsigned short INVALID_NODE_TYPE_ERR = 24;const unsigned short DATA_CLONE_ERR = 25; };
참고: § 3.14.1 DOMException 커스텀 바인딩에서 논의된 바와 같이, 자바스크립트 바인딩은 인터페이스 타입에 대한 일반 요구사항 외에 추가 요구사항을 부과합니다.
각 DOMException
객체에는 name과
message가 연관되어 있으며, 둘 다 문자열입니다.
new DOMException(message, name)
생성자 단계는 다음과 같습니다:
name
getter 단계는 this의 name을 반환하는 것입니다.
message
getter 단계는 this의 message를 반환하는 것입니다.
code
getter 단계는 DOMException
이름 테이블에서
this의
name에 해당하는 레거시 코드를
반환하거나, 테이블에 항목이 없으면 0을 반환합니다.
DOMException
객체는 직렬화 가능한 객체입니다.
이 객체의 직렬화 단계는 value와 serialized가 주어졌을 때 다음과 같습니다:
- serialized.[[Name]]을 value의 name으로 설정합니다.
- serialized.[[Message]]를 value의 message로 설정합니다.
- User agent는 아직 명세되지 않은 흥미로운 부가 데이터(특히
stack
프로퍼티)의 직렬화 표현을 serialized에 붙여야 합니다.
이 객체의 역직렬화 단계는 value와 serialized가 주어졌을 때 다음과 같습니다:
- value의 name을 serialized.[[Name]]으로 설정합니다.
- value의 message를 serialized.[[Message]]로 설정합니다.
- serialized에 다른 데이터가 붙어 있으면 역직렬화하여 value에 붙입니다.
4.5. Function
callback Function =any (any ...);
arguments
Function
콜백 함수
타입은 인자에 어떤 제한도 없으며 반환값도 제한이 없는 함수 값을 나타내는 데 사용됩니다.
4.6. VoidFunction
callback VoidFunction =undefined ();
VoidFunction
콜백 함수
타입은 인자를 받지 않으며 반환값도 없는 함수 값을 나타내는 데 사용됩니다.
5. 확장성
이 절은 참고용입니다.
언어 바인딩 요구사항에 대한 확장은, 본 문서에서 정의된 것과 충돌하지 않는 확장 속성을 사용하여 명세할 수 있습니다. 개인이나 프로젝트별 사용을 위한 확장은 다른 명세에 나오는 IDL 조각에 포함하지 않아야 하며, 다른 명세에서 사용이 필요한 확장은 Web IDL 작업 그룹(작성 시점 기준 W3C Web Platform Working Group)과 협의하여 본 문서의 향후 버전에 포함될 수 있도록 하는 것이 좋습니다.
IDL 언어의 다른 측면에 대한 확장은 강력히 권장되지 않습니다.
6. 레거시 구성 요소
이 절은 참고용입니다.
레거시 Web IDL 구성 요소는 오직 레거시 웹 플랫폼 기능을 명세하기 위해 존재합니다.
일반적으로 "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 값 사이의 변환 계층을 정의합니다. 이 계층을 잘못 구현하면 보안 문제가 발생할 수 있습니다.
이 명세는 또한 any
및
object
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 문법
이 절에서는 시작 기호
문법의 각 생성식(production)은 오른쪽에 0이 아닌 개수의 터미널과 비터미널 기호가 있거나, 기호가 없음을 나타내는 엡실론(ε)이 있습니다. 대문자로 시작하는 기호는 비터미널 기호입니다. 고정폭 글꼴로 표시되는 기호는 터미널 기호입니다. 소문자로 시작하는 산세리프 글꼴의 기호는 터미널 기호로, 다음과 같이 Perl 5 정규표현식 문법([PERLRE])을 사용해 매칭됩니다:
=
|
/-?([1-9][0-9]*|0[Xx][0-9A-Fa-f]+|0[0-7]*)/
|
|
=
|
/-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)/
|
|
=
|
/[_-]?[A-Za-z][0-9A-Z_a-z-]*/
|
|
=
|
/"[^"]*"/
|
|
=
|
/[\t\n\r ]+/
|
|
=
|
/\/\/.*|\/\*(.|\n)*?\*\//
|
|
=
|
/[^\t\n\r 0-9A-Za-z]/
|
토크나이저는 스칼라 값 시퀀스에 대해 동작합니다.
토크나이징할 때는 가능한 가장 긴 일치 항목을 사용해야 합니다. 예를 들어, 입력 텍스트가 “a1”이면 하나의 long
"이 아닙니다.
“.”는 터미널 심볼
IDL 문법은 고정폭 터미널 심볼과 A
"인 것과 "a
"인 것은 구분됩니다. 또한
확장 속성
[legacyfactoryfunction
]은
[LegacyFactoryFunction
]
확장 속성으로 인식되지 않습니다.
암시적으로, 파싱되는 입력 텍스트의 모든 터미널 사이에는 임의 개수의
아래의 LL(1) 문법은
Definitions ::ExtendedAttributeList Definition Definitions εDefinition ::CallbackOrInterfaceOrMixin Namespace Partial Dictionary Enum Typedef IncludesStatement ArgumentNameKeyword ::attribute callback const constructor deleter dictionary enum getter includes inherit interface iterable maplike mixin namespace partial readonly required setlike setter static stringifier typedef unrestricted CallbackOrInterfaceOrMixin ::callback CallbackRestOrInterface interface InterfaceOrMixin InterfaceOrMixin ::InterfaceRest MixinRest InterfaceRest ::identifier Inheritance { InterfaceMembers } ; Partial ::partial PartialDefinition PartialDefinition ::interface PartialInterfaceOrPartialMixin PartialDictionary Namespace PartialInterfaceOrPartialMixin ::PartialInterfaceRest MixinRest PartialInterfaceRest ::identifier { PartialInterfaceMembers } ; InterfaceMembers ::ExtendedAttributeList InterfaceMember InterfaceMembers εInterfaceMember ::PartialInterfaceMember Constructor PartialInterfaceMembers ::ExtendedAttributeList PartialInterfaceMember PartialInterfaceMembers εPartialInterfaceMember ::Const Operation Stringifier StaticMember Iterable AsyncIterable ReadOnlyMember ReadWriteAttribute ReadWriteMaplike ReadWriteSetlike InheritAttribute Inheritance ::: identifier εMixinRest ::mixin identifier { MixinMembers } ; MixinMembers ::ExtendedAttributeList MixinMember MixinMembers εMixinMember ::Const RegularOperation Stringifier OptionalReadOnly AttributeRest IncludesStatement ::identifier includes identifier ; CallbackRestOrInterface ::CallbackRest interface identifier { CallbackInterfaceMembers } ; CallbackInterfaceMembers ::ExtendedAttributeList CallbackInterfaceMember CallbackInterfaceMembers εCallbackInterfaceMember ::Const RegularOperation Const ::const ConstType identifier = ConstValue ; ConstValue ::BooleanLiteral FloatLiteral integer BooleanLiteral ::true false FloatLiteral ::decimal -Infinity Infinity NaN ConstType ::PrimitiveType identifier ReadOnlyMember ::readonly ReadOnlyMemberRest ReadOnlyMemberRest ::AttributeRest MaplikeRest SetlikeRest ReadWriteAttribute ::AttributeRest InheritAttribute ::inherit AttributeRest AttributeRest ::attribute TypeWithExtendedAttributes AttributeName ; AttributeName ::AttributeNameKeyword identifier AttributeNameKeyword ::required OptionalReadOnly ::readonly εDefaultValue ::ConstValue string [ ] { } null undefined Operation ::RegularOperation SpecialOperation RegularOperation ::Type OperationRest SpecialOperation ::Special RegularOperation Special ::getter setter deleter OperationRest ::OptionalOperationName ( ArgumentList ) ; OptionalOperationName ::OperationName εOperationName ::OperationNameKeyword identifier OperationNameKeyword ::includes ArgumentList ::Argument Arguments εArguments ::, Argument Arguments εArgument ::ExtendedAttributeList ArgumentRest ArgumentRest ::optional TypeWithExtendedAttributes ArgumentName Default Type Ellipsis ArgumentName ArgumentName ::ArgumentNameKeyword identifier Ellipsis ::... εConstructor ::constructor ( ArgumentList ) ; Stringifier ::stringifier StringifierRest StringifierRest ::OptionalReadOnly AttributeRest ; StaticMember ::static StaticMemberRest StaticMemberRest ::OptionalReadOnly AttributeRest RegularOperation Iterable ::iterable < TypeWithExtendedAttributes OptionalType > ; OptionalType ::, TypeWithExtendedAttributes εAsyncIterable ::async_iterable < TypeWithExtendedAttributes OptionalType > OptionalArgumentList ; OptionalArgumentList ::( ArgumentList ) εReadWriteMaplike ::MaplikeRest MaplikeRest ::maplike < TypeWithExtendedAttributes , TypeWithExtendedAttributes > ; ReadWriteSetlike ::SetlikeRest SetlikeRest ::setlike < TypeWithExtendedAttributes > ; Namespace ::namespace identifier { NamespaceMembers } ; NamespaceMembers ::ExtendedAttributeList NamespaceMember NamespaceMembers εNamespaceMember ::RegularOperation readonly AttributeRest Const Dictionary ::dictionary identifier Inheritance { DictionaryMembers } ; DictionaryMembers ::DictionaryMember DictionaryMembers εDictionaryMember ::ExtendedAttributeList DictionaryMemberRest DictionaryMemberRest ::required TypeWithExtendedAttributes identifier ; Type identifier Default ; PartialDictionary ::dictionary identifier { DictionaryMembers } ; Default ::= DefaultValue εEnum ::enum identifier { EnumValueList } ; EnumValueList ::string EnumValueListComma EnumValueListComma ::, EnumValueListString εEnumValueListString ::string EnumValueListComma εCallbackRest ::identifier = Type ( ArgumentList ) ; Typedef ::typedef TypeWithExtendedAttributes identifier ; Type ::SingleType UnionType Null TypeWithExtendedAttributes ::ExtendedAttributeList Type SingleType ::DistinguishableType any PromiseType UnionType ::( UnionMemberType or UnionMemberType UnionMemberTypes ) UnionMemberType ::ExtendedAttributeList DistinguishableType UnionType Null UnionMemberTypes ::or UnionMemberType UnionMemberTypes εDistinguishableType ::PrimitiveType Null StringType Null identifier Null sequence < TypeWithExtendedAttributes > Null async_sequence < TypeWithExtendedAttributes > Null object Null symbol Null BufferRelatedType Null FrozenArray < TypeWithExtendedAttributes > Null ObservableArray < TypeWithExtendedAttributes > Null RecordType Null undefined Null PrimitiveType ::UnsignedIntegerType UnrestrictedFloatType boolean byte octet bigint UnrestrictedFloatType ::unrestricted FloatType FloatType FloatType ::float double UnsignedIntegerType ::unsigned IntegerType IntegerType IntegerType ::short long OptionalLong OptionalLong ::long εStringType ::ByteString DOMString USVString PromiseType ::Promise < Type > RecordType ::record < StringType , TypeWithExtendedAttributes > Null ::? εBufferRelatedType ::ArrayBuffer SharedArrayBuffer DataView Int8Array Int16Array Int32Array Uint8Array Uint16Array Uint32Array Uint8ClampedArray BigInt64Array BigUint64Array Float16Array Float32Array Float64Array ExtendedAttributeList ::[ ExtendedAttribute ExtendedAttributes ] εExtendedAttributes ::, ExtendedAttribute ExtendedAttributes εExtendedAttribute ::( ExtendedAttributeInner ) ExtendedAttributeRest [ ExtendedAttributeInner ] ExtendedAttributeRest { ExtendedAttributeInner } ExtendedAttributeRest Other ExtendedAttributeRest ExtendedAttributeRest ::ExtendedAttribute εExtendedAttributeInner ::( ExtendedAttributeInner ) ExtendedAttributeInner [ ExtendedAttributeInner ] ExtendedAttributeInner { ExtendedAttributeInner } ExtendedAttributeInner OtherOrComma ExtendedAttributeInner εOther ::integer decimal identifier string other - -Infinity . ... : ; < = > ? * ByteString DOMString FrozenArray Infinity NaN ObservableArray Promise USVString any bigint boolean byte double false float long null object octet or optional record sequence short symbol true unsigned undefined ArgumentNameKeyword BufferRelatedType OtherOrComma ::Other , IdentifierList ::identifier Identifiers Identifiers ::, identifier Identifiers εIntegerList ::integer Integers Integers ::, integer Integers εExtendedAttributeNoArgs ::identifier ExtendedAttributeArgList ::identifier ( ArgumentList ) ExtendedAttributeIdent ::identifier = identifier ExtendedAttributeString ::identifier = string ExtendedAttributeInteger ::identifier = integer ExtendedAttributeDecimal ::identifier = decimal ExtendedAttributeWildcard ::identifier = * ExtendedAttributeIdentList ::identifier = ( IdentifierList ) ExtendedAttributeIntegerList ::identifier = ( IntegerList ) ExtendedAttributeNamedArgList ::identifier = identifier ( ArgumentList )
참고:
문서 관례
이 문서에서는 다음과 같은 서체 관례를 사용합니다:
-
용어의 정의 인스턴스: 예시 용어
-
이 문서 또는 다른 곳에서 정의된 용어에 대한 링크: 예시 용어
-
문법 터미널:
sometoken -
문법 비터미널:
ExampleGrammarNonTerminal -
문법 심볼:
identifier -
IDL 타입:
unsigned long
-
JavaScript 클래스:
Map
-
JavaScript 언어 타입: Object
-
코드 스니펫:
a = b + obj.f()
-
스칼라 값: U+0030 (0)
-
확장 속성: [
ExampleExtendedAttribute
] -
서술 및 알고리즘 내 변수명: exampleVariableName.
-
IDL 비공식 문법 예시:
[
extended_attributes ]interface identifier { /* interface_members... */ };(주변 설명에서 논의되는 문법의 특정 부분은 강조됩니다.)
-
IDL 문법 스니펫:
ExampleGrammarNonTerminal ::OtherNonTerminal sometoken other AnotherNonTerminal ε //nothing -
비규범적 주석:
참고: 이것은 주석입니다.
-
비규범적 예시:
-
규범적 경고:
이것은 경고입니다.
-
코드 블록:
// 이것은 IDL 코드 블록입니다. [
Exposed =Window ]interface Example {attribute long something ; };// 이것은 JavaScript 코드 블록입니다. window. onload= function () { window. alert( "loaded" ); };
이 문서의 알고리즘에서는 다음과 같은 관례를 사용합니다:
-
알고리즘은 JavaScript 명세의 관례를 사용하며, ! 및 ? 표기를 사용하여 Completion Record를 언래핑합니다.
-
알고리즘은 값 반환/예외 던지기와 Completion Record 반환을 상호 교환적으로 다루기도 합니다. 즉, 반환/던지기 용어를 사용하는 알고리즘은 Completion Record를 반환하는 것으로 간주할 수 있고, Completion Record 를 반환하는 알고리즘은 값을 반환하거나 예외를 던지는 것으로 간주할 수 있습니다. 이와 유사하게, 예외를 처리하기 위해 예외가 던져졌을 때의 동작을 정의하고, Completion Record의 [[Type]] 필드가 "throw"인지 확인하는 것은 동등합니다.
-
Completion Record는 JavaScript 값이 아닌 Web IDL 값과 같은 값을 포함할 수 있도록 확장됩니다.
적합성
이 명세서의 모든 내용은 도표, 예시, 참고 및 정보용으로 표시된 섹션을 제외하면 규범적입니다.
이 명세서는 Infra 표준에 의존합니다. [INFRA]
이 명세서에서는 다음과 같은 적합성 클래스가 정의됩니다:
- 적합한 IDL 조각 집합
-
IDL 조각들의 집합은, 함께 고려했을 때, 이 명세서에서 IDL 조각에 적용되는 must-, required-, shall- 수준의 기준을 모두 충족시키면 적합한 IDL 조각 집합으로 간주됩니다.
- 적합한 구현
-
사용자 에이전트가 지원하는 모든 언어 바인딩에 대해 구현에 적용되는 must-, required-, shall- 수준의 기준을 이 명세서에서 모두 충족시키면, 해당 사용자 에이전트는 적합한 구현으로, 해당 적합한 IDL 조각 집합에 대해 간주됩니다.
- 적합한 JavaScript 구현
-
사용자 에이전트가 JavaScript 언어 바인딩에 대해 구현에 적용되는 must-, required-, shall- 수준의 기준을 이 명세서에서 모두 충족시키면, 해당 사용자 에이전트는 적합한 JavaScript 구현으로, 해당 적합한 IDL 조각 집합에 대해 간주됩니다.
지적 재산권
Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). 이 저작물은 크리에이티브 커먼즈 저작자 표시 4.0 국제 라이선스에 따라 라이선스가 부여됩니다. 일부 내용이 소스 코드에 통합된 범위 내에서는, 해당 소스 코드의 부분은 BSD 3-Clause 라이선스에 따라 별도로 라이선스됩니다.
이것이 현행 표준입니다. 특허 검토용 버전에 관심이 있는 분은 현행 표준 검토 초안을 참고하시기 바랍니다.