生成器
生成器声明
生成器函数声明
function* generation(){
}
生成器函数表达式
let generatorFn = function * (){
}
作为对象字面量方法的生成器函数
let foo={
* generatorFn(){
}
}
作为类实例方法的生成器函数
class Foo{
* generatorFn(){
}
}
调用生成器函数
调用生成器函数会产生一个生成器对象。生成器对象一开始处于暂停执行的状态。与迭代器相似,生成器对象也实现了Iterator
接口,因此具有next()
方法。调用这个方法会让生成器开始或恢复执行。
function *generatorFn(){
}
const g = generatorFn();
console.log(g);
console.log(g.next());
Next()
方法的返回值类似于迭代器,有一个done
属性和一个value
实行。函数体为空的生成器函数中间不会停留,调用一次next()
就会让生成器到达done:true
状态
其中value
属性是生气函数的返回值,默认值是undefined
,可以通过生成器函数的返回值指定:
function * generatorFn(){
return 'foo';
}
let generatorObject = generatorFn();
console.log(generatorObject);
console.log(generatorObject.next()); //{done:true,value:'foo'};
通过yield中断执行
yield
关键字可以让生成器停止和开始执行。遇到这个关键字后,执行会停止,函数作用域的状态会被保留。停止执行的生成器函数只能通过在生成器对象上调用next()
方法来恢复执行。
function* generatorFn(){
yield;
}
let generatorObject = generatorFn();
console.log(generatorObject.next());
console.log(generatorObject.next());Function* generatorFn()
此时的yield
关键字有点像函数的中间返回语句,它生成的值会出现在next()
方法返回的对象里。通过yield
关键字退出的生成器啊还是农户会处在done:false
状态。通过return
关键字退出的生成器函数会处于done:true
状态。
function* generatorFn(){
yield 'foo';
yield 'bar';
return 'baz';
}
let generatorObject = generatorFn();
console.log(generatorObject.next());
console.log(generatorObject.next());
console.log(generatorObject.next());
生成器函数内部的执行流程会针对每个生成器对象区分作用域。在一个生成器对象上调用next()
不会影响其他生成器。
function* generatorFn(){
yield 'foo';
yield 'bar';
return 'baz';
}
for( const x of generatorFn()){
console.log(x);
}
可以使用星号增强yield的行为
让它能够迭代一个可迭代对象,从而一次产出一个值。
//等价的generatorFn();
function * generatorFn() {
for(const x of [1,2,3]){
yield x;
}
}
function generatorFn(){
yield *[1,2,3];
}
因为yield*
实际上只是将一个可迭代对象序列化为一连串可以单独产出的值,所以这跟把yield
放到一个循环里没什么不同。
使用yield*实现递归
function * nTimes(n){
if(n>0){
yield* nTimes(n-1);
yield n-1;
}
}
for (const x of nTimes(3)){
console.log(x);
}
此例中,每个生成器首先都会从新创建的生成器对象产出每个值,然后再产出一个整数。结果就是生成器函数会递归地减少计数器值,并实例化另一个生成器对象。
生成器作为默认迭代器
class Foo{
constructor() {
this.values=[1,2,3];
}
* [Symbol.iterator](){
yield *this.values;
}
}
let ei=new Foo();
for(let i of ei){
console.log(i);
}
- 本文链接:https://archer-lan.github.io/2023/11/20/JS-%E7%94%9F%E6%88%90%E5%99%A8/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。