2009-09-02 7 views
11

Estoy tratando de acceder a las variables miembro de una clase de prototipo en JavaScript en un controlador de eventos, algo que normalmente usaría la palabra clave "this" para (o "that" [copia de esto] en el caso de manejadores de eventos). No hace falta decir que me estoy metiendo en problemas."this" palabra clave en métodos de evento cuando se utiliza el objeto prototipo JavaScript

Tomemos, por ejemplo, este fragmento HTML:

<a id="myLink" href="#">My Link</a> 

Y este código JavaScript:

function MyClass() 
{ 
    this.field = "value" 
    this.link = document.getElementById("myLink"); 
    this.link.onclick = this.EventMethod; 
} 

MyClass.prototype.NormalMethod = function() 
{ 
    alert(this.field); 
} 

MyClass.prototype.EventMethod = function(e) 
{ 
    alert(this.field); 
} 

Crear instancias de un objeto MiClase y llamando NormalMethod funciona exactamente igual que espero que (alerta diciendo " valor "), pero al hacer clic en el enlace se obtiene un valor indefinido porque la palabra clave" this "ahora hace referencia al objetivo del evento (el elemento HTML anchor()).

Soy nuevo en el prototipo JavaScript estilo, pero en el pasado, con los cierres, simplemente he hecho una copia del "presente" en el constructor:

var that = this; 

Y entonces pude acceder a los miembros variables en los métodos de eventos a través del objeto "eso". Eso no parece funcionar con el código del prototipo. ¿Hay alguna otra manera de lograr esto?

Gracias.

+0

¿Se refiere a la librería Prototype o clases prototípicos de JavaScript en lugar rectas? –

+3

Respondiendo tres años tarde :) Pero para la posteridad: me estaba refiriendo a las clases prototípicas de JavaScript. – Michael

+0

Posible duplicado de [¿Cómo acceder al correcto 'this'/context dentro de una devolución de llamada?] (Http://stackoverflow.com/q/20279484/1048572)? – Bergi

Respuesta

9

Su "that=this" cierre idioma sigue siendo aplicable:

function MyClass() 
{ 
    ... 

    var that = this; 
    this.link.onclick = function() { 
     return that.EventMethod.apply(that, arguments); 

     // that.EventMethod() works too here, however 
     // the above ensures that the function closure 
     // operates exactly as EventMethod itself does. 

    }; 
} 
5

Usted debe tratar

this.link.onclick = this.EventMethod.bind(this); 
13

Es necesario:

this.link.onclick = this.EventMethod.bind(this); 

... 'bind' es parte de Prototype, y devuelve una función que llama a su método con 'this' configurado correctamente.

+0

¿Cómo 'onclick' obtiene acceso a la interfaz del evento? – Karl

+0

@Karl ¿Por "acceso a la interfaz de evento" quiere decir "recibir el objeto de evento como argumento"? El método 'bind' ** devuelve una función ** (con un' this' fijo), por lo que 'onclick = this.EventMethod' es básicamente lo mismo que' onclick = this.EventMethod.bind (this) '.En ambos casos, almacena una función en la propiedad 'onclick'; son idénticos en términos de cómo se manejan sus argumentos. Si su pregunta es más general acerca de cómo se pasan los argumentos a las funciones del oyente, esa es una pregunta bastante diferente a la que se hace aquí, y debería hacer una nueva pregunta. – apsillers

0

Como se indicó anteriormente, utilizar bind que es una parte de la biblioteca Prototype es una forma limpia de resolver este problema. Esta pregunta es un duplicado de otro SO cuestión que ha sido respondida aquí con la implementación del método de enlace sin incluir toda la biblioteca de prototipo:

https://stackoverflow.com/a/2025839/1180286

+0

Esa pregunta usa JQuery. Prefiero que una pregunta/respuesta pura de JavaScript sea el estándar. –

Cuestiones relacionadas