4 votes

Javascript 'this' retourne undefined dans un objet

J'ai le code suivant :

let myObj = {
  foo: "bar",
  getFoo: function() {
    console.log(this.foo);
  },
  method: function() {
    if (true) {
      window.addEventListener('scroll', this.getFoo);
    } else {
      window.removeEventListener('scroll', this.getFoo);
    }
  }
}

window.addEventListener('click', () => {
  myObj.method();
});

Il retourne indéfini, puisque (pour des raisons qui me sont inconnues) this fait référence à la window l'objet si getFoo est appelé en tant que callback dans un addEventListener fonction. Maintenant, si j'utilise une fonction flèche dans myObj.method -

window.addEventListener('scroll', () => {
  this.getFoo();
});

Cela devrait fonctionner, mais ensuite j'ai appelé une fonction anonyme et je ne peux pas faire removeEventListener plus tard. Comment pourrais-je faire fonctionner cela avec une fonction non anonyme ?

2voto

Mamun Points 31166

De MDN :

Une expression de fonction fléchée a une syntaxe plus courte qu'une expression de fonction et ne possède pas sa propre expression de fonction. this , arguments , super ou new.target . Ces expressions de fonction conviennent mieux aux fonctions qui ne sont pas des méthodes, et elles ne peuvent pas être utilisées comme constructeurs.

1voto

Blauharley Points 188

Vous pourriez utiliser appelez y lier pour appeler une méthode ou une fonction dans le contexte d'un certain objet de sorte que this fait référence au contexte de myObj :

let myObj = {
  foo: "bar",
  getFoo: function() {
    console.log(this.foo);
  },
  method: function() {
    if (true) {
      // here you have to use bind to create a function in a certain context
      window.addEventListener('scroll', this.getFoo.bind(this));
    } else {
      // here is the same
      window.removeEventListener('scroll', this.getFoo.bind(this));
    }
  }
}

window.addEventListener('click', () => {
  // create and call method in the context of myObj or any other object that is passed as first parameter of call
  myObj.method.call(myObj);
  // or because this in the function method refers to myObj at the beginning, just call method with obj
  myObj.method();
});

0voto

Bilger Yahov Points 157

Je vous conseille de jeter un coup d'oeil rapide aquí si vous voulez savoir comment le mot clé "this" fonctionne réellement...

Une solution à votre problème pourrait être de créer une variable appelée selfObj (ou quelque chose de similaire), puis en l'utilisant - pour accéder aux propriétés de myObj .

Edit : Cette version est testée et fonctionne. Je ne suis pas sûr que ce soit encore assez simple... La clé ici est de passer exactement les mêmes paramètres à la fois aux addEventListener y removeEventListener . C'est pour cette raison que j'ai créé le scrollEventListener pour l'attribut myObj objet. Ensuite, en utilisant déstructuration passer cela comme paramètres...

J'espère que cela vous aidera...

'use strict';

    let myObj = {
        foo: 'bar',
        counter: 0,
        getFoo: function() {
            const selfObj = this;
            console.log(selfObj.foo);
        },
        scrollEventListener: [
            'scroll',
            function () {
                myObj.getFoo();
            },
            true
        ],
        method: function() {
            const selfObj = this;
            selfObj.counter++;
            if (selfObj.counter % 2 === 0) {
                window.addEventListener(...selfObj.scrollEventListener);
            } else {
                window.removeEventListener(...selfObj.scrollEventListener);
            }
        }
    };

    window.addEventListener('click', () => {
        myObj.method();
    });

-1voto

S'il existe un this dans une fonction anonyme, this pointe vers la fenêtre, et non vers l'objet où vous l'avez défini, alors vous utilisez function , this est lié à l'objet où vous définissez cette fonction.

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