JavaScript 生成器(Generator)详解:语法、调用与循环应用

作者:资源驿站时间:2026-10-24 07:39:06浏览:301

本文深入解析 JavaScript 生成器(Generator)的核心机制。通过 function* 定义生成器函数,利用 yield 关键字实现代码暂停与恢复。文章演示了如何调用生成器对象获取值,并展示其在 for...of 循环中的自动迭代用法,帮助开发者掌握异步编程与无限序列处理技巧。

什么是生成器?

生成器本质上是函数内部的一段特殊代码逻辑。

  • 当执行到返回值后,生成器会自动暂停执行。
  • 此时,调用程序可以请求取消暂停,并获取下一个值。

这种“返回”机制不同于传统的函数 return 语句,因此被赋予了一个专用术语——yield。

不同编程语言中生成器的语法存在差异。JavaScript 的生成器语法与 PHP 类似,但细节区别显著。若期望两者行为完全一致,可能会产生混淆。

在 JavaScript 中使用生成器,需遵循以下步骤:

  • 定义专用的生成器函数。
  • 调用该函数以创建一个生成器对象实例。
  • 在循环中使用该生成器对象,或直接调用其 next 方法。

我们将通过以下简单程序作为起点,逐步执行上述每个步骤:


// File: sample-program.js
function *createGenerator() {
 for(let i=0;i<20;i++) {
 yield i
 }
}

const generator = createGenerator()

console.log(generator.next())
console.log(generator.next())

运行这段代码,将得到如下输出结果:

$ node sample-program.js

{ value: 0, done: false } { value: 1, done: false }

接下来解释该程序的工作原理。

生成器函数

首先,代码中定义了生成器函数:


function* createGenerator() {
 for(let i=0;i<20;i++) {
 yield i
 }
}

function 关键字后的 * 符号表明这是一个生成器函数。以下写法均属于有效的生成器函数定义方式。


function*createGenerator
function* createGenerator
function *createGenerator

注意,* 并非函数名的一部分,而是 function* 整体符号用于定义生成器。

调用生成器函数

定义生成器函数后,我们调用它并赋予结果一个变量名。


// 注意:当调用时,没有 *。 * 不是函数名称的一部分
// `function *` 是用于定义生成器函数的符号
const generator = createGenerator()

需注意:createGenerator 函数本身不返回传统意义上的值。生成器函数被调用时,总是返回一个实例化的 Generator 对象。

该生成器对象包含一个 next 方法。调用 next 会在生成器函数内部执行代码。


function* createGenerator() {
 for(let i=0;i<20;i++) {
  yield i
 }
}

这一点至关重要,需再次强调:直接调用生成器函数并不会执行其内部代码,而是创建生成器对象。必须在该对象上调用 next 方法,才会触发生成器函数内的代码执行。

首次调用生成器对象的 next 时,内部代码会一直执行,直到遇到 yield 语句。执行到 yield 后,JavaScript 会暂停代码执行,next 返回一个对象,其中包含 yield 语句中的值。

当第二次(或第三次、第四次等)调用 next 时,代码会从上次中断处取消暂停并继续运行。变量(如本例中的 i)会保持其值。当代码再次遇到 yield 语句时,函数会再次暂停,并返回包含 yield 值的对象。

这就是我们需要调用两次 next 的原因。


console.log(generator.next())
console.log(generator.next())

执行后将得到以下输出:

{ value: 0, done: false } { value: 1, done: false }

当生成器函数中的代码执行完毕后,后续对 next 的任何调用都会返回一个对象,其 value 为 undefined,且 done 属性设为 true。


{ value: undefined, done: true }

生成器和循环

虽然可以手动在生成器对象上调用 next,但主要用途是在循环中使用。查看以下稍作修改的程序:


// File: sample-program.js
@highlightsyntax@jscript
function *createGenerator() {
 for(let i=0;i<5;i++) {
 yield i
 }
}

const generator = createGenerator()
for(const value of generator) {
 console.log(value)
}

当在 for...of 循环中使用生成器对象时,每次循环迭代都会在生成器对象上调用 next,并将产生的值赋给变量(即上面的 value)。运行该程序将输出以下内容:

$ node sample-program.js 0 1 2 3 4

在下一篇文章中,我们将深入探讨 for...of 循环,并探索如何为 JavaScript 提供一种内置方法来遍历任何对象。

总结

到此这篇关于 JavaScript 生成器(Generator)的文章就介绍到这了,更多相关 JavaScript 生成器(Generator)内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

作者最新文章