如何检查变量是否是生成函数? (例如功能*产量) [英] How to check if a variable is a generator function? (e.g function* yield)

查看:160
本文介绍了如何检查变量是否是生成函数? (例如功能*产量)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  let fn = function *(){ 
产量100;
}

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

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



上下文:nodejs 4 +

解决方案

Erik Arvidsson在这个答案中提出了一个很好的意见这个问题的早期版本(这并不是我的这个dupe),因为任何函数都可以返回一个迭代器,所以检查一个函数是否是一个发生器是没有意义的。也就是说,实际上没有太多的可用信息,因为非发电机可以返回迭代器。






我以前是错误的,那么 比你的 toString 检查更好一些(如果由于某种原因你有一个有效的需要) :


  1. (一次)获取默认的构造函数的值一个生成器函数,它是这里指定的。它没有像功能这样的全局。


  2. (每当你需要检查)检查您的目标函数是否为 instanceof 该生成函数构造函数。


例如:

  //一旦
var GeneratorFunction =(function *(){})。构造函数;

//每当你需要检查
if(fn instanceof GeneratorFunction){
// Yep,它是一个生成函数
}






旧事情排除:



我没有看到任何规范让我们直接访问 [[FunctionKind]] 内部插槽。



规范确实说


与函数实例不同,对象是GeneratorFunction的原型的值属性没有一个构造函数属性,其值为GeneratorFunction实例。


所以在理论上:

  if(!fn.prototype.hasOwnProperty(constructor)){
//它是一个生成函数
}

,这是令人难以置信的不可靠的,因为人们一直在做这样的事情(尽管希望不如人们开始使用 class ):

 函数Foo(){
}
Foo.prototype = {
方法:function(){}
};

虽然 Foo.prototype 构造函数属性,它是继承的,而不是自己的。我们可以在检查中执行,或者执行 .constructor == fn 检查,但是上述内容仍然会错误它。你不能相信构造函数在野外,人们把它弄得太多了。


Whats a reliable way to check if a function is a generator, e.g.:

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

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

The only way I can think of is fn.toString().startsWith('function*') but that's extremely hacky and unreliable

context: nodejs 4+

解决方案

Erik Arvidsson makes a good point in this answer to an earlier version of this question (it didn't occur to me that it's a dupe), that since any function can return an iterator, there's little point in checking whether a function is a generator or not. That is, there's not much you can do with the information in practical terms, since non-generators can return iterators.


I was wrong before, there is a better way than your toString check (if for some reason you have a valid need to do it at all):

  1. (Once) Get the value of the default constructor of a generator function, which is specified here. It doesn't have a global like Function and such do.

  2. (Whenever you need to check) Check to see if your target function is instanceof that generator function constructor.

E.g.:

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

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


Old things ruled out:

I don't see anything in the specification that lets us directly access the [[FunctionKind]] internal slot.

The spec does say:

Unlike function instances, the object that is the value of the a GeneratorFunction’s prototype property does not have a constructor property whose value is the GeneratorFunction instance.

So in theory:

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

but, that would be incredibly unreliable, as people do things like this all the time (although hopefully less so as people start using class):

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

While that Foo.prototype object has a constructor property, it's inherited, not "own". We could do an in check, or a .constructor == fn check, but the above would still mis-identify it. You just can't trust constructor in the wild, people mess it up too much.

这篇关于如何检查变量是否是生成函数? (例如功能*产量)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆