13 votes

JavaScript : Accéder à 'this' lors de l'appel d'une fonction stockée dans une variable

Je suis novice en matière de JavaScript, c'est donc peut-être une question triviale :

J'essaie de construire un objet qui stocke une correspondance entre un ensemble d'entiers et certaines de ses méthodes, c'est-à-dire quelque chose comme ceci :

'use strict';

function Foo() {
    this.funcs = {
        1: this.func1,
        2: this.func2,
    }
}

Foo.prototype.func1 = function() {
    this.prop = 1;
}

Foo.prototype.func2 = function() {
    this.prop = 2;
}

J'aimerais alors pouvoir appeler des méthodes de Foo comme ça :

foo = new Foo();
var func = foo.funcs[1];
func();

Mais cela a pour conséquence : Cannot set property 'prop' of undefined es decir this ne fait pas référence à foo .

Quel est le problème ici et y a-t-il une meilleure façon de mettre cela en œuvre ?

6voto

Dacre Denny Points 17294

Il existe plusieurs façons d'obtenir ce que vous souhaitez, mais l'approche la plus robuste consiste à bind() chaque fonction à l'instance de Foo() qui est en cours d'instanciation.

Cela peut être fait en passant this a bind() de chaque fonction :

this.func1.bind(this)

Utilisation de bind() de cette manière garantit que this pour func1 et func2 est définie comme l'instance de Foo() . Cela permet de s'assurer que this.prop peuvent être accessibles et attribués comme prévu :

'use strict';

function Foo() {
  this.funcs = {
    /* Bind the functions to this Foo() instance */
    1: this.func1.bind(this),
    2: this.func2.bind(this),
  }
}

Foo.prototype.func1 = function() {
  this.prop = 1;
  console.log('called func1. this.prop =', this.prop);
}

Foo.prototype.func2 = function() {
  this.prop = 2;
  console.log('called func2. this.prop =', this.prop);
}

const foo = new Foo();
var func = foo.funcs[1];
func();

foo.funcs[2]();

Un autre élément clé à noter est le bind() ci-dessus garantit que, si vous acquérez et appelez une référence à l'une des fonctions de l'objet funcs comme indiqué dans votre message initial, qu'il fonctionnera comme prévu :

/* As per original post - doing this is not possible without .bind() */
var func = foo.funcs[1];
func();

Sans l'utilisation de bind() cette méthode d'acquisition et d'appel func échouera en raison de func n'étant pas lié à l'instance de Foo .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X