3
votes

Accédez à ce Object.keys à l'intérieur de ES6

Disons que j'ai le code suivant:

class Test {
  constructor(obj) {
    this.obj = obj
  }

  change() {
    Object.keys(this.obj).forEach(function(name, index) {
      alert(this.obj[name])
    })
  }

}

objct = {
  n1: 1,
  n2: 2
}

var test = new Test(objct)
test.change()

Cependant, lorsque j'exécute ceci, j'obtiens l'erreur suivante:

Uncaught TypeError: Impossible de lire la propriété 'obj' de undefined

Je crois que cela signifie que ce n'est pas défini dans la fonction des clés d'objet. Comment puis-je accéder à this.obj à l'intérieur des clés Object et forloop?

Selon ce réponse , je peux utiliser map , mais j'ai besoin du nom de propriété et du tableau index à l'intérieur du forloop comme bien. Et voici un violon du code, si cela peut vous aider. Je vous remercie!!!


2 commentaires

essayez de changer cette fonction: function (name, index) {alert (this.obj [name])}) en une fonction de flèche pour obtenir le contexte 'this'


N'utilisez pas forEach . Utilisez pour… dans ou pour… sur .


4 Réponses :


6
votes

C'est parce que le contexte de fonction (le this ) de la fonction que vous passez dans forEach () est maintenant window et c'est n'est plus votre instance Test .

Si vous utilisez plutôt une fonction-flèche , vous pourrez conserver la portée lexicale em> et votre this pointerait vers l'instance actuelle ( Test ):

Object.keys(this.obj).forEach((name, index) =>
{
    alert(this.obj[name])
});

Voir MDN


1 commentaires

En fait, c'est indéfini , pas window .



5
votes

this fait référence au contexte actuel de la fonction et donc dans votre exemple this.obj recherche obj dans le contexte de rappel de forEach . Vous pouvez résoudre ce problème en gardant une référence au contexte actuel, c'est-à-dire ceci OU en utilisant une fonction de flèche à la place. contexte actuel dans la variable self

class Test {
  constructor(obj){
    this.obj = obj
  }

  change() {
  Object.keys(this.obj).forEach((name, index) => {
    alert(this.obj[name])
  })
  }

}

objct = {
        n1: 1,
      n2:2
}

var test = new Test(objct)
test.change()

Solution préférée ou abrégée : en utilisant les fonctions fléchées

class Test {
  constructor(obj){
    this.obj = obj
  }

  change() {
    var self = this
    Object.keys(this.obj).forEach(function (name, index) {
    alert(self.obj[name])
  })
  }

}

objct = {
  n1: 1,
  n2: 2
}

var test = new Test(objct)
test.change()


1 commentaires

merci pour la réponse, il était intéressant de se connaître, ne l'ayant jamais utilisé auparavant. JS évolue rapidement :)



1
votes

Les fonctions anonymes ne sont pas liées au contexte, elles n'ont donc pas accès à this ; Mais les fonctions fléchées le sont. Utilisez-le à la place.

class Test {
  constructor(obj) {
    this.obj = obj
  }

  change() {
    Object.keys(this.obj).forEach((name, index) => {
      alert(this.obj[name])
    })
  }

}

objct = {
  n1: 1,
  n2: 2
}

var test = new Test(objct)
test.change()


0 commentaires

4
votes

Une leçon de portée classique en Javascript.

Il y a deux façons de faire cela:

En utilisant bind () qui lie la portée de votre forEach à la fonction parent

change() {
  Object.keys(this.obj).forEach((name, index) => {
    alert(this.obj[name])
  })
  }

en utilisant => qui est une autre façon de lier la portée de votre forEach à la fonction parente

change() {
  Object.keys(this.obj).forEach(function(name, index) {
    alert(this.obj[name])
  }.bind(this))
  }


1 commentaires

Merci pour la réponse. bind ressemble à une solution de contournement lorsque vous travaillez avec une compatibilité de navigateur plus ancienne :) (oui, je n'aime pas babel)