by @zhangbao(zhangbao) #0104
An iterable can be thought of as “an Array in the broad sense” — that is, not necessarily an Array(array.isarray (iterable) returns false), but can be for… The of loop traverses.
An overview of
- An iterable doesn’t have to be an array; an array must be an iterable.
- Each iterable must contain one
[Symbol.iterator]
The method attributes - Strings are also iterable
Transform common objects
Let’s take an example. Here’s an object:
let range = {
from: 1.to: 5
};
// We want to use for.. Of traverses the range to get the natural numbers from 1 (from) to 5 (to)
// for(let num of range) {sol.log(num)
Copy the code
Range is an iterable object. Range is an iterable object. Also use for.. 1 -> 2 -> 3 -> 4 -> 5 That’s right. It’s bullshit now, because we didn’t do anything. It’s bullshit, right?
In order to make range an iterable, we need to understand the system preset variable symbol. iterator.
Symbol.iterator
So let’s look at what the description of this property looks like.
Object.getOwnPropertyDescriptor(Symbol.'iterator')
/ / {
// value: Symbol(Symbol.iterator),
// writable: false,
// enumerable: false,
// configurable: false
// }
Copy the code
The result shows that we cannot modify this property.
Iterator: [Symbol. Iterator] : [Symbol. Iterator] : [Symbol. Iterator] : [Symbol. Iterator: [Symbol.
let range = {
from: 1.to: 5
}
// 1. for.. The of loop first calls the [symbol.iterator] property on the object -- range[symbol.iterator](),
// Attribute range[symbol.iterator] is called "iterator generator" or "iterator generator"
range[Symbol.iterator] = function() {
// range[symbol.iterator]() returns an object containing the next method,
// This object is called "iteration object"
// 2. Of is completely dealing with the iterator
return {
current: this.from,
last: this.to,
// 3. The next method is called once through the "of" loop
next() {
// 4. From the next method, we can get the value of the current traversal and the done flag.
if (this.current <= this.last) {
return { done: false.value: this.current++ }
} else {
return { done: true }
}
}
}
}
Copy the code
for… The essence of the OF loop traversal is:
for.. of
The loop first invokes method properties on the object[Symbol.iterator]
–range[Symbol.iterator]()
, and you get a containnext
Method object.
- This includes
next
The object of the method is calledIterator objects - attribute
range[Symbol.iterator]
Referred to asIterator generatororIterating over objects generates functions
- Next,
for.. of
I’m completely dealing with this iterator, - Every time
for.. of
Once through the loop, it’s called oncenext
Method, - from
next
The object returned by the{ done: ... , value: ... }
), we can get the value of the current traversal (value
) and whether the traversal is over (done
).
After the above statement, we can also define an iterable as an object that produces an “iterable”. 支那
Iterate over the transformed object
Now iterate over the modified Range object.
let range = {
from: 1.to: 5
}
range[Symbol.iterator] = function() {... }for (let num of range) {
console.log(num) // 1, then 2, 3, 4, 5
}
Copy the code
Very cool, now you can iterate through the 5 numbers 1 -> 2 -> 3 -> 4 -> 5 in one go.
Manually traverse the iterable
For fun, let’s imitate for… Of executes the flow inside the loop. Write the logic for iterating through the iterable by hand.
The while loop is used here:
// The following is equivalent to
// for (let num of range) { console.log(num) };
let iterator = range[Symbol.iterator]();
while (true) {
let result = iterator.next();
// The done flag (true) terminates the loop and completes the loop
if (result.done) break;
// Otherwise, print the current traversal value
console.log(result.value);
}
Copy the code
- First, call manually
range[Symbol.iterator]
Method, get the iteration object - in
while
Inside the loop: - If the flag ends (
done
为true
), terminates the loop and completes the traversal - Otherwise, the value of the current loop is printed
Built-in iterables
We said that an iterable is not necessarily an array, but an array must be an iterable. We know from experience that arrays can be used with for… Of is iterated.
An array of
Traversing the symbols is for… The of loop iterated successfully. This is to be expected, but let’s see if the array object has a property called symbol. iterator 🕵️♂️
Sure enough!
string
Strings are also iterable. Here’s the evidence:
Look again for the symbol. iterator attribute.
The Map and Set
Maps and sets can also be used for… Of traversal. Without further examples, I will show the symbol.iterator properties that each of them deploys.
From the screenshot above, we can summarize a few things:
- The default iterator generator function for a Map object is
map.entries()
And the- The default iterator generator function for Set is
map.values()
For more information about traversal of Map and Set objects, see Traversal of Map and Set.
(after)