2010-10-13 99 views
5

我有一個函數,它是一個JQuery事件處理程序。因爲它是一個JQuery事件處理程序,所以它使用this變量來引用它所調用的對象(對於該庫來說是正常的)。如何在Javascript中重新定義`this`?

不幸的是,我現在需要手動調用該方法。如何讓被調用函數內部的this表現得像從JQuery調用一樣?

示例代碼:

function performAjaxRequest() { 
    //Function which builds AJAX request in terms of "this" 
} 

function buildForm(dialogOfForm) { 
    var inputItem; 
    dialogOfForm.html('...'); 
    dialogOfForm.dialog('option', 'buttons', { 
     "Ok" : performAjaxRequest 
    }); 
    inputItem = dialogOfForm.children(':not(label)'); 
    //Redirect enter to submit the form 
    inputItem.keypress(function (e) { 
     if (e.which === 13) { 
      performAjaxRequest(); //Note that 'this' isn't the dialog box 
            //as performAjaxRequest expects here, it's 
            //the input element where the user pressed 
            //enter! 
     } 
    } 
} 

回答

8

如果dialog的是,你需要設置爲this那麼對象:

performAjaxRequest.apply(dialog, []); 
// arguments (instead of []) might be even better 

應該做的伎倆。

否則,jQuery的,你可以簡單地調用想要的都設置到this

說,例如在元素上trigger方法,你想有一個click事件發生在一個按鈕,你需要它發生在現在。只需撥打:

$("#my_button").trigger("click"); 

#my_buttonclick處理程序將被調用,this將被設置爲#my_button元素。

如果您需要調用一個方法,用不同的this ...比方說,與this指的是jQuery對象本身,那麼你會希望你的函數使用callapply

Chuck和MEDER已經給了你每個例子......但是有一切都在一個地方:

// Call 
my_function.call(object_to_use_for_this, argument1, argument2, ... argumentN); 

// Apply 
my_function.apply(object_to_use_for_this, arguments_array); 

SEE:A List Apart's Get Out of Binding Situations

+0

比方說,我沒有一個方便的參考事件將被觸發的實際事件或元素。 – 2010-10-13 01:17:53

+0

@Billy ...所以你想在一個變量對象或一組對象上觸發一個變量事件?如果是這樣,通用代碼是什麼樣的?什麼*做*你知道此刻你想觸發什麼,你需要觸發? – 2010-10-13 01:21:03

+0

剛剛更新了問題 - 讓我知道如果這使得它更清晰。 – 2010-10-13 01:23:44

10

您可以使用該功能的call方法。

someFunction.call(objectToBeThis, argument1, argument2, andSoOnAndSoOn); 
+1

+1回答我回答最直接的問題的第一個答案。勾選標記@肖恩的答案,只是因爲它更完整。 – 2010-10-13 01:45:19

3

您是否在尋找..

functionRef.apply(objectContext, arguments); 
+1

+1 - 也是一個很好的答案,儘管@查克的答案更直接地做我正在尋找的東西。 – 2010-10-13 01:45:46

0

使用封閉 即分配這在初期;那麼你可以做你喜歡的事情。

var that = this; 
+0

看看我的示例代碼。請注意,事件函數正在從兩個地方調用。你如何通過閉包來解決這個問題而不重複'performAjaxRequest'的內容? – 2010-10-13 02:19:26

1

你當然應該學習掌握call()apply(),因爲人們都表示,但有點幫手絕不會傷害......

在jQuery中,有$.proxy。在純JS,你可以重新創建niftyness),其具有類似:

function proxyFn(fn , scope){ 
    return function(){ 
    return fn.apply(scope,arguments); 
    } 
} 

應用實例:

var myFunctionThatUsesThis = function(A,B){ 
    console.log(this,arguments); // {foo:'bar'},'a','b' 
}; 

// setTimeout or do Ajax call or whatever you suppose loses "this" 

var thisTarget = {foo: 'bar'}; 
setTimeout(proxyFn(myFunctionThatUsesThis, thisTarget) , 1000 , 'a', 'b'); 

// or... 

var contextForcedCallback = proxyFn(myAjaxCallback , someObjectToBeThis); 
performAjaxRequest(myURL, someArgs, contextForcedCallback); 

如果你不濫用它,這是一個安全可靠的工具,從來沒有放寬「這個」的範圍。

+0

對不起,我提供的原始功能包含一個精神癱瘓。它已經更新到正確的版本。 – Quickredfox 2010-10-13 02:25:16

相關問題