2013-03-26 122 views
1

X反覆嘗試調用其方法foo,以致我的插件Y的用戶體驗受到巨大損害。我的插件Y引入了任意邏輯shouldFooExecute,必須在X.foo的最終結果發生之前考慮。但是,當用戶通過Y(發生在模式窗口中)完成時,X應該能夠繼續進行,就好像什麼也沒有發生。避免重新綁定函數參考中的遞歸

// This is an external library. I can't modify and shouldn't overwrite it. 
x = { 
    // A method that completely screws my plugin 
    foo: function(){ 
    /* nasty stuff */ 
    } 
} 

// This is my widget! 
y = { 
    // Init function, called when my plugin boots 
    init: function(){ 
    // This scope handles the x.foo problem 
    void function rebindFoo(){ 
     // Internal state 
     var shouldFooExecute = false; 
     // I need to be able to refer back to the original foo after I've temporarily rebound it 
     var x_foo = x.foo; 

     // Re-attach foo to its original definition & context 
     function rebindFooToX(){ 
     // ECMAScript 5 browsers are fine! 
     if(Function.prototype.bind){ 
      // x.foo is literally rebound to pretty much exactly what it was 
      x.foo = x_foo.bind(x); 
     } 
     // Others not so good when this function executes a second time 
     else { 
      x.foo = function rebound_foo(){ 
      // An extra scope! Horrible. And it's recursive! 
      return x_foo.apply(x, arguments); 
      } 
     } 
     } 

     x.foo = function y_foo(){ 
     // Stop and consider y's esoteric logic 
     if(shouldFooExecute){ 
      // If it's fine, we rebind everything 
      rebindFooToX(); 
      // This will have the intended effect 
      x.foo(); 
     } 
     } 
    } 
    } 
} 

問題是當我的插件在不支持綁定的瀏覽器上重新初始化時。 x.foo最終引用rebound_foo這是循環。有什麼樣的邏輯我可以寫,以避免遞歸,並在存在的情況下使用現有的rebound_foo

+0

你爲什麼試圖替換x。 FOO?你可能會遇到其他插件的問題,因爲你綁定它等等。你不能只調用你自己的y_foo()而不是使用x.foo()嗎? – 2013-03-26 13:16:06

+0

另外我想'x.foo = y_foo(){'是不正確的語法。 – 2013-03-26 13:17:43

+0

@AramKocharyan - 感謝您指出錯字。潛在地遇到與其他插件有關的問題正是我爲什麼要花費這麼長的時間來將'x.foo'重新綁定到它的原始上下文,一旦我的模態的UX完成。我不是那種試圖調用'x.foo'的人(我不想稱之爲!) - 與之相關的事件是多方面的,並且不受我的控制。 – Barney 2013-03-26 14:00:36

回答

0

您可以使用https://github.com/kriskowal/es5-shimFunction.prototype.bind方法添加到本機不支持的瀏覽器中。

+0

es5-shim的綁定方法,就像下劃線的綁定方法一樣,與我的代碼做同樣的事情:它創建一個_new_函數(在我的代碼中是'rebound_foo',在es5-shim中是'bound'),它返回原始函數通過'apply'定義的上下文。額外的範圍是捕獲'arguments'對象所必需的,因爲'apply'立即用顯式參數調用函數。 – Barney 2013-03-26 14:05:13

0

這是事實,7個月後,所以這個問題可能是OBE,但是我想指出,根據X是如何定義的,你可以嘗試繼承:

var x = function() { 
    this.foo = function() { 
     console.log("from x"); 
    }; 

    this.bar = function() { 
     console.log("from x"); 
    }; 
} 

var y = function() { 
    this.foo = function() { 
     console.log("from y"); 
    } 
} 

y.prototype = new x(); 

var test = new y(); 
test.foo(); // will output: from y 
test.bar(); // will output: from x