前言
JS的迭代器和生成器学习笔记
迭代器
定义迭代器对象
- 一个对象实现了next方法,并且next方法返回值是一个具有
done属性和value属性的对象,则这个对象就是一个迭代器对象
done:当前游标所指的元素是否是最后一个元素
true:是最后一个元素
false:不是最后一个元素
value:当前游标所指的元素值,如果是最后一个值通常定义为undefined
1 2 3 4 5
| const iterator = { next: function () { return { value: "value", done: false }; } }
|
- 在迭代器对象中实现return方法来立即终止迭代器
1 2 3 4 5 6 7 8
| const iterator = { next: function () { return { value: "value", done: false }; } return: function () { return { value: undefined, done: true }; } }
|
对象定义为可迭代对象
- 如果对象中定义类实例方法
[Symbol.iterator],则这个对象就是可迭代对象
[Symbol.iterator]方法必须返回一个迭代器才能将普通对象转换为可迭代对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const obj = { valueList: [], index: 0, [Symbol.iterator]: function () { return { next: () => { if (this.index < this.valueList.length) { return { value: this.valueList[this.index++], done: false }; } else { return { value: undefined, done: true }; } } }; } }
|
可迭代对象遍历数据
1 2 3
| for (let item of obj) { console.log(item); }
|
可迭代对象通过迭代器手动遍历数据
1 2 3 4 5 6
| let iterator = obj[Symbol.iterator](); let current = iterator.next(); while (!current.done) { console.log(current.value); current = iterator.next(); }
|
JS内置可迭代对象
1
| for (const item of [1, 2, 3]) {}
|
1
| for (const item of new Set([1, 2, 3])) {}
|
1 2 3
| function fn() { for (const item of arguments) {} }
|
可迭代对象可以使用的JS语法
for…of遍历
1
| for (const item of [1, 2, 3]) {}
|
展开语法
1
| const arr = [...[1, 2, 3]]
|
解构赋值
1
| const [a, b, c] = [1, 2, 3]
|
生成器语法
1 2 3
| function* fn() { yield* [1, 2, 3] }
|
可迭代对象可以作为参数传递的函数
部分构造方法
创建Map映射对象
1
| const map = new Map([...[1, 2, 3]]);
|
创建WeakMap映射对象
1
| const weakMap = new WeakMap([...[1, 2, 3]]);
|
创建Set集合对象
1
| const set = new Set([...[1, 2, 3]]);
|
创建WeakSet集合对象
1
| const weakSet = new WeakSet([...[1, 2, 3]]);
|
部分Promise类方法
Promise.all()
1 2 3 4
| Promise.all([ new Promise((resolve, reject) => {resolve()}), new Promise((resolve, reject) => {resolve()}), ])
|
Promise.rase()
1 2 3 4
| Promise.race([ new Promise((resolve, reject) => {resolve()}), new Promise((resolve, reject) => {resolve()}), ])
|
部分Array类方法
Array.from()
1
| const arr = Array.from([1, 2, 3]);
|
生成器
- 生成器是ES6新增的一种函数控制和函数使用的方案,它可以更加灵活地控制函数暂停执行和继续执行
定义生成器函数
yield关键字
- 生成器函数中使用
yield关键字定义函数执行的暂停位置
1 2 3 4 5 6
| function* fn() { console.log(1); console.log(2); yield; console.log(3); }
|
return关键字
1 2 3 4 5
| function* fn() { console.log(1); console.log(2); return; }
|
调用生成器函数返回生成器对象
- 生成器函数在调用后会返回一个生成器对象,而不是直接执行生成器函数体内的代码
1 2 3
| function* fn() {}
const generator = fn();
|
next方法
- 当第一次调用next方法时,从头执行代码
- 当第二次及之后调用next方法时,继续执行代码
- 每次执行到
yield关键字时会暂停执行,并立即返回一个结果对象,结果对象中包含value属性和done属性
- 当执行到
return关键字时,结果对象的done属性值立即变为true,且不会再执行后续代码
- 当没遇到
return关键字并执行完所有生成器定义的代码后(相当于return undefined),结果对象的done属性值变为true
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| function* fn() { console.log(1); console.log(2); yield; console.log(3); yield; console.log(4); return; console.log(5); }
const generator = fn();
console.log(generator.next());
console.log(generator.next());
console.log(generator.next());
console.log(generator.next());
|
1 2 3 4 5 6 7 8
| 1 2 { value: undefined, done: false } 3 { value: undefined, done: false } 4 { value: undefined, done: true } { value: undefined, done: true }
|
yield返回参数
1 2 3 4 5 6 7 8
| function* fn() { yield "value"; }
const generator = fn();
console.log(generator.next()); console.log(generator.next());
|
return返回参数
1 2 3 4 5 6 7 8
| function* fn() { return "value"; }
const generator = fn();
console.log(generator.next()); console.log(generator.next());
|
生成器对象调用next方法时传递参数
第一次调用next方法时
1 2 3 4 5 6 7 8 9
| function* fn() { const key = yield; console.log(key); }
const generator = fn("value");
generator.next(); generator.next();
|
第二次及之后调用next方法时
1 2 3 4 5 6 7 8 9 10 11
| function* fn() { yield; const key = yield; console.log(key); }
const generator = fn();
generator.next(); generator.next("value"); generator.next();
|
yield返回参数与生成器对象调用next方法时传递参数
第一次调用next方法时
1 2 3 4 5 6 7 8 9
| function* fn() { const key = yield "value2"; console.log(key); }
const generator = fn("value1");
console.log(generator.next()); console.log(generator.next());
|
第二次及之后调用next方法时
1 2 3 4 5 6 7 8 9 10 11
| function* fn() { yield; const key = yield "value2"; console.log(key); }
const generator = fn();
console.log(generator.next()); console.log(generator.next()); console.log(generator.next());
|
return方法
- 当调用return方法时,并立即返回一个结果对象,结果对象的
done属性值立即变为true,且不会再执行后续代码
1 2 3 4 5 6 7
| function* fn() { yield; }
const generator = fn();
console.log(generator.return());
|
return方法传递参数
1 2 3 4 5 6 7
| function* fn() { yield; }
const generator = fn();
console.log(generator.return("value"));
|
throw方法
1 2 3 4 5 6 7 8 9 10 11
| function* fn() { try { yield; } catch (e) { console.log(e); } }
const generator = fn();
console.log(generator.throw(new Error("error")));
|
生成器的实质
- 生成器的实质是一个特殊的迭代器,可以通过定义迭代器对象实现生成器的功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function* fn() { console.log(1); console.log(2); yield "value1"; console.log(3); return "value2"; }
const generator = fn();
const result1 = generator.next(); console.log(result1);
const result2 = generator.next(); console.log(result2);
const result3 = generator.next(); console.log(result3);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| const obj = { fnList: [ function () { console.log(1); console.log(2); }, function () { console.log(3); }, ], index: 0, [Symbol.iterator]: function () { return { next: () => { if (this.index < this.fnList.length - 1) { this.fnList[this.index](); this.index += 1; return { value: "value1", done: false }; } else if (this.index === this.fnList.length - 1) { this.fnList[this.index](); this.index += 1; return { value: "value2", done: true }; } else { return { value: undefined, done: true }; } } }; } }
let iterator = obj[Symbol.iterator]();
const result1 = iterator.next(); console.log(result1);
const result2 = iterator.next(); console.log(result2);
const result3 = iterator.next(); console.log(result3);
|
通过yield*迭代可迭代对象
1 2 3 4 5
| arr = [1, 2, 3];
for (let i of arr) { console.log(i); }
|
1 2 3 4 5 6 7 8 9 10 11
| arr = [1, 2, 3];
function* fn(arr) { yield* arr; }
const generator = fn(arr);
console.log(generator.next().value); console.log(generator.next().value); console.log(generator.next().value);
|
通过yield*定义对象的[Symbol.iterator]方法
*[Symbol.iterator]就是将[Symbol.iterator]方法定义为生成器函数
1 2 3 4 5 6
| const obj = { valueList: [], *[Symbol.iterator]: function () { yield* this.valueList; } }
|
完成