Time: 2021-10-8 Author: Xiaoming Nuggets first article
In the js for… of.. This method, like when I first contacted him, I often put him and for… in… Muck it up, muck it up and we’ll tell you about this error as we go through the object
Uncaught TypeError: a is not iterable at <anonymous>:1:16
Copy the code
Iterable protocol: Iterable protocol: iterable protocol: iterable protocol: iterable protocol: iterable protocol
To be an iterable, you have to implement the @@iterator method. Obviously, an object we normally declare is not implemented. We declare an array, and when we look at its prototype object, we see the Symbol.
const arr=[1.2.3]
arr.__proto__
Copy the code
Which means js’s built-in array is the default realized his iteration method, so the array can be through the for… of.. If we want our objects to be iterated through by “for”, we will always use “for”. of.. And for… In the mixed.. Let’s take a look atThe iteratorIs defined as follows:
We can implement an iterator that returns an object with a next method that returns value and done. Next returns value and done. Done is true if it is the last one
1. Custom iterators
const obj={a:1.b:2}// Set an object first
function myIterator(){ // Implement iterators
let self=this
let index=0; // Use closures to record subscripts
const keys=Object.keys(self);
return {
next(){ The next method returns value and done
if(index<keys.length){
return {value:self[keys[index++]],done:false}}return {value:undefined.done:true}}}}// Define the Symbol. Iterator method
obj[Symbol.iterator]=myIterator;
for(const i of obj){
console.log(i)
}
Copy the code
The above method shows that our object can use for… by using a custom iterator method. of.. Let’s go over it.
2. Define generation iterators by using generators
Generater: generater: generater: generater: generater: generater: generater: generater: generater: generater: generater: generater: generater
First of all, we literally know that a generator is a function, and this function isfunction*
The next method of the iterator returns value and done. The next method of the iterator returns value and done.
Generator functions provide a powerful alternative: they allow you to define a function that contains its own iterative algorithm while maintaining its own state automatically. When initially called, Generator functions do not execute any code, but return an iterator called Generator. When a value is consumed by calling the Generator’s next method, the Generator function executes until the yield keyword is reached.
At this point we use yield as another keyword. We can see that generator functions maintain their own state, as we did in the above custom way by setting the index closure to maintain our state in the next function. Let’s look at an example to see what generator functions do.
function* myIterator(){
yield 1;
yield 2;
}
const i=myIterator();
i.next();//{value:1,done:false}
i.next();//{value:2,done:true}
Copy the code
If we set a generator function to execute it and it returns an iterator, the iterator automatically has a next method, and value is the yield value. This means that the function maintains our state internally, and we don’t need to manually maintain it. Each time we execute the next method, it stops at the next yield method. We can change the above method to use generators to implement @@iterator
const obj={a:1.b:2}
function* myIterator(){
const self=this;
for(const key of Object.keys(self)){
yield [keys,self[key]];
}
}
obj[Symbol.iterator]=myIterator
for(const a of obj){
console.log(a);
}
// 'a' 1
// 'b' 2
Copy the code