ES6 解释生成器函数
ES6 引入了一个新概念叫做生成器(或生成器函数)。它为迭代器和函数的使用提供了一种新的方式。ES6生成器是一种特殊类型的函数,它可以在中间或多次中断,并在以后继续执行。在标准函数中,控制权一直留在被调用函数那里,直到它返回,但是ES6的生成器函数允许调用函数来控制被调用函数的执行。
生成器和普通函数之间的区别是:
- 当调用一个生成器时,它的代码不会运行。相反,它返回一个特殊的对象叫做“生成器对象”来管理执行过程。
- 生成器函数可以在任何时候将控制权返回给调用者。
- 生成器可以根据需求返回(或 yield)多个值,而普通函数则不行。
语法: 生成器函数和普通函数具有相似的语法。唯一的区别是,生成器函数在关键字function之后用一个星号(*)来表示。
function *myfunction() { }
Yield operator :
在yield语句中,函数执行被暂停并返回一个值给调用者。在此期间,足够的状态被保留以便函数能够在离开时恢复执行。在上一次yield运行之后,函数会立即在被恢复的位置继续执行。使用这个函数可以产生一系列的值。
JavaScript next方法 :
next()方法在接收到一个参数时会继续执行生成器函数,使用next()方法的参数替换掉生成器函数中被暂停执行的表达式。next()方法返回的对象始终具有两个属性。
- value-被yield的值就是这个值。
- done-函数的完成状态可以用布尔值true来表示。否则,它返回false。
示例:
在这个示例中,我们使用一个生成器函数生成3个数字,并连续4次调用生成器函数来查看实际输出。最后,我们发现当我们第四次调用生成器函数时,它的值为undefined,而done属性为true。因为在这个调用时,生成器函数已经完成了三个连续数字的生成,所以当我们第四次调用函数时,它不会返回值,并将done状态更新为true,这意味着第四次调用时没有值可以生成。
Javascript
function* generator() {
yield 1;
yield 2;
yield 3;
}
let obj = generator();
console.log(obj.next());
console.log(obj.next());
console.log(obj.next());
console.log(obj.next());
输出:
{
done: false,
value: 1
}
{
done: false,
value: 2
}
{
done: false,
value: 3
}
{
done: true,
value: undefined
}
生成器函数中的return语句: return语句将指定的值发送回调用者。它结束函数调用的执行并将结果返回给调用者。return语句后定义的语句不会在函数中执行。因此,return语句应该放在函数末尾。
示例2: 在第3行我们使用了return语句来展示生成器函数中的return如何工作。通常当我们在return语句后写任何语句会导致错误,但是在这里,当在return语句后写任何yield语句时,不会产生错误,除了显示生成器函数调用已结束,这意味着没有进一步的步骤可以生成数字。
JavaScript
function* generator() {
yield 1;
yield 2;
return 3;
yield 4;
}
let obj = generator();
console.log(obj.next());
console.log(obj.next());
console.log(obj.next());
console.log(obj.next());
输出:
{
done: false,
value: 1
}
{
done: false,
value: 2
}
{
done: true,
value: 3
}
{
done: true,
value: undefined
}
在另一个生成器函数中调用生成器函数以生成一个函数: 我们可以通过使用yield*运算符(或语句)在另一个生成器函数内部调用一个生成器函数。
示例3: 在这个示例中,我们使用yield*语句在另一个生成器函数内部调用一个生成器函数。有两个生成器函数,一个名为generator,另一个名为myfunction,两个函数都是带参数的函数。在这里,我们通过调用生成器函数并传递参数来创建一个生成器函数的对象,并在generator函数内部使用yield*运算符调用myfunction生成器函数。
JavaScript
function* myfunction(k) {
yield k + 1;
yield k + 2;
yield k + 3;
}
function* generator(i) {
yield i;
yield* myfunction(i);
yield i + 5;
}
let obj = generator(6);
console.log(obj.next());
console.log(obj.next());
console.log(obj.next());
console.log(obj.next());
console.log(obj.next());
console.log(obj.next());
输出:
{
done: false,
value: 6
}
{
done: false,
value: 7
}
{
done: false,
value: 8
}
{
done: false,
value: 9
}
{
done: false,
value: 11
}
{
done: true,
value: undefined
}
极客教程