前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
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 热点
旧版
首页程序员面试题库生成器函数能否用 new 调用
JavaScript函数与作用域

生成器函数能用 new 调用吗?里面的 new.target 是什么?

不能。new 一个生成器函数会直接抛 TypeError,函数体一行都不执行。生成器只能普通调用,所以函数体里读到的 new.target 永远是 undefined。

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

生成器为什么不能 new

  1. 调用方式普通调用返回生成器对象,函数体要等 next() 才执行
  2. new.target只有 new 调用时才有值,生成器没有这种调用,所以总是 undefined
  3. prototype调用 gen() 返回的对象以它为原型,和构造实例无关

生成器函数没有 this 可以初始化。普通调用时函数体里的 this 是调用时的接收者,而不是返回的生成器对象,所以 this.x = 1 不会出现在生成器对象上。

核心回答

先记住这个答案

生成器函数不能用 new 调用,new gen() 会立刻抛出 TypeError: gen is not a constructor。原因是规范在设计上就没给生成器函数构造能力:调用生成器的结果是一个生成器对象,函数体被推迟到 next() 时执行,这和「创建实例、用 this 初始化、返回实例」的构造流程对不上。既然只能普通调用,函数体里的 new.target 也就永远是 undefined。

  • new gen() 直接抛 TypeError
  • 生成器函数体里的 new.target 永远是 undefined
  • gen.prototype 是生成器对象的原型,不是给 new 用的
  • 想要可 new 又可遍历,用 class 加 *[Symbol.iterator]()

实际跑一下

生成器函数有 prototype,很多人因此以为能 new,试一下就知道。

普通调用、new 调用和原型关系JavaScript
function* task() {
  yield new.target // 看看函数体里 new.target 是什么
}

const it = task()
console.log(it.next().value) // 普通调用,没有 new
console.log(Object.getPrototypeOf(it) === task.prototype) // 生成器对象的原型
console.log(typeof task.prototype)

try {
  new task()
} catch (e) {
  console.log(e.name)
}
查看输出与解释
undefined
true
object
TypeError

普通调用得到的生成器对象,原型就是 task.prototype,所以这个属性是有用的,只是用途不是构造实例。new task() 在执行函数体之前就失败了,所以函数体里的 new.target 只可能在普通调用下被读到,值只能是 undefined。

prototype 在生成器上是干什么的

普通函数的 prototype 是给 new 出来的实例当原型。生成器函数的 prototype 是给调用它返回的生成器对象当原型,而这个 prototype 自己再往上,继承自一个内置的生成器原型,next、return、throw 就定义在那里。

可以往 prototype 上加方法
比如 task.prototype.hello = () => 'hi',之后 task().hello() 就能调用。这说明生成器对象确实是沿着 task.prototype 查找属性的。但这种写法很少见,了解原理即可。
想要能 new 又能遍历
用 class 定义,在类里写一个生成器方法作为 [Symbol.iterator]。比如 class Range { constructor(n) { this.n = n } *[Symbol.iterator]() { for (let i = 0; i < this.n; i++) yield i } },new Range(3) 负责构造,for...of 时自动调用生成器方法遍历,两件事各管各的。
回答前,多想一步

容易答错的地方

看到有 prototype 就认为能 new
能不能 new 取决于函数有没有构造能力,和有没有 prototype 属性不是一回事。生成器、异步生成器都有 prototype,都不能 new。
以为生成器函数里的 this 就是生成器对象
普通调用 task() 时,函数体里的 this 按普通函数规则确定,严格模式下是 undefined,不是返回的生成器对象。在函数体里写 this.count = 0 不会让生成器对象多一个属性。
试着用自己的话回答

面试官还会怎么问?

异步生成器能 new 吗?

不能,async function* 和普通生成器一样,有 prototype 但不能被 new,new.target 也总是 undefined。

箭头函数和生成器在这方面有什么不同?

两者都不能 new。区别是箭头函数没有 prototype,而且箭头函数没有自己的 new.target,读到的是外层函数的 new.target。另外没有「箭头生成器」这种写法,yield 不能出现在箭头函数里。

以前 ES6 刚出来时生成器能 new 吗?

ES2015 规范里生成器函数曾经允许 new,ES2016 起改为不可构造,现在的引擎都会抛 TypeError。这个历史细节知道即可,不用写进代码。

从一道题,走向一组知识

把知识连起来

函数与作用域

怎么从外部停掉一个生成器,或者往里面抛一个错误?

生成器对象不能 new 出来,只能调用函数得到,之后再用 return()、throw() 从外部控制它。

函数与作用域

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

生成器函数里的 return 不是返回构造结果,而是给最后一次 next() 提供 done: true 的值。

参考资料

  • JavaScript:函数与作用域参考资料
  • new.target - JavaScript | MDN

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

本题目录
  1. 先记住这个答案
  2. 实际跑一下
  3. prototype 在生成器上是干什么的
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

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

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