2011-11-19 24 views
7

Tengo un objeto con un método que me gustaría pasar a una función como una devolución de llamada. Sin embargo, dentro de la devolución de llamada, this ya no hace referencia a mi objeto. Por qué no?objeto en función de miembro de devolución de llamada

Estoy familiarizado con el uso de una variable para evitar el problema cuando se pasa una función literal:

var obj = { 
    a: function() { 
     var me = this; 

     console.log(this); 

     setTimeout(function() { 
      console.log(this); // Not obj 
      console.log(me); // This works! 
     }, 100); 
    } 
}; 

¿Cómo se puede arreglar lo que en este caso?

var obj = { 
    b: function() { 
     setTimeout(this.callback, 100); 
    }, 
    callback: function() { 
     console.log(this); // =(
    } 
}; 

Respuesta

9

Sí, puede ser algo complicado en Javascript. El problema es que su valor depende de how you call the function.

obj.callback(); //ok 

var f = obj.callback; 
f(); //does not look like a method call 
    //Javascript does not pass the this! 

La solución habitual está pasando una devolución de llamada envoltorio como lo hizo en b), excepto que el nombre común para la variable me es that (a veces se ve self demasiado)

var that = this; 
setTimeout(function(){ return that.callback(); }, 300); 

La otra alternativa es utilizar el método de enlace de funciones

setTimeout(this.callback.bind(this) , 300) 

Nota que se unen no es compatible con IE 8 (es posible que tenga una cuña en Ese caso).


Para más:

Maintaining the reference to "this" in Javascript when using callbacks and closures

+1

nota que Function.prototype.bind es parte de ECMAScript5, no funcionará en IE6/7/8 y Firefox 3.6 (y menos relevante, ya que de auto -actualizaciones, cromos más antiguos como <6) – gonchuki

+0

. Es más fácil de entender "esto" cuando se piensa en variables/propiedades como punteros a funciones en lugar de ser funciones en sí mismas. 'obj.callback' es solo un puntero a una función que no tiene idea de quién lo señala y de hecho puede tener cualquier cantidad de punteros a la misma. Así que debido a esto, 'this' para la función solo se puede resolver durante el tiempo de llamada y tiene algunas reglas simples para ello. Así que recuerde siempre que se resuelva durante la llamada-tiempo y la vida será más fácil :) Gracias – Esailija

+0

@Esailija –

Cuestiones relacionadas