Нельзя ли определить, является ли функция функцией-генератором, если для нее был вызван .bind()?

Похоже, вызов .bind(this) для любой функции-генератора лишает меня возможности увидеть, является ли функция генератором. Есть какие нибудь идеи как это починить?

var isGenerator = function(fn) {
    if(!fn) {
        return false;
    }

    var isGenerator = false;

    // Faster method first
    // Calling .bind(this) causes fn.constructor.name to be 'Function'
    if(fn.constructor.name === 'GeneratorFunction') {
        isGenerator = true;
    }
    // Slower method second
    // Calling .bind(this) causes this test to fail
    else if(/^function\s*\*/.test(fn.toString())) {
        isGenerator = true;
    }

    return isGenerator;
}

var myGenerator = function*() {
}

var myBoundGenerator = myGenerator.bind(this);

isGenerator(myBoundGenerator); // false, should be true

person Kirk Ouimet    schedule 06.11.2014    source источник
comment
bind() возвращает новую функцию. простая функция, без привязки к прошлому   -  person dandavis    schedule 06.11.2014
comment
Возможно, было бы интересно посмотреть, как они это делают: npmjs.org/package/generator-bind   -  person jfriend00    schedule 06.11.2014
comment
возможный дубликат проверить, является ли функция генератором   -  person    schedule 06.11.2014
comment
@jfriend00 спасибо! Этот пакет решил мою проблему   -  person Kirk Ouimet    schedule 06.11.2014
comment
@Kirk - я превратил свой комментарий в ответ.   -  person jfriend00    schedule 06.11.2014


Ответы (3)


Поскольку .bind() возвращает новую (заглушку) функцию, которая просто вызывает оригинал с .apply(), чтобы прикрепить правильное значение this, очевидно, что это больше не ваш генератор, и это источник вашей проблемы.

В этом модуле node есть решение: https://www.npmjs.org/package/generator-bind. .

Вы можете либо использовать этот модуль как есть, либо посмотреть, как они его решают (по сути, они делают новую функцию, которую возвращает .bind(), также генератором).

person jfriend00    schedule 06.11.2014
comment
Связанный генератор остается генератором, что можно проверить с помощью yield*. Я разместил свой ответ ниже. (справедливости ради, возможно, что была сделана коррекция с 1,5 года назад) - person niry; 01.05.2016

Да, можно определить, является ли функция генератором, даже если для нее была вызвана функция .bind():

function testIsGen(f) {
  return Object.getPrototypeOf(f) === Object.getPrototypeOf(function*() {});
}
person niry    schedule 01.05.2016

Этот пакет имеет решение:

https://www.npmjs.org/package/generator-bind

По сути, чтобы заставить его работать, вам нужно либо полифиллировать Function.prototype.bind, либо вызывать собственный метод bind().

person Kirk Ouimet    schedule 06.11.2014