@@ -808,19 +808,23 @@ const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbo
808
808
809
809
/**
810
810
* @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
811
- * @param {() => unknown[] } iterator
811
+ * @param {() => unknown } iterator
812
812
* @param {string } name name of the instance
813
813
* @param {'key'|'value'|'key+value' } kind
814
+ * @param {string | number } [keyIndex]
815
+ * @param {string | number } [valueIndex]
814
816
*/
815
- function makeIterator ( iterator , name , kind ) {
817
+ function makeIterator ( iterator , name , kind , keyIndex = 0 , valueIndex = 1 ) {
816
818
const object = {
817
819
index : 0 ,
818
820
kind,
819
821
target : iterator
820
822
}
823
+ // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%.
824
+ const iteratorObject = Object . create ( esIteratorPrototype )
821
825
822
- const i = {
823
- next ( ) {
826
+ Object . defineProperty ( iteratorObject , 'next' , {
827
+ value : function next ( ) {
824
828
// 1. Let interface be the interface for which the iterator prototype object exists.
825
829
826
830
// 2. Let thisValue be the this value.
@@ -832,7 +836,7 @@ function makeIterator (iterator, name, kind) {
832
836
833
837
// 5. If object is not a default iterator object for interface,
834
838
// then throw a TypeError.
835
- if ( Object . getPrototypeOf ( this ) !== i ) {
839
+ if ( Object . getPrototypeOf ( this ) !== iteratorObject ) {
836
840
throw new TypeError (
837
841
`'next' called on an object that does not implement interface ${ name } Iterator.`
838
842
)
@@ -852,68 +856,66 @@ function makeIterator (iterator, name, kind) {
852
856
if ( index >= len ) {
853
857
return { value : undefined , done : true }
854
858
}
855
-
856
859
// 11. Let pair be the entry in values at index index.
857
- const pair = values [ index ]
858
-
860
+ const { [ keyIndex ] : key , [ valueIndex ] : value } = values [ index ]
859
861
// 12. Set object’s index to index + 1.
860
862
object . index = index + 1
861
-
862
863
// 13. Return the iterator result for pair and kind.
863
- return iteratorResult ( pair , kind )
864
+ // https://webidl.spec.whatwg.org/#iterator-result
865
+ // 1. Let result be a value determined by the value of kind:
866
+ let result
867
+ switch ( kind ) {
868
+ case 'key' :
869
+ // 1. Let idlKey be pair’s key.
870
+ // 2. Let key be the result of converting idlKey to an
871
+ // ECMAScript value.
872
+ // 3. result is key.
873
+ result = key
874
+ break
875
+ case 'value' :
876
+ // 1. Let idlValue be pair’s value.
877
+ // 2. Let value be the result of converting idlValue to
878
+ // an ECMAScript value.
879
+ // 3. result is value.
880
+ result = value
881
+ break
882
+ case 'key+value' :
883
+ // 1. Let idlKey be pair’s key.
884
+ // 2. Let idlValue be pair’s value.
885
+ // 3. Let key be the result of converting idlKey to an
886
+ // ECMAScript value.
887
+ // 4. Let value be the result of converting idlValue to
888
+ // an ECMAScript value.
889
+ // 5. Let array be ! ArrayCreate(2).
890
+ // 6. Call ! CreateDataProperty(array, "0", key).
891
+ // 7. Call ! CreateDataProperty(array, "1", value).
892
+ // 8. result is array.
893
+ result = [ key , value ]
894
+ break
895
+ }
896
+ // 2. Return CreateIterResultObject(result, false).
897
+ return {
898
+ value : result ,
899
+ done : false
900
+ }
864
901
} ,
865
- // The class string of an iterator prototype object for a given interface is the
866
- // result of concatenating the identifier of the interface and the string " Iterator".
867
- [ Symbol . toStringTag ] : `${ name } Iterator`
868
- }
869
-
870
- // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%.
871
- Object . setPrototypeOf ( i , esIteratorPrototype )
872
- // esIteratorPrototype needs to be the prototype of i
873
- // which is the prototype of an empty object. Yes, it's confusing.
874
- return Object . setPrototypeOf ( { } , i )
875
- }
902
+ writable : true ,
903
+ enumerable : true ,
904
+ configurable : true
905
+ } )
876
906
877
- // https://webidl.spec.whatwg.org/#iterator-result
878
- function iteratorResult ( pair , kind ) {
879
- let result
880
-
881
- // 1. Let result be a value determined by the value of kind:
882
- switch ( kind ) {
883
- case 'key' : {
884
- // 1. Let idlKey be pair’s key.
885
- // 2. Let key be the result of converting idlKey to an
886
- // ECMAScript value.
887
- // 3. result is key.
888
- result = pair [ 0 ]
889
- break
890
- }
891
- case 'value' : {
892
- // 1. Let idlValue be pair’s value.
893
- // 2. Let value be the result of converting idlValue to
894
- // an ECMAScript value.
895
- // 3. result is value.
896
- result = pair [ 1 ]
897
- break
898
- }
899
- case 'key+value' : {
900
- // 1. Let idlKey be pair’s key.
901
- // 2. Let idlValue be pair’s value.
902
- // 3. Let key be the result of converting idlKey to an
903
- // ECMAScript value.
904
- // 4. Let value be the result of converting idlValue to
905
- // an ECMAScript value.
906
- // 5. Let array be ! ArrayCreate(2).
907
- // 6. Call ! CreateDataProperty(array, "0", key).
908
- // 7. Call ! CreateDataProperty(array, "1", value).
909
- // 8. result is array.
910
- result = pair
911
- break
912
- }
913
- }
907
+ // The class string of an iterator prototype object for a given interface is the
908
+ // result of concatenating the identifier of the interface and the string " Iterator".
909
+ Object . defineProperty ( iteratorObject , Symbol . toStringTag , {
910
+ value : `${ name } Iterator` ,
911
+ writable : false ,
912
+ enumerable : false ,
913
+ configurable : true
914
+ } )
914
915
915
- // 2. Return CreateIterResultObject(result, false).
916
- return { value : result , done : false }
916
+ // esIteratorPrototype needs to be the prototype of iteratorObject
917
+ // which is the prototype of an empty object. Yes, it's confusing.
918
+ return Object . create ( iteratorObject )
917
919
}
918
920
919
921
/**
0 commit comments