-
-
Save prof3ssorSt3v3/ec8fe7f28ecaa94bef793709d1b83b2f to your computer and use it in GitHub Desktop.
/**************************************** | |
ES6 Iterators and Generators | |
Arrays, Strings, Maps, Sets, NodeLists - built-in iterators | |
{Object} => Iterator => Generator | |
****************************************/ | |
let log = console.log; | |
let characters = ['Finn','Poe', 'Rey', 'Kylo', 'Luke', 'Leia'] | |
function* genny(){ | |
let i = 0; | |
yield characters[i]; | |
i++; | |
yield characters[i]; | |
i++; | |
yield characters[i]; | |
i++; | |
yield characters[i]; | |
i++; | |
yield characters[i]; | |
i++; | |
yield characters[i]; | |
i++; | |
yield characters[i]; | |
i++; | |
yield characters[i]; | |
} | |
//let iter = genny(); | |
//log(iter) | |
//log(iter.next()); | |
//log(iter.next()); | |
//log(iter.next()); | |
//log(iter.next()); | |
//log(iter.next()); | |
//log(iter.next()); | |
//log(iter.next()); | |
//log(iter.next()); | |
//log(iter.next()); | |
let starwars8 = { | |
title: 'The Last Jedi', | |
director: 'Rian Johnson', | |
year: 2017, | |
boxOffice: '1.3B' | |
} | |
let count = -1; | |
let SW8 = { | |
[Symbol.iterator]: function(obj){ | |
return { | |
next: ()=>{ | |
count++; | |
switch(count) { | |
case 0: | |
return { | |
value: obj.title, | |
done: false} | |
case 1: | |
return { | |
value: obj.year, | |
done: false | |
} | |
case 2: | |
return { | |
value: obj.director, | |
done: false | |
} | |
case 3 : | |
return { value: undefined, done: true} | |
default: | |
return { value: undefined, done: true} | |
} | |
} | |
} | |
} | |
} | |
let data = SW8[Symbol.iterator](starwars8); | |
log( data.next() ); | |
log( data.next() ); | |
log( data.next() ); | |
log( data.next() ); | |
log( data.next() ); | |
// | |
//for(let p of starwars8){ | |
// for of loops are using the .next( ) method behind the scenes | |
//} |
/** | |
This second version has two objects - `Obj1` and `Obj2` | |
The generator `myGenerator`, is put in the prototype chain for both objects | |
This way we can call the [Symbol.iterator] method on each object to give them each their own iterator. | |
The new version of the Iterator also checks for the existence of the property, to make this more generic. It will | |
display a message about missing properties. | |
**/ | |
let log = console.log; | |
let Obj1 = { | |
title: 'The Last Jedi', | |
director: 'Rian Johnson', | |
year: 2017, | |
}; | |
let Obj2 = { | |
title: 'The Hobbit', | |
director: 'Peter Jackson', | |
boxOffice: '1.017B', | |
}; | |
let myGenerator = { | |
[Symbol.iterator]: function () { | |
let count = -1; //reset the count | |
return { | |
next: () => { | |
count++; | |
switch (count) { | |
case 0: | |
return { | |
value: this.title ? this.title : 'No title property', | |
done: false, | |
}; | |
case 1: | |
return { | |
value: this.year ? this.year : 'No year property', | |
done: false, | |
}; | |
case 2: | |
return { | |
value: this.director ? this.director : 'No director property', | |
done: false, | |
}; | |
default: | |
return { value: undefined, done: true }; | |
} | |
}, | |
}; | |
}, | |
}; | |
Object.setPrototypeOf(Obj1, myGenerator); | |
Object.setPrototypeOf(Obj2, myGenerator); | |
let data1 = Obj1[Symbol.iterator](); //create the iterator for Obj1 | |
//this sets count to -1 | |
for (let prop of Obj1) { | |
log(prop); | |
} | |
log('\n\n'); | |
let data2 = Obj2[Symbol.iterator](); //create the iterator for Obj2 | |
//this sets count to -1 again | |
for (let prop of Obj2) { | |
log(prop); | |
} |
thanks for your comment. I already discussed these changes in the comments with the original commenter who asked the original question that prompted the second script.
I have updated them here now as well.
Thank you Sir,
If I may, asking specific to the use of let in , let log = console.log. why did you use let instead of const? Since this assignment would rather be a permanent one, throughout the script?
You can use const if you like. I'm not hung up on forcing absolute usage of let or const, as long as it's not var I'm happy.
Hi Steve!
Quick question regarding creating the iterators for Obj1 and Obj2 ('data1' and 'data2' respectively).
I'm unsure of what's happening "behind the scenes" inside the for/of loops when we create each object's iterators in those variables.
//From your code snippet:
let data1 = Obj1Symbol.iterator;
for (let prop of Obj1){
log(prop);
}
// Is this the equivalent of what's happening with the 'data1' variable behind the scenes in that for/of loop?
let data1 = Obj1Symbol.iterator;
for (let a = 0; a < Object.keys(Obj1).length; a++){
log(data1.next())
}
Thanks for all your hard work!
-J
Basically yes.
It is also checking to see if done === false each time after calling next()
Hello Sir,
just few modifications :
code here
https://gist.github.com/dinkarinjosh/6afbd4afaaab04463b7ec937c0dc56d2