Référencer "ceci" à l'intérieur de SetInterval / setTimeout dans les méthodes de prototypes d'objets

Normalement, j'attribuerais une référence alternative "self" en référence à "this" dans setInterval. Est-il possible d'accomplir quelque chose de similaire dans le contexte d'une méthode prototype? Les erreurs de code suivantes.

function Foo() {} Foo.prototype = { bar: function () { this.baz(); }, baz: function () { this.draw(); requestAnimFrame(this.baz); } }; 

Contrairement à une langue comme Python, une méthode oublie sa méthode après l'extraire et la transmettre quelque part. Tu peux soit

Enrouler l'appel de la méthode dans une fonction anonyme

De cette façon, accéder à la propriété baz et l'appeler se produire en même temps, ce qui est nécessaire pour que this soit correctement configuré dans l'appel de méthode.

Étant donné que la fonction interne a une différence de l'extérieur, vous devez utiliser une variable auxiliaire.

 var that = this; setInterval(function(){ return that.baz(); }, 1000); 

Enrouler l'appel de la méthode dans une fonction de flèche en graisse

Certaines implémentations Javascript prennent en charge les fonctions de flèche , qui sont des fonctions anonymes qui héritent de la "fonction" de la fonction externe. Si cette fonctionnalité ES6 est disponible pour vous , il est possible de rendre la solution précédente un peu plus succincte:

 setInterval( () => this.baz(), 1000 ); 

Utilisez une fonction de liaison

Une alternative finale est d'utiliser une fonction telle que Function.prototype.bind ou un équivalent de votre bibliothèque Javascript préférée.

 setInterval( this.baz.bind(this), 1000 ); //dojo toolkit example: setInterval( dojo.hitch(this, 'baz'), 100); 
 requestAnimFrame(function() { this.baz.apply(this); }); 

J'ai fait une classe 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);