如何学习JavaScript中的迭代器与生成器_JavaScript的yield关键字如何工作

发布时间 - 2026-01-11 00:00:00    点击率:
yield仅在function生成器函数中有效,配合迭代器协议通过next()控制暂停/恢复执行,返回{value, done}对象;不可用于普通、箭头或async函数(除非async function);自动生成[Symbol.iterator],支持for...of等语法糖。

JavaScript 中的 yield 关键字本身不“工作”,它只在 function*(生成器函数)内部起作用,且必须配合迭代器协议才能产生实际效果。

生成器函数返回的是迭代器对象,不是执行结果

调用 function* 不会立即运行函数体,而是返回一个实现了 next() 方法的迭代器对象。每次调用 iterator.next(),函数才从上次暂停处继续执行,直到下一个 yieldreturn

  • yield 表达式会暂停执行,并把右侧值作为 { value: ..., done: false }value 返回
  • 再次调用 next() 时,函数从 yield 后恢复,上一次 yield 表达式的返回值是本次 next(arg) 传入的 arg
  • 函数结束或遇到 return 时,done 变为 truevalue 是返回值(或 undefined
function* countdown(n) {
  while (n > 0) {
    yield n;
    n--;
  }
  return 'done';
}

const iter = countdown(3); console.log(iter.next()); // { value: 3, done: false } console.log(iter.next()); // { value: 2, done: false } console.log(iter.next()); // { value: 1, done: false } console.log(iter.next()); // { value: 'done', done: true }

yield 不能出现在普通函数、箭头函数或异步函数中

语法错误会直接抛出 SyntaxError,比如在 async function 里写 yield,或在 () => { yield 1; } 中使用——这些都不合法。

  • 只有 function* 内部允许 yield
  • async function* 是合法的,它返回异步迭代器,yield 仍可用,但需配合 for await...ofnext().then()
  • yield 后面可以是任意表达式,包括 yield* anotherGenerator()(委托迭代)

迭代器协议是底层契约,for...of 和展开运算符依赖它

for...of[...iter]Array.from(iter) 等语法糖,本质都是反复调用 iter.next(),直到 done: true。如果对象没有 [Symbol.iterator]() 方法,就会报错 TypeError: XXX is not iterable

立即学习“Java免费学习笔记(深入)”;

  • 生成器函数自动实现 [Symbol.iterator],所以可直接用于 for...of
  • 手动实现迭代器需返回带 next() 的对象,yield 是最简方式,否则要自己维护状态和 done 标志
  • 注意:生成器一旦 done: true,后续所有 next() 调用都返回 { value: undefined, done: true },不可重用
function* fib() {
  let [a, b] = [0, 1];
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

const fibIter = fib(); console.log(fibIter.next().value); // 0 console.log(fibIter.next().value); // 1 console.log(fibIter.next().value); // 1 console.log(fibIter.next().value); // 2

// 可无限遍历(但注意别用 [...fib()],会卡死) for (const n of fib()) { if (n > 10) break; console.log(n); // 0 1 1 2 3 5 8 }

真正容易被忽略的是:生成器函数内部的 try...finallyreturnthrow 时仍会执行,但 yield 暂停期间不会触发;另外,yield 表达式本身有返回值,这个值只在下一次 next(arg) 时传入,不是 yield 右侧表达式的值。


# javascript  # java  # ai 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】  如何用JavaScript实现文本编辑器_光标和选区怎么处理  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】  nodejs redis 发布订阅机制封装实现方法及实例代码  javascript中的try catch异常捕获机制用法分析  ,网页ppt怎么弄成自己的ppt?  JS碰撞运动实现方法详解  Laravel如何为API生成Swagger或OpenAPI文档  html5audio标签播放结束怎么触发事件_onended回调方法【教程】  html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】  如何构建满足综合性能需求的优质建站方案?  JavaScript如何实现路由_前端路由原理是什么  南京网站制作费用,南京远驱官方网站?  canvas 画布在主流浏览器中的尺寸限制详细介绍  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  Laravel怎么上传文件_Laravel图片上传及存储配置  JS中页面与页面之间超链接跳转中文乱码问题的解决办法  Laravel怎么自定义错误页面_Laravel修改404和500页面模板  Bootstrap整体框架之JavaScript插件架构  如何用AI帮你把自己的生活经历写成一个有趣的故事?  Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权  香港服务器部署网站为何提示未备案?  今日头条AI怎样推荐抢票工具_今日头条AI抢票工具推荐算法与筛选【技巧】  如何登录建站主机?访问步骤全解析  如何快速搭建高效可靠的建站解决方案?  如何在橙子建站上传落地页?操作指南详解  Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程  Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案  如何彻底卸载建站之星软件?  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法  Laravel如何使用模型观察者?(Observer代码示例)  如何在不使用负向后查找的情况下匹配特定条件前的换行符  如何在IIS中新建站点并配置端口与IP地址?  Laravel如何处理异常和错误?(Handler示例)  Android自定义listview布局实现上拉加载下拉刷新功能  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?  WEB开发之注册页面验证码倒计时代码的实现  怎样使用JSON进行数据交换_它有什么限制  php结合redis实现高并发下的抢购、秒杀功能的实例  MySQL查询结果复制到新表的方法(更新、插入)  laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法  Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能  如何在Windows服务器上快速搭建网站?  想要更高端的建设网站,这些原则一定要坚持!  Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】  Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  如何在万网开始建站?分步指南解析