페이지 표시 설정

24 키 컬렉션

24.1 Map 객체

Map은 키와 값 모두 임의의 ECMAScript language value일 수 있는 키/값 쌍의 컬렉션입니다. 서로 다른 키 값은 Map의 컬렉션 안에서 하나의 키/값 쌍에만 존재할 수 있습니다. 서로 다른 키 값은 SameValueZero 비교 알고리즘의 의미론을 사용하여 구별합니다.

Map은 평균적으로 컬렉션의 요소 수에 대해 선형보다 빠른 접근 시간을 제공하는 해시 테이블이나 그 밖의 메커니즘을 사용하여 구현해야 합니다. 이 명세에서 사용하는 데이터 구조는 Map에 요구되는 관찰 가능한 의미론을 설명하기 위한 것일 뿐입니다. 실제 구현 모델로 사용하려는 것은 아닙니다.

24.1.1 Map 생성자

Map 생성자는:

  • %Map%입니다.
  • 전역 객체의 "Map" 프로퍼티의 초기 값입니다.
  • 생성자로 호출되면 새로운 Map을 생성하고 초기화합니다.
  • 함수로 호출하도록 의도되지 않았으며 그러한 방식으로 호출되면 예외를 던집니다.
  • 클래스 정의의 extends 절에서 값으로 사용할 수 있습니다. 지정된 Map 동작을 상속하려는 하위 클래스 생성자는 Map.prototype의 내장 메서드를 지원하는 데 필요한 내부 상태를 갖도록 하위 클래스 인스턴스를 생성하고 초기화하기 위해 Map 생성자에 대한 super 호출을 포함해야 합니다.

24.1.1.1 Map ( [ iterable ] )

이 함수는 호출되면 다음 단계를 수행합니다:

  1. NewTarget이 undefined이면 TypeError 예외를 던집니다.
  2. map을 ? OrdinaryCreateFromConstructor(NewTarget, "%Map.prototype%", « [[MapData]] »)로 둡니다.
  3. map.[[MapData]]를 새로운 빈 List로 설정합니다.
  4. iterable이 undefined 또는 null이면 map을 반환합니다.
  5. adder를 ? Get(map, "set")으로 둡니다.
  6. IsCallable(adder)가 false이면 TypeError 예외를 던집니다.
  7. ? AddEntriesFromIterable(map, iterable, adder)를 반환합니다.
참고

매개변수 iterable이 존재하는 경우, 첫 번째 요소는 Map 키로 사용할 값이고 두 번째 요소는 해당 키와 연결할 값인 두 요소의 배열과 유사한 객체를 생성하는 반복자 객체를 반환하는 %Symbol.iterator% 메서드를 구현한 객체일 것으로 예상됩니다.

24.1.1.2 AddEntriesFromIterable ( target, iterable, adder )

추상 연산 AddEntriesFromIterable. 인수 target (Object), iterable (an ECMAScript language value, but not undefined or null) 및 adder (함수 객체). 반환값: (정상 완료 (값: Object) 또는 throw 완료). adder는 target을 수신자로 하여 호출됩니다. 호출되면 다음 단계를 수행한다.

  1. iteratorRecord를 ? GetIterator(iterable, sync)로 둡니다.
  2. 다음을 반복합니다.
    1. next를 ? IteratorStepValue(iteratorRecord)로 둡니다.
    2. next가 done이면 target을 반환합니다.
    3. next가 Object가 아니면, 다음을 수행합니다.
      1. error를 ThrowCompletion(새로 생성된 TypeError 객체)로 둡니다.
      2. ? IteratorClose(iteratorRecord, error)를 반환합니다.
    4. key를 Completion(Get(next, "0"))으로 둡니다.
    5. IfAbruptCloseIterator(key, iteratorRecord).
    6. value를 Completion(Get(next, "1"))으로 둡니다.
    7. IfAbruptCloseIterator(value, iteratorRecord).
    8. status를 Completion(Call(adder, target, « key, value »))로 둡니다.
    9. IfAbruptCloseIterator(status, iteratorRecord).
참고

매개변수 iterable은 첫 번째 요소는 Map 키로 사용할 값이고 두 번째 요소는 해당 키와 연결할 값인 두 요소의 배열과 유사한 객체를 생성하는 반복자 객체를 반환하는 %Symbol.iterator% 메서드를 구현한 객체일 것으로 예상됩니다.

24.1.2 Map 생성자의 프로퍼티

Map 생성자는:

  • 값이 %Function.prototype%인 [[Prototype]] 내부 슬롯을 갖습니다.
  • 다음 프로퍼티를 갖습니다:

24.1.2.1 Map.groupBy ( items, callback )

참고

callback은 두 인수를 받는 함수여야 합니다. groupBy는 items의 각 요소에 대해 오름차순으로 callback을 한 번씩 호출하고 새로운 Map을 구성합니다. callback이 반환하는 각 값은 Map의 키로 사용됩니다. 그러한 각 키에 대해 결과 Map에는 해당 키를 키로 하고 callback이 해당 키를 반환한 모든 요소를 포함하는 배열을 값으로 하는 항목이 있습니다.

callback은 요소의 값과 요소의 인덱스라는 두 인수로 호출됩니다.

groupBy의 반환 값은 Map입니다.

이 함수는 호출되면 다음 단계를 수행합니다:

  1. groups를 ? GroupBy(items, callback, collection)로 둡니다.
  2. map을 ! Construct(%Map%)으로 둡니다.
  3. groups의 각 Record { [[Key]], [[Elements]] } group에 대해 다음을 수행합니다.
    1. elements를 CreateArrayFromList(group.[[Elements]])로 둡니다.
    2. entry를 Record { [[Key]]: group.[[Key]], [[Value]]: elements }로 둡니다.
    3. entry를 map.[[MapData]]에 추가합니다.
  4. map을 반환합니다.

24.1.2.2 Map.prototype

Map.prototype의 초기 값은 Map 프로토타입 객체입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } 속성을 갖습니다.

24.1.2.3 get Map [ %Symbol.species% ]

Map[%Symbol.species%]는 set 접근자 함수가 undefined인 접근자 프로퍼티입니다. get 접근자 함수는 호출되면 다음 단계를 수행합니다:

  1. this 값을 반환합니다.

이 함수의 "name" 프로퍼티 값은 "get [Symbol.species]"입니다.

참고

파생 컬렉션 객체를 생성하는 메서드는 파생 객체를 생성하는 데 사용할 생성자를 결정하기 위해 %Symbol.species%를 호출해야 합니다. 하위 클래스 생성자는 기본 생성자 할당을 변경하기 위해 %Symbol.species%를 재정의할 수 있습니다.

24.1.3 Map 프로토타입 객체의 프로퍼티

Map 프로토타입 객체는:

  • %Map.prototype%입니다.
  • 값이 %Object.prototype%인 [[Prototype]] 내부 슬롯을 갖습니다.
  • 일반 객체입니다.
  • [[MapData]] 내부 슬롯을 갖지 않습니다.

24.1.3.1 Map.prototype.clear ( )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? RequireInternalSlot(map, [[MapData]])를 수행합니다.
  3. map.[[MapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]를 empty로 설정합니다.
    2. entry.[[Value]]를 empty로 설정합니다.
  4. undefined를 반환합니다.
참고

해당 List를 순회하는 도중 일시 중단된 기존 Map Iterator 객체가 있을 수 있으므로 기존 [[MapData]] List를 유지합니다.

24.1.3.2 Map.prototype.constructor

Map.prototype.constructor의 초기 값은 %Map%입니다.

24.1.3.3 Map.prototype.delete ( key )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? RequireInternalSlot(map, [[MapData]])를 수행합니다.
  3. key를 CanonicalizeKeyedCollectionKey(key)로 설정합니다.
  4. map.[[MapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면, 다음을 수행합니다.
      1. entry.[[Key]]를 empty로 설정합니다.
      2. entry.[[Value]]를 empty로 설정합니다.
      3. true를 반환합니다.
  5. false를 반환합니다.
참고

값 empty는 항목이 삭제되었음을 나타내기 위한 명세상의 장치로 사용됩니다. 실제 구현체는 내부 데이터 구조에서 항목을 물리적으로 제거하는 등의 다른 동작을 수행할 수 있습니다.

24.1.3.4 Map.prototype.entries ( )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? CreateMapIterator(map, key+value)를 반환합니다.

24.1.3.5 Map.prototype.forEach ( callback [ , thisArg ] )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? RequireInternalSlot(map, [[MapData]])를 수행합니다.
  3. IsCallable(callback)이 false이면 TypeError 예외를 던집니다.
  4. entries를 map.[[MapData]]로 둡니다.
  5. entriesCount를 entries의 요소 수로 둡니다.
  6. index를 0으로 둡니다.
  7. index < entriesCount인 동안 다음을 반복합니다.
    1. entry를 entries[index]로 둡니다.
    2. index를 index + 1로 설정합니다.
    3. entry.[[Key]]가 empty가 아니면, 다음을 수행합니다.
      1. ? Call(callback, thisArg, « entry.[[Value]], entry.[[Key]], map »)를 수행합니다.
      2. 참고: callback 실행 중 entries의 요소 수가 증가했을 수 있습니다.
      3. entriesCount를 entries의 요소 수로 설정합니다.
  8. undefined를 반환합니다.
참고

callback은 세 인수를 받는 함수여야 합니다. forEach는 Map에 존재하는 각 키/값 쌍에 대해 키 삽입 순서로 callback을 한 번씩 호출합니다. callback은 Map에 실제로 존재하는 키에 대해서만 호출되며 Map에서 삭제된 키에 대해서는 호출되지 않습니다.

thisArg 매개변수가 제공되면 callback을 호출할 때마다 this 값으로 사용됩니다. 제공되지 않으면 대신 undefined를 사용합니다.

callback은 항목의 값, 항목의 키, 순회 중인 Map이라는 세 인수로 호출됩니다.

forEach는 호출된 객체를 직접 변경하지 않지만 callback 호출에 의해 객체가 변경될 수 있습니다. Map의 [[MapData]]에 있는 각 항목은 한 번만 방문됩니다. forEach 호출이 시작된 후 추가된 새로운 키는 방문됩니다. 키가 방문된 후 삭제되고 forEach 호출이 완료되기 전에 다시 추가되면 해당 키를 다시 방문합니다. forEach 호출이 시작된 후 방문되기 전에 삭제된 키는 forEach 호출이 완료되기 전에 다시 추가되지 않는 한 방문되지 않습니다.

24.1.3.6 Map.prototype.get ( key )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? RequireInternalSlot(map, [[MapData]])를 수행합니다.
  3. key를 CanonicalizeKeyedCollectionKey(key)로 설정합니다.
  4. map.[[MapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면 entry.[[Value]]를 반환합니다.
  5. undefined를 반환합니다.

24.1.3.7 Map.prototype.getOrInsert ( key, value )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? RequireInternalSlot(map, [[MapData]])를 수행합니다.
  3. key를 CanonicalizeKeyedCollectionKey(key)로 설정합니다.
  4. map.[[MapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면 entry.[[Value]]를 반환합니다.
  5. entry를 Record { [[Key]]: key, [[Value]]: value }로 둡니다.
  6. entry를 map.[[MapData]]에 추가합니다.
  7. value를 반환합니다.

24.1.3.8 Map.prototype.getOrInsertComputed ( key, callback )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? RequireInternalSlot(map, [[MapData]])를 수행합니다.
  3. IsCallable(callback)이 false이면 TypeError 예외를 던집니다.
  4. key를 CanonicalizeKeyedCollectionKey(key)로 설정합니다.
  5. map.[[MapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면 entry.[[Value]]를 반환합니다.
  6. value를 ? Call(callback, undefined, « key »)로 둡니다.
  7. 참고: callback 실행 중 Map이 변경되었을 수 있습니다.
  8. map.[[MapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면, 다음을 수행합니다.
      1. entry.[[Value]]를 value로 설정합니다.
      2. value를 반환합니다.
  9. entry를 Record { [[Key]]: key, [[Value]]: value }로 둡니다.
  10. entry를 map.[[MapData]]에 추가합니다.
  11. value를 반환합니다.

24.1.3.9 Map.prototype.has ( key )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? RequireInternalSlot(map, [[MapData]])를 수행합니다.
  3. key를 CanonicalizeKeyedCollectionKey(key)로 설정합니다.
  4. map.[[MapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면 true를 반환합니다.
  5. false를 반환합니다.

24.1.3.10 Map.prototype.keys ( )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? CreateMapIterator(map, key)를 반환합니다.

24.1.3.11 Map.prototype.set ( key, value )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? RequireInternalSlot(map, [[MapData]])를 수행합니다.
  3. key를 CanonicalizeKeyedCollectionKey(key)로 설정합니다.
  4. map.[[MapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면, 다음을 수행합니다.
      1. entry.[[Value]]를 value로 설정합니다.
      2. map을 반환합니다.
  5. entry를 Record { [[Key]]: key, [[Value]]: value }로 둡니다.
  6. entry를 map.[[MapData]]에 추가합니다.
  7. map을 반환합니다.

24.1.3.12 get Map.prototype.size

Map.prototype.size는 set 접근자 함수가 undefined인 접근자 프로퍼티입니다. get 접근자 함수는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? RequireInternalSlot(map, [[MapData]])를 수행합니다.
  3. count를 0으로 둡니다.
  4. map.[[MapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니면 count를 count + 1로 설정합니다.
  5. 𝔽(count)를 반환합니다.

24.1.3.13 Map.prototype.values ( )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. map을 this 값으로 둡니다.
  2. ? CreateMapIterator(map, value)를 반환합니다.

24.1.3.14 Map.prototype [ %Symbol.iterator% ] ( )

%Symbol.iterator% 프로퍼티의 초기 값은 24.1.3.4에 정의된 %Map.prototype.entries%입니다.

24.1.3.15 Map.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 프로퍼티의 초기 값은 String 값 "Map"입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } 속성을 갖습니다.

24.1.4 Map 인스턴스의 프로퍼티

Map 인스턴스는 Map 프로토타입 객체에서 프로퍼티를 상속하는 일반 객체입니다. Map 인스턴스는 [[MapData]] 내부 슬롯도 갖습니다.

24.1.5 Map Iterator 객체

Map Iterator는 특정 Map 인스턴스 객체에 대한 특정 순회를 나타내는 객체입니다. Map Iterator 객체에는 이름 있는 생성자가 없습니다. 대신 Map Iterator 객체는 Map 인스턴스 객체의 특정 메서드를 호출하여 생성됩니다.

24.1.5.1 CreateMapIterator ( map, kind )

추상 연산 CreateMapIterator. 인수 map (ECMAScript 언어 값) 및 kind ((key+value, key 또는 value)). 반환값: (정상 완료 (값: Generator) 또는 throw 완료). 그러한 반복자를 반환하는 Map 메서드의 반복자 객체를 생성하는 데 사용됩니다. 호출되면 다음 단계를 수행한다.

  1. ? RequireInternalSlot(map, [[MapData]])를 수행합니다.
  2. closure를 매개변수가 없고 map과 kind를 캡처하며 호출될 때 다음 단계를 수행하는 새로운 Abstract Closure로 둡니다:
    1. entries를 map.[[MapData]]로 둡니다.
    2. index를 0으로 둡니다.
    3. entriesCount를 entries의 요소 수로 둡니다.
    4. index < entriesCount인 동안 다음을 반복합니다.
      1. entry를 entries[index]로 둡니다.
      2. index를 index + 1로 설정합니다.
      3. entry.[[Key]]가 empty가 아니면, 다음을 수행합니다.
        1. kind가 key이면, 다음을 수행합니다.
          1. result를 entry.[[Key]]로 둡니다.
        2. 그렇지 않고 kind가 value이면, 다음을 수행합니다.
          1. result를 entry.[[Value]]로 둡니다.
        3. 그렇지 않으면,
          1. 단언: kind는 key+value입니다.
          2. result를 CreateArrayFromList(« entry.[[Key]], entry.[[Value]] »)로 둡니다.
        4. ? GeneratorYield(CreateIteratorResultObject(result, false))를 수행합니다.
        5. 참고: GeneratorYield에 의해 이 추상 연산의 실행이 일시 중단된 동안 entries의 요소 수가 증가했을 수 있습니다.
        6. entriesCount를 entries의 요소 수로 설정합니다.
    5. NormalCompletion(unused)을 반환합니다.
  3. CreateIteratorFromClosure(closure, "%MapIteratorPrototype%", %MapIteratorPrototype%)을 반환합니다.

24.1.5.2 %MapIteratorPrototype% 객체

%MapIteratorPrototype% 객체는:

24.1.5.2.1 %MapIteratorPrototype%.next ( )

  1. ? GeneratorResume(this 값, empty, "%MapIteratorPrototype%")를 반환합니다.

24.1.5.2.2 %MapIteratorPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 프로퍼티의 초기 값은 String 값 "Map Iterator"입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } 속성을 갖습니다.

24.2 Set 객체

Set 객체는 ECMAScript language value의 컬렉션입니다. Set은 서로 다른 각 값을 최대 한 번만 포함할 수 있습니다. 서로 다른 값은 SameValueZero 비교 알고리즘의 의미론을 사용하여 구별합니다.

Set 객체는 평균적으로 컬렉션의 요소 수에 대해 선형보다 빠른 접근 시간을 제공하는 해시 테이블이나 그 밖의 메커니즘을 사용하여 구현해야 합니다. 이 명세에서 사용하는 데이터 구조는 Set 객체에 요구되는 관찰 가능한 의미론을 설명하기 위한 것일 뿐입니다. 실제 구현 모델로 사용하려는 것은 아닙니다.

24.2.1 Set 객체를 위한 추상 연산

24.2.1.1 Set Records

Set Record는 Set 또는 유사한 객체의 인터페이스를 캡슐화하는 데 사용되는 Record입니다.

Set Records에는 표 72에 나열된 필드가 있습니다.

표 72: Set Record 필드
필드 이름 값 의미
[[SetObject]] an Object Set 또는 유사한 객체입니다.
[[Size]] a non-negative integer or +∞ 보고된 객체의 크기입니다.
[[Has]] a function object 객체의 has 메서드입니다.
[[Keys]] a function object 객체의 keys 메서드입니다.

24.2.1.2 GetSetRecord ( obj )

추상 연산 GetSetRecord. 인수 obj (ECMAScript 언어 값). 반환값: (정상 완료 (값: Set 레코드) 또는 throw 완료). 호출되면 다음 단계를 수행한다.

  1. obj가 Object가 아니면 TypeError 예외를 던집니다.
  2. rawSize를 ? Get(obj, "size")로 둡니다.
  3. numberSize를 ? ToNumber(rawSize)로 둡니다.
  4. 참고: rawSize가 undefined이면 numberSize는 NaN이 됩니다.
  5. numberSize가 NaN이면 TypeError 예외를 던집니다.
  6. intSize를 ! ToIntegerOrInfinity(numberSize)로 둡니다.
  7. intSize < 0이면 RangeError 예외를 던집니다.
  8. has를 ? Get(obj, "has")로 둡니다.
  9. IsCallable(has)가 false이면 TypeError 예외를 던집니다.
  10. keys를 ? Get(obj, "keys")로 둡니다.
  11. IsCallable(keys)가 false이면 TypeError 예외를 던집니다.
  12. 새로운 Set Record { [[SetObject]]: obj, [[Size]]: intSize, [[Has]]: has, [[Keys]]: keys }를 반환합니다.

24.2.1.3 SetDataHas ( setData, value )

추상 연산 SetDataHas. 인수 setData (리스트 (요소: (ECMAScript 언어 값 또는 empty))) 및 value (ECMAScript 언어 값). 반환값: Boolean. 호출되면 다음 단계를 수행한다.

  1. SetDataIndex(setData, value)가 not-found이면 false를 반환합니다.
  2. true를 반환합니다.

24.2.1.4 SetDataIndex ( setData, value )

추상 연산 SetDataIndex. 인수 setData (리스트 (요소: (ECMAScript 언어 값 또는 empty))) 및 value (ECMAScript 언어 값). 반환값: (음이 아닌 정수 또는 not-found). 호출되면 다음 단계를 수행한다.

  1. value를 CanonicalizeKeyedCollectionKey(value)로 설정합니다.
  2. size를 setData의 요소 수로 둡니다.
  3. index를 0으로 둡니다.
  4. index < size인 동안 다음을 반복합니다.
    1. element를 setData[index]로 둡니다.
    2. element가 empty가 아니고 element가 value이면, 다음을 수행합니다.
      1. index를 반환합니다.
    3. index를 index + 1로 설정합니다.
  5. not-found를 반환합니다.

24.2.1.5 SetDataSize ( setData )

추상 연산 SetDataSize. 인수 setData (리스트 (요소: (ECMAScript 언어 값 또는 empty))). 반환값: 음이 아닌 정수. 호출되면 다음 단계를 수행한다.

  1. count를 0으로 둡니다.
  2. setData의 각 요소 element에 대해 다음을 수행합니다.
    1. element가 empty가 아니면 count를 count + 1로 설정합니다.
  3. count를 반환합니다.

24.2.2 Set 생성자

Set 생성자는:

  • %Set%입니다.
  • 전역 객체의 "Set" 프로퍼티의 초기 값입니다.
  • 생성자로 호출되면 새로운 Set 객체를 생성하고 초기화합니다.
  • 함수로 호출하도록 의도되지 않았으며 그러한 방식으로 호출되면 예외를 던집니다.
  • 클래스 정의의 extends 절에서 값으로 사용할 수 있습니다. 지정된 Set 동작을 상속하려는 하위 클래스 생성자는 Set.prototype의 내장 메서드를 지원하는 데 필요한 내부 상태를 갖도록 하위 클래스 인스턴스를 생성하고 초기화하기 위해 Set 생성자에 대한 super 호출을 포함해야 합니다.

24.2.2.1 Set ( [ iterable ] )

이 함수는 호출되면 다음 단계를 수행합니다:

  1. NewTarget이 undefined이면 TypeError 예외를 던집니다.
  2. set을 ? OrdinaryCreateFromConstructor(NewTarget, "%Set.prototype%", « [[SetData]] »)로 둡니다.
  3. set.[[SetData]]를 새로운 빈 List로 설정합니다.
  4. iterable이 undefined 또는 null이면 set을 반환합니다.
  5. adder를 ? Get(set, "add")로 둡니다.
  6. IsCallable(adder)가 false이면 TypeError 예외를 던집니다.
  7. iteratorRecord를 ? GetIterator(iterable, sync)로 둡니다.
  8. 다음을 반복합니다.
    1. next를 ? IteratorStepValue(iteratorRecord)로 둡니다.
    2. next가 done이면 set을 반환합니다.
    3. status를 Completion(Call(adder, set, « next »))로 둡니다.
    4. IfAbruptCloseIterator(status, iteratorRecord).

24.2.3 Set 생성자의 프로퍼티

Set 생성자는:

  • 값이 %Function.prototype%인 [[Prototype]] 내부 슬롯을 갖습니다.
  • 다음 프로퍼티를 갖습니다:

24.2.3.1 Set.prototype

Set.prototype의 초기 값은 Set 프로토타입 객체입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } 속성을 갖습니다.

24.2.3.2 get Set [ %Symbol.species% ]

Set[%Symbol.species%]는 set 접근자 함수가 undefined인 접근자 프로퍼티입니다. get 접근자 함수는 호출되면 다음 단계를 수행합니다:

  1. this 값을 반환합니다.

이 함수의 "name" 프로퍼티 값은 "get [Symbol.species]"입니다.

참고

파생 컬렉션 객체를 생성하는 메서드는 파생 객체를 생성하는 데 사용할 생성자를 결정하기 위해 %Symbol.species%를 호출해야 합니다. 하위 클래스 생성자는 기본 생성자 할당을 변경하기 위해 %Symbol.species%를 재정의할 수 있습니다.

24.2.4 Set 프로토타입 객체의 프로퍼티

Set 프로토타입 객체는:

  • %Set.prototype%입니다.
  • 값이 %Object.prototype%인 [[Prototype]] 내부 슬롯을 갖습니다.
  • 일반 객체입니다.
  • [[SetData]] 내부 슬롯을 갖지 않습니다.

24.2.4.1 Set.prototype.add ( value )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. value를 CanonicalizeKeyedCollectionKey(value)로 설정합니다.
  4. set.[[SetData]]의 각 요소 entry에 대해 다음을 수행합니다.
    1. entry가 empty가 아니고 SameValue(entry, value)가 true이면, 다음을 수행합니다.
      1. set을 반환합니다.
  5. value를 set.[[SetData]]에 추가합니다.
  6. set을 반환합니다.

24.2.4.2 Set.prototype.clear ( )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. set.[[SetData]]의 각 요소 entry에 대해 다음을 수행합니다.
    1. 값이 entry인 set.[[SetData]]의 요소를 값이 empty인 요소로 대체합니다.
  4. undefined를 반환합니다.
참고

해당 List를 순회하는 도중 일시 중단된 기존 Set Iterator 객체가 있을 수 있으므로 기존 [[SetData]] List를 유지합니다.

24.2.4.3 Set.prototype.constructor

Set.prototype.constructor의 초기 값은 %Set%입니다.

24.2.4.4 Set.prototype.delete ( value )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. value를 CanonicalizeKeyedCollectionKey(value)로 설정합니다.
  4. set.[[SetData]]의 각 요소 entry에 대해 다음을 수행합니다.
    1. entry가 empty가 아니고 SameValue(entry, value)가 true이면, 다음을 수행합니다.
      1. 값이 entry인 set.[[SetData]]의 요소를 값이 empty인 요소로 대체합니다.
      2. true를 반환합니다.
  5. false를 반환합니다.
참고

값 empty는 항목이 삭제되었음을 나타내기 위한 명세상의 장치로 사용됩니다. 실제 구현체는 내부 데이터 구조에서 항목을 물리적으로 제거하는 등의 다른 동작을 수행할 수 있습니다.

24.2.4.5 Set.prototype.difference ( other )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. otherRecord를 ? GetSetRecord(other)로 둡니다.
  4. resultSetData를 set.[[SetData]]의 복사본으로 둡니다.
  5. SetDataSize(set.[[SetData]]) ≤ otherRecord.[[Size]]이면, 다음을 수행합니다.
    1. thisSize를 set.[[SetData]]의 요소 수로 둡니다.
    2. index를 0으로 둡니다.
    3. index < thisSize인 동안 다음을 반복합니다.
      1. entry를 resultSetData[index]로 둡니다.
      2. entry가 empty가 아니면, 다음을 수행합니다.
        1. inOther를 ToBoolean(? Call(otherRecord.[[Has]], otherRecord.[[SetObject]], « entry »))로 둡니다.
        2. inOther가 true이면, 다음을 수행합니다.
          1. resultSetData[index]를 empty로 설정합니다.
      3. index를 index + 1로 설정합니다.
  6. 그렇지 않으면,
    1. keysIterator를 ? GetIteratorFromMethod(otherRecord.[[SetObject]], otherRecord.[[Keys]])로 둡니다.
    2. next를 not-started로 둡니다.
    3. next가 done이 아닌 동안 다음을 반복합니다.
      1. next를 ? IteratorStepValue(keysIterator)로 설정합니다.
      2. next가 done이 아니면, 다음을 수행합니다.
        1. next를 CanonicalizeKeyedCollectionKey(next)로 설정합니다.
        2. valueIndex를 SetDataIndex(resultSetData, next)로 둡니다.
        3. valueIndex가 not-found가 아니면, 다음을 수행합니다.
          1. resultSetData[valueIndex]를 empty로 설정합니다.
  7. result를 OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »)로 둡니다.
  8. result.[[SetData]]를 resultSetData로 설정합니다.
  9. result를 반환합니다.

24.2.4.6 Set.prototype.entries ( )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? CreateSetIterator(set, key+value)를 반환합니다.
참고

순회 목적에서 Set은 각 항목의 키와 값이 동일한 Map과 유사하게 보입니다.

24.2.4.7 Set.prototype.forEach ( callback [ , thisArg ] )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. IsCallable(callback)이 false이면 TypeError 예외를 던집니다.
  4. entries를 set.[[SetData]]로 둡니다.
  5. entriesCount를 entries의 요소 수로 둡니다.
  6. index를 0으로 둡니다.
  7. index < entriesCount인 동안 다음을 반복합니다.
    1. entry를 entries[index]로 둡니다.
    2. index를 index + 1로 설정합니다.
    3. entry가 empty가 아니면, 다음을 수행합니다.
      1. ? Call(callback, thisArg, « entry, entry, set »)를 수행합니다.
      2. 참고: callback 실행 중 entries의 요소 수가 증가했을 수 있습니다.
      3. entriesCount를 entries의 요소 수로 설정합니다.
  8. undefined를 반환합니다.
참고

callback은 세 인수를 받는 함수여야 합니다. forEach는 Set 객체에 존재하는 각 값에 대해 값 삽입 순서로 callback을 한 번씩 호출합니다. callback은 Set에 실제로 존재하는 값에 대해서만 호출되며 Set에서 삭제된 키에 대해서는 호출되지 않습니다.

thisArg 매개변수가 제공되면 callback을 호출할 때마다 this 값으로 사용됩니다. 제공되지 않으면 대신 undefined를 사용합니다.

callback은 세 인수로 호출됩니다. 처음 두 인수는 Set에 포함된 값입니다. 두 인수 모두에 동일한 값이 전달됩니다. 순회 중인 Set 객체는 세 번째 인수로 전달됩니다.

callback은 Map 및 Array의 forEach 메서드가 사용하는 콜백 함수와 일관성을 유지하기 위해 세 인수로 호출됩니다. Set에서는 각 항목 값이 키이자 값으로 간주됩니다.

forEach는 호출된 객체를 직접 변경하지 않지만 callback 호출에 의해 객체가 변경될 수 있습니다.

각 값은 일반적으로 한 번만 방문됩니다. 그러나 값이 방문된 후 삭제되고 forEach 호출이 완료되기 전에 다시 추가되면 다시 방문됩니다. forEach 호출이 시작된 후 방문되기 전에 삭제된 값은 forEach 호출이 완료되기 전에 다시 추가되지 않는 한 방문되지 않습니다. forEach 호출이 시작된 후 추가된 새로운 값은 방문됩니다.

24.2.4.8 Set.prototype.has ( value )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. value를 CanonicalizeKeyedCollectionKey(value)로 설정합니다.
  4. set.[[SetData]]의 각 요소 entry에 대해 다음을 수행합니다.
    1. entry가 empty가 아니고 SameValue(entry, value)가 true이면 true를 반환합니다.
  5. false를 반환합니다.

24.2.4.9 Set.prototype.intersection ( other )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. otherRecord를 ? GetSetRecord(other)로 둡니다.
  4. resultSetData를 새로운 빈 List로 둡니다.
  5. SetDataSize(set.[[SetData]]) ≤ otherRecord.[[Size]]이면, 다음을 수행합니다.
    1. thisSize를 set.[[SetData]]의 요소 수로 둡니다.
    2. index를 0으로 둡니다.
    3. index < thisSize인 동안 다음을 반복합니다.
      1. entry를 set.[[SetData]][index]로 둡니다.
      2. index를 index + 1로 설정합니다.
      3. entry가 empty가 아니면, 다음을 수행합니다.
        1. inOther를 ToBoolean(? Call(otherRecord.[[Has]], otherRecord.[[SetObject]], « entry »))로 둡니다.
        2. inOther가 true이면, 다음을 수행합니다.
          1. 참고: 이전의 otherRecord.[[Has]] 호출이 set.[[SetData]]의 요소를 제거한 뒤 다시 추가할 수 있으므로 이 순회 중 동일한 요소를 두 번 방문할 수 있습니다.
          2. SetDataHas(resultSetData, entry)가 false이면, 다음을 수행합니다.
            1. entry를 resultSetData에 추가합니다.
        3. 참고: otherRecord.[[Has]] 실행 중 set.[[SetData]]의 요소 수가 증가했을 수 있습니다.
        4. thisSize를 set.[[SetData]]의 요소 수로 설정합니다.
  6. 그렇지 않으면,
    1. keysIterator를 ? GetIteratorFromMethod(otherRecord.[[SetObject]], otherRecord.[[Keys]])로 둡니다.
    2. next를 not-started로 둡니다.
    3. next가 done이 아닌 동안 다음을 반복합니다.
      1. next를 ? IteratorStepValue(keysIterator)로 설정합니다.
      2. next가 done이 아니면, 다음을 수행합니다.
        1. next를 CanonicalizeKeyedCollectionKey(next)로 설정합니다.
        2. inThis를 SetDataHas(set.[[SetData]], next)로 둡니다.
        3. inThis가 true이면, 다음을 수행합니다.
          1. 참고: other는 임의의 객체이므로 해당 "keys" 반복자가 동일한 값을 두 번 이상 생성할 수 있습니다.
          2. SetDataHas(resultSetData, next)가 false이면, 다음을 수행합니다.
            1. next를 resultSetData에 추가합니다.
  7. result를 OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »)로 둡니다.
  8. result.[[SetData]]를 resultSetData로 설정합니다.
  9. result를 반환합니다.

24.2.4.10 Set.prototype.isDisjointFrom ( other )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. otherRecord를 ? GetSetRecord(other)로 둡니다.
  4. SetDataSize(set.[[SetData]]) ≤ otherRecord.[[Size]]이면, 다음을 수행합니다.
    1. thisSize를 set.[[SetData]]의 요소 수로 둡니다.
    2. index를 0으로 둡니다.
    3. index < thisSize인 동안 다음을 반복합니다.
      1. entry를 set.[[SetData]][index]로 둡니다.
      2. index를 index + 1로 설정합니다.
      3. entry가 empty가 아니면, 다음을 수행합니다.
        1. inOther를 ToBoolean(? Call(otherRecord.[[Has]], otherRecord.[[SetObject]], « entry »))로 둡니다.
        2. inOther가 true이면 false를 반환합니다.
        3. 참고: otherRecord.[[Has]] 실행 중 set.[[SetData]]의 요소 수가 증가했을 수 있습니다.
        4. thisSize를 set.[[SetData]]의 요소 수로 설정합니다.
  5. 그렇지 않으면,
    1. keysIterator를 ? GetIteratorFromMethod(otherRecord.[[SetObject]], otherRecord.[[Keys]])로 둡니다.
    2. next를 not-started로 둡니다.
    3. next가 done이 아닌 동안 다음을 반복합니다.
      1. next를 ? IteratorStepValue(keysIterator)로 설정합니다.
      2. next가 done이 아니면, 다음을 수행합니다.
        1. SetDataHas(set.[[SetData]], next)가 true이면, 다음을 수행합니다.
          1. ? IteratorClose(keysIterator, NormalCompletion(unused))를 수행합니다.
          2. false를 반환합니다.
  6. true를 반환합니다.

24.2.4.11 Set.prototype.isSubsetOf ( other )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. otherRecord를 ? GetSetRecord(other)로 둡니다.
  4. SetDataSize(set.[[SetData]]) > otherRecord.[[Size]]이면 false를 반환합니다.
  5. thisSize를 set.[[SetData]]의 요소 수로 둡니다.
  6. index를 0으로 둡니다.
  7. index < thisSize인 동안 다음을 반복합니다.
    1. entry를 set.[[SetData]][index]로 둡니다.
    2. index를 index + 1로 설정합니다.
    3. entry가 empty가 아니면, 다음을 수행합니다.
      1. inOther를 ToBoolean(? Call(otherRecord.[[Has]], otherRecord.[[SetObject]], « entry »))로 둡니다.
      2. inOther가 false이면 false를 반환합니다.
      3. 참고: otherRecord.[[Has]] 실행 중 set.[[SetData]]의 요소 수가 증가했을 수 있습니다.
      4. thisSize를 set.[[SetData]]의 요소 수로 설정합니다.
  8. true를 반환합니다.

24.2.4.12 Set.prototype.isSupersetOf ( other )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. otherRecord를 ? GetSetRecord(other)로 둡니다.
  4. SetDataSize(set.[[SetData]]) < otherRecord.[[Size]]이면 false를 반환합니다.
  5. keysIterator를 ? GetIteratorFromMethod(otherRecord.[[SetObject]], otherRecord.[[Keys]])로 둡니다.
  6. next를 not-started로 둡니다.
  7. next가 done이 아닌 동안 다음을 반복합니다.
    1. next를 ? IteratorStepValue(keysIterator)로 설정합니다.
    2. next가 done이 아니면, 다음을 수행합니다.
      1. SetDataHas(set.[[SetData]], next)가 false이면, 다음을 수행합니다.
        1. ? IteratorClose(keysIterator, NormalCompletion(unused))를 수행합니다.
        2. false를 반환합니다.
  8. true를 반환합니다.

24.2.4.13 Set.prototype.keys ( )

"keys" 프로퍼티의 초기 값은 24.2.4.17에 정의된 %Set.prototype.values%입니다.

참고

순회 목적에서 Set은 각 항목의 키와 값이 동일한 Map과 유사하게 보입니다.

24.2.4.14 get Set.prototype.size

Set.prototype.size는 set 접근자 함수가 undefined인 접근자 프로퍼티입니다. get 접근자 함수는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. size를 SetDataSize(set.[[SetData]])로 둡니다.
  4. 𝔽(size)를 반환합니다.

24.2.4.15 Set.prototype.symmetricDifference ( other )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. otherRecord를 ? GetSetRecord(other)로 둡니다.
  4. keysIterator를 ? GetIteratorFromMethod(otherRecord.[[SetObject]], otherRecord.[[Keys]])로 둡니다.
  5. resultSetData를 set.[[SetData]]의 복사본으로 둡니다.
  6. next를 not-started로 둡니다.
  7. next가 done이 아닌 동안 다음을 반복합니다.
    1. next를 ? IteratorStepValue(keysIterator)로 설정합니다.
    2. next가 done이 아니면, 다음을 수행합니다.
      1. next를 CanonicalizeKeyedCollectionKey(next)로 설정합니다.
      2. resultIndex를 SetDataIndex(resultSetData, next)로 둡니다.
      3. resultIndex가 not-found이면 alreadyInResult를 false로 둡니다. 그렇지 않으면 alreadyInResult를 true로 둡니다.
      4. SetDataHas(set.[[SetData]], next)가 true이면, 다음을 수행합니다.
        1. alreadyInResult가 true이면 resultSetData[resultIndex]를 empty로 설정합니다.
      5. 그렇지 않으면,
        1. alreadyInResult가 false이면 next를 resultSetData에 추가합니다.
  8. result를 OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »)로 둡니다.
  9. result.[[SetData]]를 resultSetData로 설정합니다.
  10. result를 반환합니다.

24.2.4.16 Set.prototype.union ( other )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  3. otherRecord를 ? GetSetRecord(other)로 둡니다.
  4. keysIterator를 ? GetIteratorFromMethod(otherRecord.[[SetObject]], otherRecord.[[Keys]])로 둡니다.
  5. resultSetData를 set.[[SetData]]의 복사본으로 둡니다.
  6. next를 not-started로 둡니다.
  7. next가 done이 아닌 동안 다음을 반복합니다.
    1. next를 ? IteratorStepValue(keysIterator)로 설정합니다.
    2. next가 done이 아니면, 다음을 수행합니다.
      1. next를 CanonicalizeKeyedCollectionKey(next)로 설정합니다.
      2. SetDataHas(resultSetData, next)가 false이면, 다음을 수행합니다.
        1. next를 resultSetData에 추가합니다.
  8. result를 OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »)로 둡니다.
  9. result.[[SetData]]를 resultSetData로 설정합니다.
  10. result를 반환합니다.

24.2.4.17 Set.prototype.values ( )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. set을 this 값으로 둡니다.
  2. ? CreateSetIterator(set, value)를 반환합니다.

24.2.4.18 Set.prototype [ %Symbol.iterator% ] ( )

%Symbol.iterator% 프로퍼티의 초기 값은 24.2.4.17에 정의된 %Set.prototype.values%입니다.

24.2.4.19 Set.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 프로퍼티의 초기 값은 String 값 "Set"입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } 속성을 갖습니다.

24.2.5 Set 인스턴스의 프로퍼티

Set 인스턴스는 Set 프로토타입 객체에서 프로퍼티를 상속하는 일반 객체입니다. Set 인스턴스는 [[SetData]] 내부 슬롯도 갖습니다.

24.2.6 Set Iterator 객체

Set Iterator는 아래에 정의된 구조를 가지며 특정 Set 인스턴스 객체에 대한 특정 순회를 나타내는 일반 객체입니다. Set Iterator 객체에는 이름 있는 생성자가 없습니다. 대신 Set Iterator 객체는 Set 인스턴스 객체의 특정 메서드를 호출하여 생성됩니다.

24.2.6.1 CreateSetIterator ( set, kind )

추상 연산 CreateSetIterator. 인수 set (ECMAScript 언어 값) 및 kind ((key+value 또는 value)). 반환값: (정상 완료 (값: Generator) 또는 throw 완료). 그러한 반복자를 반환하는 Set 메서드의 반복자 객체를 생성하는 데 사용됩니다. 호출되면 다음 단계를 수행한다.

  1. ? RequireInternalSlot(set, [[SetData]])를 수행합니다.
  2. closure를 매개변수가 없고 set과 kind를 캡처하며 호출될 때 다음 단계를 수행하는 새로운 Abstract Closure로 둡니다:
    1. index를 0으로 둡니다.
    2. entries를 set.[[SetData]]로 둡니다.
    3. entriesCount를 entries의 요소 수로 둡니다.
    4. index < entriesCount인 동안 다음을 반복합니다.
      1. entry를 entries[index]로 둡니다.
      2. index를 index + 1로 설정합니다.
      3. entry가 empty가 아니면, 다음을 수행합니다.
        1. kind가 key+value이면, 다음을 수행합니다.
          1. result를 CreateArrayFromList(« entry, entry »)로 둡니다.
          2. ? GeneratorYield(CreateIteratorResultObject(result, false))를 수행합니다.
        2. 그렇지 않으면,
          1. 단언: kind는 value입니다.
          2. ? GeneratorYield(CreateIteratorResultObject(entry, false))를 수행합니다.
        3. 참고: GeneratorYield에 의해 이 추상 연산의 실행이 일시 중단된 동안 entries의 요소 수가 증가했을 수 있습니다.
        4. entriesCount를 entries의 요소 수로 설정합니다.
    5. NormalCompletion(unused)을 반환합니다.
  3. CreateIteratorFromClosure(closure, "%SetIteratorPrototype%", %SetIteratorPrototype%)을 반환합니다.

24.2.6.2 %SetIteratorPrototype% 객체

%SetIteratorPrototype% 객체는:

24.2.6.2.1 %SetIteratorPrototype%.next ( )

  1. ? GeneratorResume(this 값, empty, "%SetIteratorPrototype%")를 반환합니다.

24.2.6.2.2 %SetIteratorPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 프로퍼티의 초기 값은 String 값 "Set Iterator"입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } 속성을 갖습니다.

24.3 WeakMap 객체

WeakMap은 키가 객체 및/또는 Symbol이고 값은 임의의 ECMAScript language value일 수 있는 키/값 쌍의 컬렉션입니다. WeakMap에 특정 키를 갖는 키/값 쌍이 포함되어 있는지 조회할 수 있지만, 키로 보유하는 값을 열거하는 메커니즘은 제공되지 않습니다. 특정 조건에서는 9.9.3에 설명된 대로 생존하지 않는 값이 WeakMap 키에서 제거됩니다.

구현체는 WeakMap의 키/값 쌍에 접근할 수 없게 된 시점과 해당 키/값 쌍이 WeakMap에서 제거되는 시점 사이에 임의로 정한 지연 시간을 둘 수 있습니다. 이 지연 시간을 ECMAScript 프로그램이 관찰할 수 있다면 프로그램 실행에 영향을 줄 수 있는 비결정성의 원인이 됩니다. 따라서 ECMAScript 구현체는 관찰자가 관찰 대상 키를 제시하지 않고도 WeakMap의 키를 관찰할 수 있는 수단을 제공해서는 안 됩니다.

WeakMap은 평균적으로 컬렉션의 키/값 쌍 수에 대해 선형보다 빠른 접근 시간을 제공하는 해시 테이블이나 그 밖의 메커니즘을 사용하여 구현해야 합니다. 이 명세에서 사용하는 데이터 구조는 WeakMap에 요구되는 관찰 가능한 의미론을 설명하기 위한 것일 뿐입니다. 실제 구현 모델로 사용하려는 것은 아닙니다.

참고

WeakMap과 WeakSet은 WeakMap 또는 WeakSet 인스턴스가 없었다면 객체나 Symbol에 더 이상 접근할 수 없게 되어 구현체의 가비지 컬렉션 메커니즘에 의해 리소스 회수 대상이 되었을 경우 메모리 리소스를 “누수”하지 않는 방식으로 객체 또는 Symbol에 상태를 동적으로 연결하는 메커니즘을 제공하기 위한 것입니다. 이 특성은 객체/Symbol별로 WeakMap 또는 WeakSet 인스턴스를 키에 역매핑하는 방식을 사용하여 달성할 수 있습니다. 또는 각 WeakMap이나 WeakSet 인스턴스가 내부적으로 키와 값 데이터를 저장할 수도 있지만, 이 접근 방식은 WeakMap 또는 WeakSet 구현체와 가비지 컬렉터 사이의 조정이 필요합니다. 다음 참고 문헌에서는 WeakMap과 WeakSet 구현체에 유용할 수 있는 메커니즘을 설명합니다:

Barry Hayes. 1997. Ephemerons: a new finalization mechanism. In Proceedings of the 12th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA '97), A. Michael Berman (Ed.). ACM, New York, NY, USA, 176-183, http://doi.acm.org/10.1145/263698.263733.

Alexandra Barros, Roberto Ierusalimschy, Eliminating Cycles in Weak Tables. Journal of Universal Computer Science - J.UCS, vol. 14, no. 21, pp. 3481-3497, 2008, http://www.jucs.org/jucs_14_21/eliminating_cycles_in_weak

24.3.1 WeakMap 생성자

WeakMap 생성자는:

  • %WeakMap%입니다.
  • 전역 객체의 "WeakMap" 프로퍼티의 초기 값입니다.
  • 생성자로 호출되면 새로운 WeakMap을 생성하고 초기화합니다.
  • 함수로 호출하도록 의도되지 않았으며 그러한 방식으로 호출되면 예외를 던집니다.
  • 클래스 정의의 extends 절에서 값으로 사용할 수 있습니다. 지정된 WeakMap 동작을 상속하려는 하위 클래스 생성자는 WeakMap.prototype의 내장 메서드를 지원하는 데 필요한 내부 상태를 갖도록 하위 클래스 인스턴스를 생성하고 초기화하기 위해 WeakMap 생성자에 대한 super 호출을 포함해야 합니다.

24.3.1.1 WeakMap ( [ iterable ] )

이 함수는 호출되면 다음 단계를 수행합니다:

  1. NewTarget이 undefined이면 TypeError 예외를 던집니다.
  2. map을 ? OrdinaryCreateFromConstructor(NewTarget, "%WeakMap.prototype%", « [[WeakMapData]] »)로 둡니다.
  3. map.[[WeakMapData]]를 새로운 빈 List로 설정합니다.
  4. iterable이 undefined 또는 null이면 map을 반환합니다.
  5. adder를 ? Get(map, "set")으로 둡니다.
  6. IsCallable(adder)가 false이면 TypeError 예외를 던집니다.
  7. ? AddEntriesFromIterable(map, iterable, adder)를 반환합니다.
참고

매개변수 iterable이 존재하는 경우, 첫 번째 요소는 WeakMap 키로 사용할 값이고 두 번째 요소는 해당 키와 연결할 값인 두 요소의 배열과 유사한 객체를 생성하는 반복자 객체를 반환하는 %Symbol.iterator% 메서드를 구현한 객체일 것으로 예상됩니다.

24.3.2 WeakMap 생성자의 프로퍼티

WeakMap 생성자는:

  • 값이 %Function.prototype%인 [[Prototype]] 내부 슬롯을 갖습니다.
  • 다음 프로퍼티를 갖습니다:

24.3.2.1 WeakMap.prototype

WeakMap.prototype의 초기 값은 WeakMap 프로토타입 객체입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } 속성을 갖습니다.

24.3.3 WeakMap 프로토타입 객체의 프로퍼티

WeakMap 프로토타입 객체는:

  • %WeakMap.prototype%입니다.
  • 값이 %Object.prototype%인 [[Prototype]] 내부 슬롯을 갖습니다.
  • 일반 객체입니다.
  • [[WeakMapData]] 내부 슬롯을 갖지 않습니다.

24.3.3.1 WeakMap.prototype.constructor

WeakMap.prototype.constructor의 초기 값은 %WeakMap%입니다.

24.3.3.2 WeakMap.prototype.delete ( key )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. weakMap을 this 값으로 둡니다.
  2. ? RequireInternalSlot(weakMap, [[WeakMapData]])를 수행합니다.
  3. CanBeHeldWeakly(key)가 false이면 false를 반환합니다.
  4. weakMap.[[WeakMapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면, 다음을 수행합니다.
      1. entry.[[Key]]를 empty로 설정합니다.
      2. entry.[[Value]]를 empty로 설정합니다.
      3. true를 반환합니다.
  5. false를 반환합니다.
참고

값 empty는 항목이 삭제되었음을 나타내기 위한 명세상의 장치로 사용됩니다. 실제 구현체는 내부 데이터 구조에서 항목을 물리적으로 제거하는 등의 다른 동작을 수행할 수 있습니다.

24.3.3.3 WeakMap.prototype.get ( key )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. weakMap을 this 값으로 둡니다.
  2. ? RequireInternalSlot(weakMap, [[WeakMapData]])를 수행합니다.
  3. CanBeHeldWeakly(key)가 false이면 undefined를 반환합니다.
  4. weakMap.[[WeakMapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면 entry.[[Value]]를 반환합니다.
  5. undefined를 반환합니다.

24.3.3.4 WeakMap.prototype.getOrInsert ( key, value )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. weakMap을 this 값으로 둡니다.
  2. ? RequireInternalSlot(weakMap, [[WeakMapData]])를 수행합니다.
  3. CanBeHeldWeakly(key)가 false이면 TypeError 예외를 던집니다.
  4. weakMap.[[WeakMapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면 entry.[[Value]]를 반환합니다.
  5. entry를 Record { [[Key]]: key, [[Value]]: value }로 둡니다.
  6. entry를 weakMap.[[WeakMapData]]에 추가합니다.
  7. value를 반환합니다.

24.3.3.5 WeakMap.prototype.getOrInsertComputed ( key, callback )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. weakMap을 this 값으로 둡니다.
  2. ? RequireInternalSlot(weakMap, [[WeakMapData]])를 수행합니다.
  3. CanBeHeldWeakly(key)가 false이면 TypeError 예외를 던집니다.
  4. IsCallable(callback)이 false이면 TypeError 예외를 던집니다.
  5. weakMap.[[WeakMapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면 entry.[[Value]]를 반환합니다.
  6. value를 ? Call(callback, undefined, « key »)로 둡니다.
  7. 참고: callback 실행 중 WeakMap이 변경되었을 수 있습니다.
  8. weakMap.[[WeakMapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면, 다음을 수행합니다.
      1. entry.[[Value]]를 value로 설정합니다.
      2. value를 반환합니다.
  9. entry를 Record { [[Key]]: key, [[Value]]: value }로 둡니다.
  10. entry를 weakMap.[[WeakMapData]]에 추가합니다.
  11. value를 반환합니다.

24.3.3.6 WeakMap.prototype.has ( key )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. weakMap을 this 값으로 둡니다.
  2. ? RequireInternalSlot(weakMap, [[WeakMapData]])를 수행합니다.
  3. CanBeHeldWeakly(key)가 false이면 false를 반환합니다.
  4. weakMap.[[WeakMapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면 true를 반환합니다.
  5. false를 반환합니다.

24.3.3.7 WeakMap.prototype.set ( key, value )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. weakMap을 this 값으로 둡니다.
  2. ? RequireInternalSlot(weakMap, [[WeakMapData]])를 수행합니다.
  3. CanBeHeldWeakly(key)가 false이면 TypeError 예외를 던집니다.
  4. weakMap.[[WeakMapData]]의 각 Record { [[Key]], [[Value]] } entry에 대해 다음을 수행합니다.
    1. entry.[[Key]]가 empty가 아니고 SameValue(entry.[[Key]], key)가 true이면, 다음을 수행합니다.
      1. entry.[[Value]]를 value로 설정합니다.
      2. weakMap을 반환합니다.
  5. entry를 Record { [[Key]]: key, [[Value]]: value }로 둡니다.
  6. entry를 weakMap.[[WeakMapData]]에 추가합니다.
  7. weakMap을 반환합니다.

24.3.3.8 WeakMap.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 프로퍼티의 초기 값은 String 값 "WeakMap"입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } 속성을 갖습니다.

24.3.4 WeakMap 인스턴스의 프로퍼티

WeakMap 인스턴스는 WeakMap 프로토타입 객체에서 프로퍼티를 상속하는 일반 객체입니다. WeakMap 인스턴스는 [[WeakMapData]] 내부 슬롯도 갖습니다.

24.4 WeakSet 객체

WeakSet은 객체 및/또는 Symbol의 컬렉션입니다. 서로 다른 객체나 Symbol은 WeakSet의 컬렉션에 요소로 한 번만 나타날 수 있습니다. WeakSet에 특정 값이 포함되어 있는지 조회할 수 있지만, 보유하는 값을 열거하는 메커니즘은 제공되지 않습니다. 특정 조건에서는 9.9.3에 설명된 대로 생존하지 않는 값이 WeakSet 요소에서 제거됩니다.

구현체는 WeakSet에 포함된 값에 접근할 수 없게 된 시점과 해당 값이 WeakSet에서 제거되는 시점 사이에 임의로 정한 지연 시간을 둘 수 있습니다. 이 지연 시간을 ECMAScript 프로그램이 관찰할 수 있다면 프로그램 실행에 영향을 줄 수 있는 비결정성의 원인이 됩니다. 따라서 ECMAScript 구현체는 관찰자가 관찰 대상 값을 제시하지 않고도 WeakSet에 특정 값이 포함되어 있는지 판단할 수 있는 수단을 제공해서는 안 됩니다.

WeakSet은 평균적으로 컬렉션의 요소 수에 대해 선형보다 빠른 접근 시간을 제공하는 해시 테이블이나 그 밖의 메커니즘을 사용하여 구현해야 합니다. 이 명세에서 사용하는 데이터 구조는 WeakSet에 요구되는 관찰 가능한 의미론을 설명하기 위한 것일 뿐입니다. 실제 구현 모델로 사용하려는 것은 아닙니다.

참고

24.3의 참고를 참조하시기 바랍니다.

24.4.1 WeakSet 생성자

WeakSet 생성자는:

  • %WeakSet%입니다.
  • 전역 객체의 "WeakSet" 프로퍼티의 초기 값입니다.
  • 생성자로 호출되면 새로운 WeakSet을 생성하고 초기화합니다.
  • 함수로 호출하도록 의도되지 않았으며 그러한 방식으로 호출되면 예외를 던집니다.
  • 클래스 정의의 extends 절에서 값으로 사용할 수 있습니다. 지정된 WeakSet 동작을 상속하려는 하위 클래스 생성자는 WeakSet.prototype의 내장 메서드를 지원하는 데 필요한 내부 상태를 갖도록 하위 클래스 인스턴스를 생성하고 초기화하기 위해 WeakSet 생성자에 대한 super 호출을 포함해야 합니다.

24.4.1.1 WeakSet ( [ iterable ] )

이 함수는 호출되면 다음 단계를 수행합니다:

  1. NewTarget이 undefined이면 TypeError 예외를 던집니다.
  2. set을 ? OrdinaryCreateFromConstructor(NewTarget, "%WeakSet.prototype%", « [[WeakSetData]] »)로 둡니다.
  3. set.[[WeakSetData]]를 새로운 빈 List로 설정합니다.
  4. iterable이 undefined 또는 null이면 set을 반환합니다.
  5. adder를 ? Get(set, "add")로 둡니다.
  6. IsCallable(adder)가 false이면 TypeError 예외를 던집니다.
  7. iteratorRecord를 ? GetIterator(iterable, sync)로 둡니다.
  8. 다음을 반복합니다.
    1. next를 ? IteratorStepValue(iteratorRecord)로 둡니다.
    2. next가 done이면 set을 반환합니다.
    3. status를 Completion(Call(adder, set, « next »))로 둡니다.
    4. IfAbruptCloseIterator(status, iteratorRecord).

24.4.2 WeakSet 생성자의 프로퍼티

WeakSet 생성자는:

  • 값이 %Function.prototype%인 [[Prototype]] 내부 슬롯을 갖습니다.
  • 다음 프로퍼티를 갖습니다:

24.4.2.1 WeakSet.prototype

WeakSet.prototype의 초기 값은 WeakSet 프로토타입 객체입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } 속성을 갖습니다.

24.4.3 WeakSet 프로토타입 객체의 프로퍼티

WeakSet 프로토타입 객체는:

  • %WeakSet.prototype%입니다.
  • 값이 %Object.prototype%인 [[Prototype]] 내부 슬롯을 갖습니다.
  • 일반 객체입니다.
  • [[WeakSetData]] 내부 슬롯을 갖지 않습니다.

24.4.3.1 WeakSet.prototype.add ( value )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. weakSet을 this 값으로 둡니다.
  2. ? RequireInternalSlot(weakSet, [[WeakSetData]])를 수행합니다.
  3. CanBeHeldWeakly(value)가 false이면 TypeError 예외를 던집니다.
  4. weakSet.[[WeakSetData]]의 각 요소 entry에 대해 다음을 수행합니다.
    1. entry가 empty가 아니고 SameValue(entry, value)가 true이면, 다음을 수행합니다.
      1. weakSet을 반환합니다.
  5. value를 weakSet.[[WeakSetData]]에 추가합니다.
  6. weakSet을 반환합니다.

24.4.3.2 WeakSet.prototype.constructor

WeakSet.prototype.constructor의 초기 값은 %WeakSet%입니다.

24.4.3.3 WeakSet.prototype.delete ( value )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. weakSet을 this 값으로 둡니다.
  2. ? RequireInternalSlot(weakSet, [[WeakSetData]])를 수행합니다.
  3. CanBeHeldWeakly(value)가 false이면 false를 반환합니다.
  4. weakSet.[[WeakSetData]]의 각 요소 entry에 대해 다음을 수행합니다.
    1. entry가 empty가 아니고 SameValue(entry, value)가 true이면, 다음을 수행합니다.
      1. 값이 entry인 weakSet.[[WeakSetData]]의 요소를 값이 empty인 요소로 대체합니다.
      2. true를 반환합니다.
  5. false를 반환합니다.
참고

값 empty는 항목이 삭제되었음을 나타내기 위한 명세상의 장치로 사용됩니다. 실제 구현체는 내부 데이터 구조에서 항목을 물리적으로 제거하는 등의 다른 동작을 수행할 수 있습니다.

24.4.3.4 WeakSet.prototype.has ( value )

이 메서드는 호출되면 다음 단계를 수행합니다:

  1. weakSet을 this 값으로 둡니다.
  2. ? RequireInternalSlot(weakSet, [[WeakSetData]])를 수행합니다.
  3. CanBeHeldWeakly(value)가 false이면 false를 반환합니다.
  4. weakSet.[[WeakSetData]]의 각 요소 entry에 대해 다음을 수행합니다.
    1. entry가 empty가 아니고 SameValue(entry, value)가 true이면 true를 반환합니다.
  5. false를 반환합니다.

24.4.3.5 WeakSet.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 프로퍼티의 초기 값은 String 값 "WeakSet"입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } 속성을 갖습니다.

24.4.4 WeakSet 인스턴스의 프로퍼티

WeakSet 인스턴스는 WeakSet 프로토타입 객체에서 프로퍼티를 상속하는 일반 객체입니다. WeakSet 인스턴스는 [[WeakSetData]] 내부 슬롯도 갖습니다.

24.5 키 컬렉션을 위한 추상 연산

24.5.1 CanonicalizeKeyedCollectionKey ( key )

추상 연산 CanonicalizeKeyedCollectionKey. 인수 key (ECMAScript 언어 값). 반환값: ECMAScript 언어 값. 호출되면 다음 단계를 수행한다.

  1. key가 -0𝔽이면 +0𝔽을 반환합니다.
  2. key를 반환합니다.