2010-10-13 9 views
5

Tengo una función que es un controlador de eventos JQuery. Como es un controlador de eventos JQuery, usa la variable this para hacer referencia al objeto en el que se invoca (como es normal para esa biblioteca).¿Cómo redefino `this` en Javascript?

Lamentablemente, tengo que llamar manualmente a ese método en este momento. ¿Cómo hago que this dentro de la función llamada se comporte como si se llamara desde JQuery?

código Ejemplo:

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! 
     } 
    } 
} 

Respuesta

8

Si dialog es el objeto que debe ser fijado a this a continuación:

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

debe hacer el truco.

De lo contrario, en jQuery sólo tiene que llamar al método trigger en el elemento que desea han establecido en this

Digamos, por ejemplo, que quería tener un evento click suceda en un botón y lo que necesita Ocurrirá ahora. Simplemente llaman: serán invocadas

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

Sus #my_button 's click manejador, y this se establecerán en el elemento #my_button.

Si necesita llamar a un método con una diferente ... this decir, por ejemplo, con this refiriéndose al propio objeto jQuery, entonces usted tendrá que usar call o apply en su función.

Chuck y meder ya se han dado ejemplos de cada uno ... pero para tener todo en un solo lugar:

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

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

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

+0

Digamos que no tengo una referencia útil para el evento o elemento real en el que se desencadenaría el evento. –

+0

@Billy ... por lo que desea desencadenar un evento variable en un objeto variable o conjunto de objetos? Si es así, ¿cómo se ve el código general? ¿Qué * sabe * en el momento en que desea desencadenar lo que sea que necesite desencadenar? –

+0

Acabo de actualizar la pregunta, hágamelo saber si eso lo aclara. –

10

Puede utilizar el método de la función call.

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

+1 a la primera respuesta que responde al problema más directo que planteé. Marcó la respuesta de @ Sean aunque porque es más completa. –

3

¿Está buscando ..

functionRef.apply(objectContext, arguments); 
+1

+1 - También es una buena respuesta, aunque la respuesta de @ Chuck más directamente hace lo que estaba buscando. –

0

uso un cierre es decir asignar esto a que desde el principio; entonces puedes hacer lo que quieras con eso.

var that = this; 
+0

Mira mi código de ejemplo. Tenga en cuenta que se llama a la función de evento desde dos lugares. ¿Cómo propone resolver eso con un cierre sin duplicar el contenido de 'performAjaxRequest'? –

1

Debe, por supuesto, aprender a dominar call() y apply() como personas han dicho, sino un poco de ayuda nunca viene mal ...

En jQuery, hay $.proxy.En js puros, puede volver a crear ese niftyness;) con algo como:

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

Ejemplos de uso:

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); 

Si no abusar de ella, que es una herramienta más segura de que nunca perder el alcance de "esto".

+0

Lo siento, la función original que proporcioné contenía un lapsus mental. Se ha actualizado a la versión correcta. – Quickredfox

Cuestiones relacionadas