For of Loop
Usually use the forEach loop, but one reason to use the ForOfLoop is because of the Generators
const colours = ['red','blue',...]
for (let color of colours) {
console.log(color);
}
Generators
What is a generator?
A generator is a function that can be entered and exit multiple time. Normally when we call a function, it runs and returns some value, and its over. But a generator, we can run some code, return a value, and go right back into the function at the same place we left it.
To create a generato, add * at the end of function
function* shopping() {
//stuff on the sidewalk
//walking down the sidewalk
//go into the store with cash (Indicates that we are transitioning from being inside the generator to outside
const stuffFromStore = yield 'cash'; //Transition with some cash
//walking back home
return stuffFromStore;
}
//stuff in the store
const gen = shopping(); //When we first call our generator shopping, nothing happens, does not invoke any code
//Only when we call gen.next do we actually leave the house
gen.next(); //leaving our house -> {"value":"cash","done": false}
//walked into the store
//walking up and down the aisles
//purchases our stuff
//When we call gen.next now, we got this transition to go back to the sidewalk, so back to the generator
//Re-enter the generator at the 'yield' statement
//You can imagine yield 'cash' is 'groceries'
gen.next('groceries'); //leaving the store with groceries-> {"value":"groceries","done": true}
Iteration with generators.
function* colours() {
yield 'red';
yield 'blue';
yield 'green';
}
const myColours = [];
for (let color of colours()){ //With for of loop, no need to use gen.next
myColors.push(color);
}
myColors;
Why use generator?
const engineeringTeam = {
size: 3,
department: 'Engineering',
lead: 'Jill',
manager: 'Alex',
engineer: 'Dave'
}
//Problem:
//I want to use Generator to figure out how to iterate through this object
//Notice, we can't figure out all the keys and arbitrary iterate through it as we only want to iterate through employees
//Not size, department
function* TeamIterator(team) {
yield team.lead;
yield team.manager;
yield.team.engineer;
}
const names = [];
for (let name of TeamIterator(engineeringTeam)){
name.push(name);
}
console.log(names); -> ["Jill", "Alex", "Dave"]
Generator delegation
(Engineering Team)
|
|
(Lead) (Manager) (Engineer) (Testing Team)
|
|
(Lead) (Tester)
//Problem
//I want to iterate through both team to find the employee names
const engineeringTeam = {
size: 3,
department: 'Engineering',
lead: 'Jill',
manager: 'Alex',
engineer: 'Dave',
testingTeam: testingTeam
}
const testingTeam = {
lead: 'Amanda',
tester: 'Bill'
}
//We now need to iterate through the testing team as well
//Two ways to do it: we can do: yield.testingTeam.lead; yield.testingTeam.tester
//Or we can create a TestingTeamGenerator
function* TeamIterator(team) {
yield team.lead;
yield team.manager;
yield.team.engineer;
const testingTeamGenerator = TestingTeamIterator(team.testingTeam);
yield* testingTeamGenerator; //yield * Can be read as i am currently in a generator but i got another generator that has a few yield statements
}
function* TestingTeamIterator(team) {
yield team.lead;
yield team.tester;
}
const names = [];
for (let name of TeamIterator(engineeringTeam)){
name.push(name);
}
console.log(names); -> ["Jill", "Alex", "Dave", "Amanda", "Bill"]
Generators with Symbol.iterator
Symbol iterator is a tool that teaches object how to respond to the ForOfLoop
const testingTeam = {
lead: 'Amanda',
tester: 'Bill'
//Special key:
[Symbol.iterator]: function* () {
yield team.lead;
yield team.tester;
}
};
const engineeringTeam = {
size: 3,
department: 'Engineering',
lead: 'Jill',
manager: 'Alex',
engineer: 'Dave',
testingTeam: testingTeam,
[Symbol.iterator]: function* () {
yield team.lead;
yield team.manager;
yield.team.engineer;
yield* team.testingTeam;
}
};
const names = [];
for (let name of engineeringTeam){
name.push(name);
}
console.log(names); -> ["Jill", "Alex", "Dave", "Amanda", "Bill"]