javascript - does - Hacer referencia a "esto" dentro de setInterval/setTimeout dentro de los métodos de prototipos de objetos
lexical binding javascript (2)
Normalmente asignaría una referencia "propia" alternativa cuando haga referencia a "esto" dentro de setInterval. ¿Es posible lograr algo similar dentro del contexto de un método prototipo? Los siguientes errores de código.
function Foo() {}
Foo.prototype = {
bar: function () {
this.baz();
},
baz: function () {
this.draw();
requestAnimFrame(this.baz);
}
};
A diferencia de un lenguaje como Python, un método de Javascript olvida que es un método después de extraerlo y pasarlo a otro lugar. Tu también puedes
Envuelva la llamada al método dentro de una función anónima
De esta forma, acceder a la propiedad baz
y llamarla al mismo tiempo, lo que es necesario para que this
se configure correctamente dentro de la llamada al método.
Deberá guardar this
desde la función externa en una variable auxiliar, ya que la función interna se referirá a un objeto diferente.
var that = this;
setInterval(function(){
return that.baz();
}, 1000);
Ajustar la llamada al método dentro de una función de flecha de grasa
En las implementaciones de Javascript que implementan la función de funciones de flecha , es posible escribir la solución anterior de una manera más concisa utilizando la sintaxis de la flecha fat:
setInterval( () => this.baz(), 1000 );
Las funciones anónimas de la flecha de grasa conservan this
de la función circundante, por lo que no es necesario utilizar var that = this
truco. Para ver si puede usar esta característica, consulte una tabla de compatibilidad como esta .
Use una función de enlace
Una última alternativa es usar una función como Function.prototype.bind o un equivalente de su biblioteca de Javascript favorita.
setInterval( this.baz.bind(this), 1000 );
//dojo toolkit example:
setInterval( dojo.hitch(this, ''baz''), 100);
hice una clase de proxy :)
function callback_proxy(obj, obj_method_name)
{
instance_id = callback_proxy.instance_id++;
callback_proxy.instances[instance_id] = obj;
return eval(''fn = function() { callback_proxy.instances[''+instance_id+''].''+obj_method_name+''(); }'');
}
callback_proxy.instance_id = 0;
callback_proxy.instances = new Array();
function Timer(left_time)
{
this.left_time = left_time; //second
this.timer_id;
this.update = function()
{
this.left_time -= 1;
if( this.left_time<=0 )
{
alert(''fin!'');
clearInterval(this.timer_id);
return;
}
}
this.timer_id = setInterval(callback_proxy(this, ''update''), 1000);
}
new Timer(10);