2012-07-06 10 views
6

No estoy seguro exactamente cómo formular mi pregunta, así que me presento un ejemplo:¿Cómo puedo agregar una función prototipo a un detector de eventos en la función de inicialización?

function foo() { 
    window.addEventListener("keydown", function(event) { 
     bar(event.keycode); 
} 

foo.prototype.bar = function (keycode) { 
//code 
} 

He intentado usar this.bar(), pero que se traduce en el uso de la window como this. ¿Hay alguna manera de hacerlo, o tendré que llamar a otro método de inicialización manualmente?

Respuesta

7

Enlaza this.bar a antes de aprobarlo.

function foo() { 
    window.addEventListener("keydown", this.bar.bind(this), false); 
} 


foo.prototype.bar = function (event) { 
    console.log(event.keyCode); 
} 

demostración http://jsfiddle.net/2tee4/

+0

Por qué unirse? 'window.addEventListener (" keydown ", this.bar, false);'? –

+1

@SheikhHeera, de modo que 'bar' se llama en el contexto de' this'; de lo contrario, se ejecutará en el ámbito global y no habrá una ventaja de haber enlazado una función de prototipo. – zzzzBov

+0

@SheikhHeera '.bind' corrige que el valor' this' es siempre el mismo sin importar cómo se llame a la función enlazada. En este caso, siempre será el objeto 'foo'. – Esailija

5

Una solución alternativa si no tiene Function.prototype.bind * disponible, y que está dispuesto a añadir funciones adicionales a Function.prototype sería para cerrar sobre la llamada a this.bar:

function foo() { 
    var self; 
    self = this; 
    window.addEventListener('keydown', function (e) { 
     self.bar(e); 
    }, false); 
} 
foo.prototype.bar = function (e) { 
    console.log(e.keyCode); 
} 

* aunque su uso de addEventListener sin me lleva a creer que Function.prototype.bind sería un acce elección ptable


Además, las bibliotecas, tales como jQuery puede incluir su propia forma de bind, jQuery es de jQuery.proxy.

+0

Gracias por las opciones adicionales, siempre es bueno tener más información. Aún más, cuando esto se convierta en un resultado de búsqueda en Google para otra persona ... – Bloodyaugust

4

Si su intención es agregar un nuevo oyente para cada foo creado, otra opción es hacer foo implementar la interfaz EventListener, y simplemente pasar this en lugar del controlador.

function Foo() { 
    window.addEventListener("keydown", this, false); 
} 

Foo.prototype.bar = "foobar"; 

Foo.prototype.handleEvent = function(e) { 
    console.log(e.type); // "mousedown" (for example) 
    console.log(this.bar); // "foobar" 
}; 

new Foo(); 

Tenga en cuenta que esto solo funciona con addEventListener().

DEMO:http://jsfiddle.net/k93Pr/

+2

+1, sería genial si jQuery lo soportara también, eliminaría una gran cantidad de parábolas '$ .proxy' :) – Esailija

+0

Dado que el comentario anterior se subió, voy a vincular mi ticket: http://bugs.jquery.com/ticket/12031: P – Esailija

+1

@Esailija: Será interesante ver si lo implementan. Sin embargo, no esperaría por jQuery. Solo hazlo un complemento. Aquí hay una implementación inicial simple y quizás ingenua. Solo necesita agregar soporte para las otras firmas de '.on()'. http://jsfiddle.net/suQEZ/ * (Sé que no necesitabas que te mostrara cómo. Es más por el bien de los demás.) * –

Cuestiones relacionadas