This is the fifth day of my participation in the August More text Challenge. For details, see:August is more challenging
The Iterator Iterator
Iterator is a new set of syntax in ES6, but there is no Iterator class in ES6. An Iterator is a mechanism (interface) that provides a uniform access mechanism for various data structures. Any data structure can be traversed by deploying an Iterator interface, processing all members of that data structure in turn. Features of iterators:
- Have the next method to iterate over/iterate over members of the data structure once
- Done: false, value: XXX}
- Done Indicates whether the traversal is complete
- Value: indicates the result of the current traversal
// Simulate the traverser
class Iterator{
constructor(assemble){
//assemble: The number is the index level, with length attribute.
this.assemble = assemble;
this.index = 0;
}
next(){
if(this.index > this.assemble.length){
return {done: true.value:undefined};// Indicates that the traversal is complete
}
return{
done: false.value: this.assemble[this.index++]; }}}Copy the code
Although there is no Iterator class in ES6, some data structures already implement Iterator’s iterable specification by default. All data structures (values) that have a Symbol. Iterator attribute are iterable and can be traversed based on a for of loop. Objects do not have a Symbol. Iterator property by default, so objects belong to non-traversable data structures. Common data structures are:
- An array of
- Arguments, NodeList, HTMLCllection…
- String
- Set
- Map
- generator object
For of is internally iterated according to iterator.next, so only data structures that have Symbol
You can use for of to iterate
let arr = [1.2.3.4];
for(let item of arr){
console.log(item);
}
// Output 1, 2, 3, 4
Copy the code
Make objects iterable
let obj = {
0: 10.1: 20.2: 30[Symbol.iterator]:function(){
let self = this, index = 1;
return{
next(){
if(index > self.length){
return {done: true.value:undefined};// Indicates that the traversal is complete
}
return{
done: false.value: self[index++];
}
}
}
}
}
Copy the code
The Generator Generator
A generator object is returned by a generator function, and it conforms to the iterable specification and is iterable. Generator functions are defined by function*, for example function* fn(){}
- Proto__ === function.prototype
- Generator function is GeneratorFunction instance, generator function. __ proto__ = = = GeneratorFunction. The prototype; GeneratorFunction.prototype.__ proto__ === Function.prototype
- The generator function has the IsGenerator property with the value true
- The this inside the generator function does not point to an instance of the generator, but to the window
- Generator functions are not allowed to be new, and instances are created when called as normal functions
- As with normal function calls, the code inside is not executed
- The code is executed only on subsequent calls to Next, and ends every time next is executed with a yield
- The result returned each time conforms to the iterator specification
- {done: true/false, value:yield;}
function* func(){}
let itor = func();// The code inside the function is not executed until a subsequent call to next
({}).toString.call(func);//[object GeneratorFunction]
({}).toString.call(itor);//[object Generator];
Copy the code
function* func(){
console.log('A');
yield 1;
console.log('B');
yield 2;
console.log('C');
yield 3;
console.log('D');
yield 4;
}
let itor = func();// Internal code will not be executed
console.log(itor.next());//{done:false, value:1}
console.log(itor.next());//{done:false, value:2}
console.log(itor.next());//{done:false, value:3}
console.log(itor.next());//{done:true, value:4}
Copy the code
The next pass parameter can be passed as the result of the last yield, but the yield is followed by the value after each next
function* func(){
let x = yield 1;
console.log(x);
}
let itor = func();
console.log(itor.next(10));// Return value: {done:false, value:1
console.log(itor.next());// Start execution where the last yield ended, i.e. let x = 10(the value passed last next)
/ / the result output undefined {done: true, value: undefined}
Copy the code
If you use yield* to implement a generator within a generator, when you call next, you will not continue until the generator following yield* has iterated over
function* func1(){
yield 1;
yield 2;
}
function* func2(){
yield 3;
yield* func1();
yield 4;
}
console.log(itor.next());//{done:false, value: 3}
console.log(itor.next());//{done:false, value: 1}
console.log(itor.next());//{done:false, value: 2}
console.log(itor.next());//{done:false, value: 4}
console.log(itor.next());//{done:true, value: undefined}
Copy the code
So that’s iterators and generators in JavaScript.