web-dev-qa-db-fra.com

Les fonctions fléchées ES6 ne fonctionnent pas sur le prototype?

Lorsque les fonctions de flèche ES6 ne semblent pas fonctionner pour affecter une fonction à un objet avec prototype.object. Considérez les exemples suivants:

function Animal(name, type){
 this.name = name;
  this.type = type;
  this.toString = () => `${this.name} is a ${this.type}`;

}
var myDog = new Animal('Max', 'Dog');
console.log(myDog.toString()); //Max is a Dog

L'utilisation explicite de la fonction flèche dans la définition d'objet fonctionne, mais l'utilisation des fonctions flèche avec la syntaxe Object.prototype ne permet pas:

function Animal2(name, type){
  this.name = name;
  this.type = type;
}
Animal2.prototype.toString = () => `${this.name} is a ${this.type}`;

var myPet2 = new Animal2('Noah', 'cat');
console.log(myPet2.toString()); //is a undefined

Tout comme une preuve de concept, l'utilisation de la syntaxe de chaîne de modèle avec la syntaxe Object.prototype fonctionne:

function Animal3(name, type){
  this.name = name;
  this.type = type;
}
Animal3.prototype.toString = function(){ return `${this.name} is a ${this.type}`;}

var myPet3 = new Animal3('Joey', 'Kangaroo');
console.log(myPet3.toString()); //Joey is a Kangaroo

Suis-je en train de manquer quelque chose d'évident? Je pense que l'exemple 2 devrait fonctionner logiquement, mais je suis perplexe par la sortie. J'imagine que c'est un problème de portée, mais je suis découragé par la sortie "est un indéfini".

ES6 Fiddle

27
Jonathan Lucas

Les fonctions fléchées fournissent un this lexical. Il utilise le this qui est disponible au moment où la fonction est évaluée.

Il est logiquement équivalent à (le code suivant n'est pas valide car vous ne pouvez pas avoir de variable nommée this):

(function(this){
   // code that uses "this"
 })(this)

Dans votre 1er exemple, la fonction flèche se trouve dans le constructeur et this pointe vers l'instance nouvellement générée.

Dans votre 3ème exemple, une fonction de flèche n'est pas utilisée et le comportement standard de this fonctionne comme toujours (le ceci dans la portée de la fonction).

Dans votre 2ème exemple, vous utilisez une fonction de flèche mais au niveau de l'étendue, elle est évaluée, this est global/non défini.

26
Amit

La fonction régulière renvoie une référence à l'objet JavaScript actuel, mais la fonction flèche renvoie la référence à l'objet de fenêtre globale.

Les fonctions régulières fonctionnent bien avec les objets à l'aide du nouveau mot-clé. Ils ont la fonction constructeur par laquelle les valeurs peuvent être initialisées lors de la création d'objet. Il peut être géré en utilisant le chaînage de prototype mais la fonction flèche n'a pas de fonction constructeur , le chaînage de prototype . Ils ne fonctionnent pas bien avec les objets. Ils ne peuvent pas être utilisés avec le nouveau mot clé pour affecter la mémoire.

Dans votre premier exemple, vous écrivez votre fonction de touche fléchée dans la fonction régulière, puis vous obtiendrez la sortie.

function Animal2(name, type){
    this.name = name;
    this.type = type;
}
Animal2.prototype.toString = function(){
    return () => `${this.name} is a ${this.type}`;
}

var myPet2 = new Animal2('Noah', 'cat');
console.log(myPet2.toString()()); //Noah is a cat

Référence: Différence entre la fonction régulière et la fonction des touches fléchées

0