Как мне переопределить `this` в Javascript? - PullRequest
5 голосов
/ 13 октября 2010

У меня есть функция, которая является обработчиком событий JQuery.Поскольку это обработчик событий JQuery, он использует переменную 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!
        }
    }
}

Ответы [ 5 ]

12 голосов
/ 13 октября 2010

Вы можете использовать метод call функции.

someFunction.call(objectToBeThis, argument1, argument2, andSoOnAndSoOn);
8 голосов
/ 13 октября 2010

Если dialog - это объект, который вам нужно установить на this, тогда:

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

должно помочь.

В противном случае, в jQuery вы можете просто вызватьметод trigger для элемента, который вы хотите установить на this

Скажем, например, что вы хотите, чтобы событие click происходило на кнопке ивам нужно, чтобы это произошло сейчас .Просто позвоните:

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

Ваш обработчик #my_button click будет вызван, и для this будет установлен элемент #my_button.

Если вам нужновызовите метод с другим this ... скажем, например, с this, ссылающимся на сам объект jQuery, тогда вы захотите использовать call или apply в вашей функции.

Чак и Медер уже дали вам примеры каждого ... но чтобы все было в одном месте:

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

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

СМОТРИТЕ: A List Apart Выход из обязательных ситуаций

4 голосов
/ 13 октября 2010

Вы ищете ..

functionRef.apply( objectContext, arguments);
1 голос
/ 13 октября 2010

Вы, конечно, должны научиться владеть call() и apply(), как утверждают люди, но маленький помощник никогда не причиняет боль ...

В jQuery есть $. Proxy ,В чистом js вы можете воссоздать эту изящность;) с помощью чего-то вроде:

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 голосов
/ 13 октября 2010

использовать замыкание, т. Е. Присвоить его этому на ранней стадии;тогда вы можете делать то, что вам нравится с ним.

var that = this;
...