Iterators and Generators
For Of Iterables
Use for...of with a custom iterable.
for-of-iterable
`for...of` reads from any object that provides `Symbol.iterator`. The loop keeps asking for the next value until the iterator is done.
For Of Iterables
for_of_iterable.js
Replay: real traced execution (multi-file project)
const stop = 3;
const values = [];
const range = {
[Symbol.iterator]() {
let current = 1;
return {
next() {
if (current <= stop) {
const value = current;
current = current + 1;
return { value, done: false };
}
return { value: undefined, done: true };
},
};
},
};
for (const value of range) {
values.push(value * 10);
}
console.log("stop=" + stop);
console.log("scaled=" + values.join("-"));
const stop = 2;
const values = [];
const range = {
[Symbol.iterator]() {
let current = 1;
return {
next() {
if (current <= stop) {
const value = current;
current = current + 1;
return { value, done: false };
}
return { value: undefined, done: true };
},
};
},
};
for (const value of range) {
values.push(value * 10);
}
console.log("stop=" + stop);
console.log("scaled=" + values.join("-"));
const stop = 4;
const values = [];
const range = {
[Symbol.iterator]() {
let current = 1;
return {
next() {
if (current <= stop) {
const value = current;
current = current + 1;
return { value, done: false };
}
return { value: undefined, done: true };
},
};
},
};
for (const value of range) {
values.push(value * 10);
}
console.log("stop=" + stop);
console.log("scaled=" + values.join("-"));
stop ← 3
1const stop→ 3 = 3; //@stop=2, 42const values = [];values ← (empty)
1const stop = 3; //@stop=2, 42const values→ (empty) = [];range ← [object Object]
1const stop = 3; //@stop=2, 42const values = [];34const range→ [object Object] = {5 [Symbol.iterator]() {6 let current = 1;7 return {8 next() {9 if (current <= stop) {10 const value = current;11 current = current + 1;12 return { value, done: false };13 }14 return { value: undefined, done: true };15 },16 };17 },18};values ← 10, value ← 1
20for (const value of range) {21 values.push(value→ 1 * 10);22}values this step(empty) → 10valuesvalues ← 10,20, value ← 2
20for (const value of range) {21 values.push(value→ 2 * 10);22}values this step10 → 10,20valuesvalues ← 10,20,30, value ← 3
20for (const value of range) {21 values.push(value→ 3 * 10);22}values this step10,20 → 10,20,30valuesconsole.log("stop=" + stop);
21 values.push(value * 10);22}2324console.log("stop=" + stop3);25console.log("scaled=" + values.join("-"));outputstop=3console.log("scaled=" + values.join("-"));
24console.log("stop=" + stop);25console.log("scaled=" + values10,20,30.join("-"));outputscaled=10-20-30
stop ← 2
1const stop→ 2 = 2;2const values = [];values ← (empty)
1const stop = 2;2const values→ (empty) = [];range ← [object Object]
1const stop = 2;2const values = [];34const range→ [object Object] = {5 [Symbol.iterator]() {6 let current = 1;7 return {8 next() {9 if (current <= stop) {10 const value = current;11 current = current + 1;12 return { value, done: false };13 }14 return { value: undefined, done: true };15 },16 };17 },18};values ← 10, value ← 1
20for (const value of range) {21 values.push(value→ 1 * 10);22}values this step(empty) → 10valuesvalues ← 10,20, value ← 2
20for (const value of range) {21 values.push(value→ 2 * 10);22}values this step10 → 10,20valuesconsole.log("stop=" + stop);
21 values.push(value * 10);22}2324console.log("stop=" + stop2);25console.log("scaled=" + values.join("-"));outputstop=2console.log("scaled=" + values.join("-"));
24console.log("stop=" + stop);25console.log("scaled=" + values10,20.join("-"));outputscaled=10-20
stop ← 4
1const stop→ 4 = 4;2const values = [];values ← (empty)
1const stop = 4;2const values→ (empty) = [];range ← [object Object]
1const stop = 4;2const values = [];34const range→ [object Object] = {5 [Symbol.iterator]() {6 let current = 1;7 return {8 next() {9 if (current <= stop) {10 const value = current;11 current = current + 1;12 return { value, done: false };13 }14 return { value: undefined, done: true };15 },16 };17 },18};values ← 10, value ← 1
20for (const value of range) {21 values.push(value→ 1 * 10);22}values this step(empty) → 10valuesvalues ← 10,20, value ← 2
20for (const value of range) {21 values.push(value→ 2 * 10);22}values this step10 → 10,20valuesvalues ← 10,20,30, value ← 3
20for (const value of range) {21 values.push(value→ 3 * 10);22}values this step10,20 → 10,20,30valuesvalues ← 10,20,30,40, value ← 4
20for (const value of range) {21 values.push(value→ 4 * 10);22}values this step10,20,30 → 10,20,30,40valuesconsole.log("stop=" + stop);
21 values.push(value * 10);22}2324console.log("stop=" + stop4);25console.log("scaled=" + values.join("-"));outputstop=4console.log("scaled=" + values.join("-"));
24console.log("stop=" + stop);25console.log("scaled=" + values10,20,30,40.join("-"));outputscaled=10-20-30-40