前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库生成器 yield 与 return 区别
JavaScript函数与作用域

生成器里 yield 和 return 有什么区别?return 之后还能继续 next 吗?

yield 交出一个值然后暂停,返回 done: false,后面还能接着跑。return 交出最后一个值并结束生成器,返回 done: true。结束后还能调用 next(),不会报错,但只会一直得到 { value: undefined, done: true }。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#函数与作用域
先看核心答案读代码示例
理解线索

中途交出的值和最后的值

  1. yield value交出一个元素,生成器停在这里,局部变量都保留
  2. return value交出结束时的值,生成器状态变为已完成
  3. 结束后的 next()不再进入函数体,每次都返回 done: true

生成器结束是不可逆的。想重新遍历,只能再调用一次生成器函数,得到一个新的生成器对象。

核心回答

先记住这个答案

yield 是「交出一个值,先停一下」,next() 返回 { value, done: false },生成器停在这里,下次 next() 从这里接着执行。return 是「交出最后一个值,彻底结束」,next() 返回 { value, done: true },生成器进入完成状态。return 之后可以继续调用 next(),不会报错,但函数体不会再执行,每次都返回 { value: undefined, done: true }。

  • yield 暂停,done: false,还能继续
  • return 结束,done: true,不能再恢复
  • 结束后再 next() 得到 { value: undefined, done: true }
  • for...of 和展开运算符都拿不到 return 的值

逐次调用 next 看区别

手动调用 next(),每次的返回值都能看得很清楚。

两个 yield 加一个 returnJavaScript
function* steps() {
  yield '第一步'
  yield '第二步'
  return '完成'
}

const it = steps()
console.log(JSON.stringify(it.next())) // 转成 JSON 看得更清楚
console.log(JSON.stringify(it.next()))
console.log(JSON.stringify(it.next()))
const after = it.next() // 已经结束,再调一次
console.log(after.value, after.done)
console.log([...steps()].join(',')) // 展开拿不到 return 的值
查看输出与解释
{"value":"第一步","done":false}
{"value":"第二步","done":false}
{"value":"完成","done":true}
undefined true
第一步,第二步

前两次 next() 遇到 yield,done 是 false。第三次遇到 return,value 是 '完成',done 是 true。第四次生成器已经结束,value 是 undefined,done 仍然是 true,不会报错,也不会从头再来。 最后一行用展开运算符,只拿到了两个 yield 的值,return 的 '完成' 被丢掉了。

为什么 for...of 拿不到 return 的值

for...of、展开运算符、Array.from 都按同一个规则消费迭代器:done 为 false 时,value 是一个元素,放进结果里;一旦 done 为 true,就说明遍历结束,这次的 value 不算元素,直接停止。

return 值该怎么用
return 的值更像是「任务的最终结果」,而不是序列里的一项。比如一个生成器按步骤处理数据,每一步 yield 进度,最后 return 汇总结果。调用方想拿到汇总结果,只能手动调用 next(),读到 done: true 那一次的 value。
yield* 可以拿到 return 的值
在一个生成器里用 const result = yield* inner() 委托给另一个生成器时,inner 的所有 yield 会被转发出去,而 inner 的 return 值会成为 yield* 表达式的结果,赋给 result。这是 return 值在生成器之间传递的主要方式。
回答前,多想一步

容易答错的地方

以为 for...of 会包含 return 的值
for...of 看到 done: true 就停止,不会执行循环体。需要这个值时要手动读取,或者把它改成 yield。
以为结束后再 next() 会报错或重新开始
结束后调用 next() 是安全的,只会一直返回 { value: undefined, done: true }。它不会自动重新开始,要重来只能重新调用生成器函数。
试着用自己的话回答

面试官还会怎么问?

没写 return 时最后一次 next() 返回什么?

函数体执行到末尾相当于 return undefined,最后一次返回 { value: undefined, done: true }。

return 后面的 yield 还会执行吗?

不会。return 之后生成器就结束了,后面的代码都不会执行。唯一的例外是 return 写在 try 里,而 finally 里还有 yield,这时会先停在 finally 的 yield 上,直到 finally 跑完才真正结束。

yield 和 await 有什么区别?

yield 把控制权交给调用 next() 的代码,什么时候继续由调用方决定,而且能交出值。await 等待一个 Promise,Promise 完成后由事件循环自动恢复执行,不会向外交出值。async 函数可以看作一个自动调用 next 的生成器。

从一道题,走向一组知识

把知识连起来

函数与作用域

var 和 let 都会提升吗?为什么 let 在声明前访问会报错?

生成器暂停时 let 和 const 声明的局部变量都会保留,恢复后接着用,结束后才一起释放。

函数与作用域

什么是 IIFE?现在有了 let 和模块,它还有什么用?

IIFE 调用一次就结束,生成器能暂停多次再继续,两者正好是函数执行方式的两个极端。

参考资料

  • JavaScript:函数与作用域参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 逐次调用 next 看区别
  3. 为什么 for...of 拿不到 return 的值
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑