web-dev-qa-db-fra.com

Fonction flèche dans le littéral objet

J'essaie de comprendre pourquoi une fonction de flèche dans un littéral objet est appelée avec window comme this. Quelqu'un peut-il me donner un aperçu?

var arrowObject = {
  name: 'arrowObject',
  printName: () => {
    console.log(this);
  }
};

// Prints: Window {external: Object, chrome: Object ...}
arrowObject.printName();

Et un objet qui fonctionne comme prévu:

var functionObject = {
  name: 'functionObject',
  printName: function() {
    console.log(this);
  }
};

// Prints: Object {name: "functionObject"}
functionObject.printName();

Selon Babel REPL , ils sont transposés en

var arrowObject = {
  name: 'arrowObject',
  printName: function printName() {
    console.log(undefined);
  }
};

Et

var functionObject = {
  name: 'functionObject',
  printName: function printName() {
    console.log(this);
  }
};

Pourquoi arrowObject.printName(); n'est-il pas appelé avec arrowObject comme this?

Les journaux de la console proviennent de Fiddle (où use strict; N'est pas utilisé).

22
Dennis S

Notez que la traduction Babel suppose un mode strict, mais votre résultat avec window indique que vous exécutez votre code en mode lâche. Si vous dites à Babel d'assumer le mode lâche, sa transpilation est différente :

var _this = this;                    // **

var arrowObject = {
  name: 'arrowObject',
  printName: function printName() {
    console.log(_this);              // **
  }
};

Notez le _this Global et console.log(_this);, au lieu du console.log(undefined); de votre transpilation en mode strict.

J'essaie de comprendre pourquoi une fonction de flèche dans un littéral objet est appelée avec window comme this.

Parce que les fonctions fléchées héritent this du contexte dans lequel elles sont créées. Apparemment, où vous faites cela:

var arrowObject = {
  name: 'arrowObject',
  printName: () => {
    console.log(this);
  }
};

...this est window. (Ce qui suggère que vous n'utilisez pas le mode strict; je recommanderais de l'utiliser là où il n'y a pas de raison claire de ne pas le faire.) S'il s'agissait d'autre chose, comme le undefined du code global en mode strict, this dans la fonction flèche serait plutôt cette autre valeur.

Il peut être un peu plus clair quel est le contexte dans lequel la fonction flèche est créée si nous divisons votre initialiseur en son équivalent logique:

var arrowObject = {};
arrowObject.name = 'arrowObject';
arrowObject.printName = () => {
  console.log(this);
};
34
T.J. Crowder