2011-05-01 12 views
5

對Paul Irish的博客中第一次遇到的'duck punching'模式有疑問。我得到的一般前提是...保存一個現有函數的引用,然後用一個條件分支替換現有的函數,如果滿足條件將調用一個新函數,否則舊版本。我的問題是爲什麼當我們調用_old函數時,我們必須使用「apply」作爲第一個參數?我瞭解申請是如何運作的,但我正在尋找一些關於爲什麼有必要的澄清。Paul Irish'duck punching'pattern observation

(function($){ 

     // store original reference to the method 
     var _old = $.fn.method; 

     $.fn.method = function(arg1,arg2){ 

      if (... condition ...) { 
       return .... 
      } else {   // do the default 
       return _old.apply(this,arguments); 
      } 
     }; 
    })(jQuery); 

回答

8

考慮這個例子

var obj = { 
    foo: "bar", 
    baz: function() { 
     return this.foo; 
    } 
}; 
o = obj.baz; 
obj.baz(); // "bar" 
o(); // undefined 

,如果你調用一個方法與obj.baz,即點後面的對象是函數的上下文(將把這個對象)。 如果將方法存儲在變量中,則會丟失有關上下文的信息。在這種情況下,上下文將被設置爲全局對象。

var obj = { 
    baz: function() { 
     return this; 
    } 
}; 
o = obj.baz; 
obj.baz() === obj; // true 
o() === obj; // false 
o() === window; // true 

適當的上下文對於.method按預期工作可能很重要。

+0

我明白,我想我不明白'適用'與此作爲第一個參數有助於防止。如果我們做了類似於上面用鴨子代碼所描述的內容,'this','this'可能是窗口,那麼這個應用有什麼幫助? – mike 2011-05-01 14:17:17

+0

嗯 - 不要試圖鈍,也許我只是需要更多的研究,但在鴨打碼的應用盲目地採取任何'這'目前設置。我不明白這與直接致電_old不同。也許這就是我錯過的。如果我直接打電話給_old,那麼'這個'總是與代碼傳遞'apply'的'this'一樣。那麼,什麼是使用點 – mike 2011-05-01 14:30:11

+0

假設原來的$ .fn.method內部使用其他jQuery方法,這取決於此上下文。用全局上下文調用它會使其他方法無法使用。還有許多jQuery函數返回這個,所以鏈接是可能的。如果你返回錯誤的環境,鏈接將被打破。 – Rafael 2011-05-01 14:30:34

1

您通過this因爲apply()需要的第一個參數是調用舊功能時this應該是什麼。

apply()正在使用,因此您可以輕鬆地將arguments作爲舊函數的參數處理。

所以,當決定什麼通過this,你選擇傳遞什麼this是在這種情況下。

+0

問題是爲什麼使用首先適用,而不是爲什麼你必須通過'this'作爲第一個參數,我想。 – 2011-05-01 14:06:42

+0

所以它與上下文無關或者'this'設置爲什麼,只是一個簡單的機制將參數傳遞給_old? – mike 2011-05-01 14:07:31

+0

那麼,當使用'apply()'時,你必須決定設置什麼'this'。 – alex 2011-05-01 14:09:04

1

如果你要調用原來的功能,無需apply,你讓JavaScript的決定如何綁定this到,這很可能是一些從它會被綁定到如果你沒有monkeypatched不同/ duckpunched原代碼。

使用apply,您確保將正確的值用於this,例如,包裝函數被調用的那個。

+0

但如果我做了類似於f = jquery.fn._old的東西,然後調用f(),那麼當我們調用apply時,'this'將會是窗口。應用,也許我只是不理解,並不是阻止任何事情,而是盲目地使用任何「這個」。那麼有什麼意義。我開始認爲Alex可能是對的,只是一個傳遞參數數組的機制。 – mike 2011-05-01 14:24:37

+0

打鴨時,要儘可能地重新創建_old的原始上下文。這包括確保'this'設置爲與直接調用_old相同的對象。通用的方法是通過使用'.apply()'傳遞'this'。 – 2011-05-01 14:45:40

相關問題