@@ -739,19 +739,23 @@ const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbo
739
739
740
740
/**
741
741
* @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
742
- * @param {() => unknown[] } iterator
742
+ * @param {() => unknown } iterator
743
743
* @param {string } name name of the instance
744
744
* @param {'key'|'value'|'key+value' } kind
745
+ * @param {string | number } [keyIndex]
746
+ * @param {string | number } [valueIndex]
745
747
*/
746
- function makeIterator ( iterator , name , kind ) {
748
+ function makeIterator ( iterator , name , kind , keyIndex = 0 , valueIndex = 1 ) {
747
749
const object = {
748
750
index : 0 ,
749
751
kind,
750
752
target : iterator
751
753
}
754
+ // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%.
755
+ const iteratorObject = Object . create ( esIteratorPrototype )
752
756
753
- const i = {
754
- next ( ) {
757
+ Object . defineProperty ( iteratorObject , 'next' , {
758
+ value : function next ( ) {
755
759
// 1. Let interface be the interface for which the iterator prototype object exists.
756
760
757
761
// 2. Let thisValue be the this value.
@@ -763,7 +767,7 @@ function makeIterator (iterator, name, kind) {
763
767
764
768
// 5. If object is not a default iterator object for interface,
765
769
// then throw a TypeError.
766
- if ( Object . getPrototypeOf ( this ) !== i ) {
770
+ if ( Object . getPrototypeOf ( this ) !== iteratorObject ) {
767
771
throw new TypeError (
768
772
`'next' called on an object that does not implement interface ${ name } Iterator.`
769
773
)
@@ -783,68 +787,66 @@ function makeIterator (iterator, name, kind) {
783
787
if ( index >= len ) {
784
788
return { value : undefined , done : true }
785
789
}
786
-
787
790
// 11. Let pair be the entry in values at index index.
788
- const pair = values [ index ]
789
-
791
+ const { [ keyIndex ] : key , [ valueIndex ] : value } = values [ index ]
790
792
// 12. Set object’s index to index + 1.
791
793
object . index = index + 1
792
-
793
794
// 13. Return the iterator result for pair and kind.
794
- return iteratorResult ( pair , kind )
795
+ // https://webidl.spec.whatwg.org/#iterator-result
796
+ // 1. Let result be a value determined by the value of kind:
797
+ let result
798
+ switch ( kind ) {
799
+ case 'key' :
800
+ // 1. Let idlKey be pair’s key.
801
+ // 2. Let key be the result of converting idlKey to an
802
+ // ECMAScript value.
803
+ // 3. result is key.
804
+ result = key
805
+ break
806
+ case 'value' :
807
+ // 1. Let idlValue be pair’s value.
808
+ // 2. Let value be the result of converting idlValue to
809
+ // an ECMAScript value.
810
+ // 3. result is value.
811
+ result = value
812
+ break
813
+ case 'key+value' :
814
+ // 1. Let idlKey be pair’s key.
815
+ // 2. Let idlValue be pair’s value.
816
+ // 3. Let key be the result of converting idlKey to an
817
+ // ECMAScript value.
818
+ // 4. Let value be the result of converting idlValue to
819
+ // an ECMAScript value.
820
+ // 5. Let array be ! ArrayCreate(2).
821
+ // 6. Call ! CreateDataProperty(array, "0", key).
822
+ // 7. Call ! CreateDataProperty(array, "1", value).
823
+ // 8. result is array.
824
+ result = [ key , value ]
825
+ break
826
+ }
827
+ // 2. Return CreateIterResultObject(result, false).
828
+ return {
829
+ value : result ,
830
+ done : false
831
+ }
795
832
} ,
796
- // The class string of an iterator prototype object for a given interface is the
797
- // result of concatenating the identifier of the interface and the string " Iterator".
798
- [ Symbol . toStringTag ] : `${ name } Iterator`
799
- }
800
-
801
- // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%.
802
- Object . setPrototypeOf ( i , esIteratorPrototype )
803
- // esIteratorPrototype needs to be the prototype of i
804
- // which is the prototype of an empty object. Yes, it's confusing.
805
- return Object . setPrototypeOf ( { } , i )
806
- }
833
+ writable : true ,
834
+ enumerable : true ,
835
+ configurable : true
836
+ } )
807
837
808
- // https://webidl.spec.whatwg.org/#iterator-result
809
- function iteratorResult ( pair , kind ) {
810
- let result
811
-
812
- // 1. Let result be a value determined by the value of kind:
813
- switch ( kind ) {
814
- case 'key' : {
815
- // 1. Let idlKey be pair’s key.
816
- // 2. Let key be the result of converting idlKey to an
817
- // ECMAScript value.
818
- // 3. result is key.
819
- result = pair [ 0 ]
820
- break
821
- }
822
- case 'value' : {
823
- // 1. Let idlValue be pair’s value.
824
- // 2. Let value be the result of converting idlValue to
825
- // an ECMAScript value.
826
- // 3. result is value.
827
- result = pair [ 1 ]
828
- break
829
- }
830
- case 'key+value' : {
831
- // 1. Let idlKey be pair’s key.
832
- // 2. Let idlValue be pair’s value.
833
- // 3. Let key be the result of converting idlKey to an
834
- // ECMAScript value.
835
- // 4. Let value be the result of converting idlValue to
836
- // an ECMAScript value.
837
- // 5. Let array be ! ArrayCreate(2).
838
- // 6. Call ! CreateDataProperty(array, "0", key).
839
- // 7. Call ! CreateDataProperty(array, "1", value).
840
- // 8. result is array.
841
- result = pair
842
- break
843
- }
844
- }
838
+ // The class string of an iterator prototype object for a given interface is the
839
+ // result of concatenating the identifier of the interface and the string " Iterator".
840
+ Object . defineProperty ( iteratorObject , Symbol . toStringTag , {
841
+ value : `${ name } Iterator` ,
842
+ writable : false ,
843
+ enumerable : false ,
844
+ configurable : true
845
+ } )
845
846
846
- // 2. Return CreateIterResultObject(result, false).
847
- return { value : result , done : false }
847
+ // esIteratorPrototype needs to be the prototype of iteratorObject
848
+ // which is the prototype of an empty object. Yes, it's confusing.
849
+ return Object . create ( iteratorObject )
848
850
}
849
851
850
852
/**
0 commit comments