2014-11-06 75 views
5

看起來像在任何生成器函數中調用.bind(this)會破壞我看看該函數是否爲生成器的能力。有想法該怎麼解決這個嗎?如果函數是一個生成器函數,如果已經調用了.bind()函數,是不可能的?

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 
+2

bind()的返回一個新的功能。一個普通的函數,與過去沒有任何聯繫 – dandavis 2014-11-06 00:13:21

+1

也許這將是有趣的,看他們是如何做到的:https://www.npmjs.org/package/generator-bind – jfriend00 2014-11-06 00:45:46

+0

可能的重複[檢查函數是一個發生器](http://stackoverflow.com/questions/16754956/check-if-function-is-a-generator) – 2014-11-06 02:12:03

回答

6

由於.bind()返回一個新的(存根)函數,它纔剛剛調用原始與.apply()爲了安裝適當的this值,這顯然不再是你的發電機,這是你的問題的根源。

此節點模塊中有一個解決方案:https://www.npmjs.org/package/generator-bind

您可以按原樣使用該模塊,也可以看看它們如何解決它(基本上它們使得.bind()返回的新函數也是一個生成器)。

+1

綁定的發生器仍然是一個發生器,可以用yield *進行測試。我在下面發佈了我的答案。 (公平地說,自1.5年前以來可能會進行更正) – niry 2016-05-01 18:16:19

1

是的,有可能判斷一個功能是即使.bind發電機()被調用就可以了:

function testIsGen(f) { 
    return Object.getPrototypeOf(f) === Object.getPrototypeOf(function*() {}); 
} 
相關問題