@@ -745,55 +745,72 @@ const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbo
745745 * @param {string | number } [keyIndex]
746746 * @param {string | number } [valueIndex]
747747 */
748- function createIterator ( name , kInternalIterator , keyIndex = 0 , valueIndex = 1 ) {
749- const kInternalObject = Symbol ( 'internal Object' )
750-
751- // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%.
752- const iteratorObject = Object . create ( esIteratorPrototype )
748+ function createFastIterator ( name , kInternalIterator , keyIndex = 0 , valueIndex = 1 ) {
749+ class FastIterableIterator {
750+ /** @type {any } */
751+ #target
752+ /** @type {'key' | 'value' | 'key+value' } */
753+ #kind
754+ /** @type {number } */
755+ #index
756+
757+ /**
758+ * @see https://webidl.spec.whatwg.org/#dfn-default-iterator-object
759+ * @param {unknown } target
760+ * @param {'key' | 'value' | 'key+value' } kind
761+ */
762+ constructor ( target , kind ) {
763+ this . #target = target
764+ this . #kind = kind
765+ this . #index = 0
766+ }
753767
754- Object . defineProperty ( iteratorObject , 'next' , {
755- value : function next ( ) {
768+ next ( ) {
756769 // 1. Let interface be the interface for which the iterator prototype object exists.
757-
758770 // 2. Let thisValue be the this value.
759-
760771 // 3. Let object be ? ToObject(thisValue).
761-
762772 // 4. If object is a platform object, then perform a security
763773 // check, passing:
764-
765774 // 5. If object is not a default iterator object for interface,
766775 // then throw a TypeError.
767- if ( typeof this !== 'object' || this === null || ! ( kInternalObject in this ) ) {
776+ // Object.getPrototypeOf(this) !== FastIterator.prototype
777+ if ( typeof this !== 'object' || this === null || ! ( #target in this ) ) {
768778 throw new TypeError (
769779 `'next' called on an object that does not implement interface ${ name } Iterator.`
770780 )
771781 }
772- const object = this [ kInternalObject ]
773782
774783 // 6. Let index be object’s index.
775784 // 7. Let kind be object’s kind.
776785 // 8. Let values be object’s target's value pairs to iterate over.
777- const { index, kind , target } = object
778- const values = target [ kInternalIterator ]
786+ const index = this . #index
787+ const values = this . # target[ kInternalIterator ]
779788
780789 // 9. Let len be the length of values.
781790 const len = values . length
782791
783792 // 10. If index is greater than or equal to len, then return
784793 // CreateIterResultObject(undefined, true).
785794 if ( index >= len ) {
786- return { value : undefined , done : true }
795+ return {
796+ value : undefined ,
797+ done : true
798+ }
787799 }
800+
788801 // 11. Let pair be the entry in values at index index.
789802 const { [ keyIndex ] : key , [ valueIndex ] : value } = values [ index ]
803+
790804 // 12. Set object’s index to index + 1.
791- object . index = index + 1
805+ this . #index = index + 1
806+
792807 // 13. Return the iterator result for pair and kind.
808+
793809 // https://webidl.spec.whatwg.org/#iterator-result
810+
794811 // 1. Let result be a value determined by the value of kind:
795812 let result
796- switch ( kind ) {
813+ switch ( this . # kind) {
797814 case 'key' :
798815 // 1. Let idlKey be pair’s key.
799816 // 2. Let key be the result of converting idlKey to an
@@ -822,45 +839,37 @@ function createIterator (name, kInternalIterator, keyIndex = 0, valueIndex = 1)
822839 result = [ key , value ]
823840 break
824841 }
842+
825843 // 2. Return CreateIterResultObject(result, false).
826844 return {
827845 value : result ,
828846 done : false
829847 }
830- } ,
831- writable : true ,
832- enumerable : true ,
833- configurable : true
834- } )
848+ }
849+ }
850+
851+ // https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
852+ // @ts -ignore
853+ delete FastIterableIterator . prototype . constructor
854+
855+ Object . setPrototypeOf ( FastIterableIterator . prototype , esIteratorPrototype )
835856
836- // The class string of an iterator prototype object for a given interface is the
837- // result of concatenating the identifier of the interface and the string " Iterator".
838- Object . defineProperty ( iteratorObject , Symbol . toStringTag , {
839- value : `${ name } Iterator` ,
840- writable : false ,
841- enumerable : false ,
842- configurable : true
857+ Object . defineProperties ( FastIterableIterator . prototype , {
858+ [ Symbol . toStringTag ] : {
859+ writable : false ,
860+ enumerable : false ,
861+ configurable : true ,
862+ value : `${ name } Iterator`
863+ } ,
864+ next : { writable : true , enumerable : true , configurable : true }
843865 } )
844866
845867 /**
846868 * @param {unknown } target
847- * @param {'key'| 'value'| 'key+value' } kind
869+ * @param {'key' | 'value' | 'key+value' } kind
848870 */
849871 return function ( target , kind ) {
850- // esIteratorPrototype needs to be the prototype of iteratorObject
851- // which is the prototype of an empty object. Yes, it's confusing.
852- const iterator = Object . create ( iteratorObject )
853- Object . defineProperty ( iterator , kInternalObject , {
854- value : {
855- target,
856- kind,
857- index : 0
858- } ,
859- writable : false ,
860- enumerable : false ,
861- configurable : true
862- } )
863- return iterator
872+ return new FastIterableIterator ( target , kind )
864873 }
865874}
866875
@@ -873,7 +882,7 @@ function createIterator (name, kInternalIterator, keyIndex = 0, valueIndex = 1)
873882 * @param {string | number } [valueIndex]
874883 */
875884function iteratorMixin ( name , object , kInternalIterator , keyIndex = 0 , valueIndex = 1 ) {
876- const makeIterator = createIterator ( name , kInternalIterator , keyIndex , valueIndex )
885+ const createIterator = createFastIterator ( name , kInternalIterator , keyIndex , valueIndex )
877886
878887 const properties = {
879888 keys : {
@@ -882,7 +891,7 @@ function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, valueInde
882891 configurable : true ,
883892 value : function keys ( ) {
884893 webidl . brandCheck ( this , object )
885- return makeIterator ( this , 'key' )
894+ return createIterator ( this , 'key' )
886895 }
887896 } ,
888897 values : {
@@ -891,7 +900,7 @@ function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, valueInde
891900 configurable : true ,
892901 value : function values ( ) {
893902 webidl . brandCheck ( this , object )
894- return makeIterator ( this , 'value' )
903+ return createIterator ( this , 'value' )
895904 }
896905 } ,
897906 entries : {
@@ -900,7 +909,7 @@ function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, valueInde
900909 configurable : true ,
901910 value : function entries ( ) {
902911 webidl . brandCheck ( this , object )
903- return makeIterator ( this , 'key+value' )
912+ return createIterator ( this , 'key+value' )
904913 }
905914 } ,
906915 forEach : {
@@ -915,7 +924,7 @@ function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, valueInde
915924 `Failed to execute 'forEach' on '${ name } ': parameter 1 is not of type 'Function'.`
916925 )
917926 }
918- for ( const { 0 : key , 1 : value } of makeIterator ( this , 'key+value' ) ) {
927+ for ( const { 0 : key , 1 : value } of createIterator ( this , 'key+value' ) ) {
919928 callbackfn . call ( thisArg , value , key , this )
920929 }
921930 }
@@ -1448,7 +1457,6 @@ module.exports = {
14481457 sameOrigin,
14491458 normalizeMethod,
14501459 serializeJavascriptValueToJSONString,
1451- createIterator,
14521460 iteratorMixin,
14531461 isValidHeaderName,
14541462 isValidHeaderValue,
0 commit comments