2010-07-23 12 views
14

yo soy un principiante a los cierres (y javscript en general), y no puedo encontrar una explicación satisfactoria en cuanto a lo que está pasando en este código:¿Por qué este cierre no tiene acceso a la palabra clave 'this'? - jQuery

function myObject(){ 
    this.myHello = "hello"; 
    this.myMethod = do_stuff; 
} 

function do_stuff(){ 
    var myThis = this; 
    $.get('http://example.com', function(){ 
     alert(this.myHello); 
     alert(myThis.myHello); 
    }); 
} 

var obj = new myObject; 
obj.myMethod(); 

Se alerta 'indefinido' y luego 'hola'. Obviamente, esto no debería ser específico de jQuery, pero esta es la forma más simple de mi código original que podría surgir. El cierre en do_stuff() tiene acceso a las variables en ese ámbito, pero aparentemente esta regla no se aplica a la palabra clave this.

Preguntas:

¿Qué ocurre con this cuando el cierre se pasa fuera del alcance de do_stuff() (en este caso $.get())? ¿Contiene myThis una copia de this o una referencia al mismo? ¿En general no es una buena idea usar this en cierres?

Cualquier respuesta muy apreciada.

Respuesta

8

¿Qué sucede cuando el cierre se pasa fuera del alcance de do_stuff() (en este caso $ .get())?

Cada función tiene su propio contexto de ejecución, la palabra clave this recupera el valor del contexto actual.

El doStuff identificador y la propiedad obj.myMethod se refieren al mismo objeto función, pero ya que está invocando como una propiedad de un objeto (obj.myMethod();), el valor this dentro de esa función, se referirá a obj.

Cuando la petición Ajax ha tenido éxito, jQuery invocar la segunda función (que comienza un nuevo contexto de ejecución), y se utilizará un objeto que contiene los parámetros utilizados para la solicitud como el valor de ese this de devolución de llamada.

¿Incluye myThis una copia de esta o una referencia a esta?

El identificador myThis contendrá una referencia al objeto que también se hace referencia por el valor this sobre el alcance exterior.

¿En general no es una buena idea usar esto en cierres?

Si comprende cómo se maneja implícitamente el valor this, no veo ningún problema ...

dado que está utilizando jQuery, es posible que desee comprobar el método jQuery.proxy, es un método de utilidad que se puede utilizar para preservar el contexto de una función, por ejemplo:

function myObject(){ 
    this.myHello = "hello"; 
    this.myMethod = do_stuff; 
} 

function do_stuff(){ 
    $.get('http://example.com', jQuery.proxy(function(){ 
     alert(this.myHello); 
    }, this)); // we are binding the outer this value as the this value inside 
} 

var obj = new myObject; 
obj.myMethod(); 

Ver también:

+0

Iba a pedir un seguimiento, pero su última edición respondió eso. ¡Gracias! – thewiglaf

+0

@thewiglaf: ¡De nada! Siéntase libre de comentar si tiene alguna duda ... – CMS

2
$.get('http://example.com', function(){ 
    alert(this.myHello); // this is scoped to the function 
    alert(myThis.myHello); // myThis is 'closed-in'; defined outside 
}); 

tenga en cuenta la función anónima. esto en ese alcance es el alcance de la función. myThis es el este del alcance externo, donde se ha definido myHello. Compruébalo en firebug.

'esto' siempre se refiere al alcance actual de la ejecución, creo. Si desea tomar el alcance actual y conservarlo, haga lo que hizo, que es asignarlo a otra variable.

1
$.get('http://example.com', function(){ 
    // inside jQuery ajax functions - this == the options used for the ajax call 
}); 

¿Qué sucede cuando el cierre se pasa fuera del alcance de do_stuff() (en este caso $ .get())?

Nada "pasa" a ella, esto sigue siendo este para que el cierre, el contexto de ejecución de las funciones llamadas desde el cierre no heredan automáticamente this.

¿Incluye myThis una copia de esta o una referencia a esta?

Todas las asignaciones no escalares son referencias en JavaScript. Por lo tanto, es una referencia al this, si cambia las propiedades en cualquiera, cambian para ambos.

¿En general no es una buena idea usar esto en cierres?

Por lo general, es una buena idea usar this en cierres, pero si usted va a utilizar cierres dentro de esa necesidad de acceder a la misma this, sus buenas prácticas para hacer exactamente lo que hizo: var someName = this; y luego acceso usando someName

Cuestiones relacionadas