- read

In-depth Reading of “Iterator Iterable”

Xiuer Old 56

In-depth Reading of “Iterator Iterable”

Xiuer Old
JavaScript in Plain English
5 min read20 hours ago


Why you need an iterator

Because for ... of it is very convenient to loop through arrays, but it would be too troublesome if only arrays supported this syntax. For example, we would naturally want to be able to for ... of traverse each character of the string and hope new Set([1, 2, 3]) to quickly initialize a new one Set.

JS supports all the capabilities mentioned above, so why does the JS engine know how to traverse strings? How to know the correspondence between the array [1, 2, 3] and Set each Key of the type? The principle behind implementing these functions is Iterables.

Because Array both Set are iterable, they can all be for ... of traversed, and the JS engine naturally knows the mutual conversion relationship between them.

How iterators are designed

There are two ways to define iterators, namely defining them independently and combining them in an object.

independent definition

Just extend the properties for the object [Symbol.iterator]. The reason why is adopted in the specification [Symbol.iterator] is to prevent the ordinary literal Key from conflicting with the object's own OwnProperties:

const obj = {}
obj[Symbol.iterator] = function() {
return {
someValue: 1,

next() {
// This value can be accessed and modified through this.someValue,
// and any number of variables can be defined as auxiliary variables
// during the iteration process
if (...) {
// Indicates that the iteration is not over yet and the current value is value
return { done: false, value: this.current++ }
return { done: true } // Indicates that the iteration is completed

At for ... of, done: true it will continue to loop as long as it is not read.

Merge is defined in the object

To simplify it a bit, you can define iteration in an object:

let range = {
from: 1,
to: 5,

[Symbol.iterator]() {
this.current = this.from;
return this;

next() {
if (this.current <= this.to) {
return { done: false, value: this.current++ }…