【问题标题】:How to check if a variable is a generator function? (e.g function* yield) [duplicate]如何检查变量是否是生成器函数? (例如函数*产量)[重复]
【发布时间】:2016-03-10 06:06:08
【问题描述】:

什么是检查函数是否是生成器的可靠方法,例如:

let fn = function* () {
    yield 100;
}

if (fn instanceof ??) {
   for (let value in fn()) {
       ...
   }
}

我能想到的唯一方法是fn.toString().startsWith('function*'),但这非常不可靠且不可靠

上下文:nodejs 4+

【问题讨论】:

  • 也许你可以检查一下上面是否定义了next
  • 刚试过,typeof fn.next 是“未定义”
  • 你可能会做类似if(typeof fn().next === 'function') {}
  • 那不是iterator函数,那是generator函数。
  • @saadq:但这会错误地识别任何使用next 方法返回对象的函数。

标签: javascript node.js ecmascript-6


【解决方案1】:

Erik Arvidsson makes a good point in this answer 这个问题的早期版本(我没有想到这是一个骗局),因为任何函数都可以返回一个迭代器,所以检查一个函数是否是一个生成器没有什么意义。也就是说,实际上您对这些信息无能为力,因为非生成器可以返回迭代器。


我之前错了,比你的toString检查更好的方法(如果出于某种原因你有一个有效的需要这样做的话):

  1. (Once) 获取生成器函数默认constructor的值,即specified here。它没有像Function 这样的全局变量。

  2. (当你需要检查时)检查你的目标函数是否是instanceof那个生成器函数构造函数。

例如:

// Once
var GeneratorFunction = (function*(){}).constructor;

// Whenever you need to check
if (fn instanceof GeneratorFunction) {
    // Yep, it's a generator function
}

旧事排除:

我在规范中没有看到任何可以让我们直接访问[[FunctionKind]] 内部插槽的内容。

规范does say:

与函数实例不同,作为 GeneratorFunction 的 prototype 属性值的对象没有值为 GeneratorFunction 实例的 constructor 属性。

理论上来说:

if (!fn.prototype.hasOwnProperty("constructor")) {
    // It's a generator function
}

但是,这将是难以置信的不可靠,因为人们一直在做这样的事情(尽管希望随着人们开始使用class而减少):

function Foo() {
}
Foo.prototype = {
    method: function() {}
};

虽然 Foo.prototype 对象具有 constructor 属性,但它是继承的,而不是“拥有的”。我们可以进行in 检查或.constructor == fn 检查,但上述方法仍然会错误识别它。在野外你不能相信constructor,人们把事情搞砸了。

【讨论】:

  • toString 太可怕了。请不要推荐这个。还有更好的方法,比如instanceof Generator(其中Generator是生成器函数的内置构造函数)。
  • 无论如何,you shouldn't be doing this anyway,将生成器函数与返回迭代器(或生成器)的任何其他(普通)函数区分开来是没有意义的。
  • @Bergi:我不推荐它。我回答的问题是如何,而不是你应该
  • @Bergi:规范定义的Generator 符号在哪里? V8 不知道。
  • 它不是一个实例属性(就像.prototype 是 - 生成器函数是“构造函数”),它是一个property inherited from GeneratorFunction.prototype。规范令人困惑:-)
猜你喜欢
  • 1970-01-01
  • 2014-04-17
  • 2013-05-21
  • 2016-06-30
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 2015-06-10
  • 2015-05-30
相关资源
最近更新 更多