2011-04-28 108 views
1

我有一個腳本,基於特定的場景,可能需要取代函數來在最終調用原始函數之前進行一些處理。 (請參閱「'overriding' Javascript Function」)動態替換不在全局範圍內的函數

我一般可以得到這個工作 - 在這裏是一個使用jQuery插件Tinyscrollbar(不是我預期的應用,只是一些快速和容易的說明)一個簡單的例子:

(function ($) { 
    // Snip.. 

    function initalize() { 
     oSelf.update(); 
     setEvents(); 
     return oSelf; 
    } 

    // Snip.. 

    function setEvents() { 

     (function() { 
      var oldInit = wheel; 

      wheel = function (oEvent) { 
       console.log('Intercept'); 
       oldInit(oEvent); 
      } 
     })(); 

     // Original event code, irrelevant to question 
    } 

    function wheel(oEvent) { 
     // Actual function, related to using the mousewheel 
    } 

})(jQuery); 

當我滾動鼠標滾輪,控制檯打印「攔截」,滾動條按原定義移動。精彩!

但是,函數名是硬編碼的,並不在全局範圍內,所以window []不可用(我喜歡)。是否有任何可能的黑魔法,'new Function()'和/或其他方式組合循環遍歷潛在的函數名稱列表(可能會根據其他邏輯進行更改)並將它們封裝在這個(或類似的內部函數)精神)的態度?

在此先感謝!

回答

1

不幸的是,有沒有辦法一一列舉或動態的範圍對象訪問成員(與全球範圍/ window對象的便捷除外)

所以你需要修改你的代碼位。而不是在你的外部函數中有自由浮動函數,而是在它們上面有方法的對象。這會使得更換這些方法變得更容易。

如果您在開始將它們分配爲事件處理程序或其他類型之後修改函數,那麼還有一些額外的技巧。如果你碰巧在這些函數中使用了某種bind()包裝,你的行爲的正確性將取決於bind()函數。

具體來說,如果您希望替換方法追溯地成爲調用它的任何事件處理程序或回調的方法,您將需要使用一個bind()包裝器,該包裝器需要一個上下文對象和一個字符串是函數名稱而不是上下文對象和函數引用。 (並確保bind()不會早期解析該字符串以便在每次調用時削減一些ms)。

如果不想要追溯行爲,則仍然必須確保不要有一些bind() - 版本的原始方法漂浮在你的替換髮生後仍然用於新的回調。

+0

夠公平的,我非常感謝迴應。對於它的價值,我的實際應用程序沒有嘗試取代bind() - s,所以至少很多瘋狂不適用;但絕對值得指出。通過在init() - 時間引用的對象屬性中編寫覆蓋函數,我能夠實現我的目標;不是超級時尚的生成代碼,但它完成了工作,因爲沒有太多人擔心。 – Morgon 2011-04-29 01:59:39

相關問題