Quand dois-je utiliser les fonctions Flèche dans ECMAScript 6?

407

La question s'adresse aux personnes qui ont pensé au style de code dans le contexte du prochain ECMAScript 6 (Harmony) et qui ont déjà travaillé avec le langage.

Avec () => {}et function () {}nous obtenons deux façons très similaires d'écrire des fonctions dans ES6. Dans d'autres langages, les fonctions lambda se distinguent souvent en étant anonymes, mais dans ECMAScript, toute fonction peut être anonyme. Chacun des deux types a des domaines d'utilisation uniques (à savoir quand thisdoit être lié explicitement ou explicitement ne pas être lié). Entre ces domaines, il existe un grand nombre de cas où l'une ou l'autre notation fera l'affaire.

Les fonctions fléchées dans ES6 ont au moins deux limitations:

  • Ne fonctionne pas avec newet ne peut pas être utilisé lors de la créationprototype
  • Fixé thislié à la portée à l'initialisation

Ces deux limitations mises à part, les fonctions fléchées pourraient théoriquement remplacer les fonctions normales presque n'importe où. Quelle est la bonne approche en les utilisant dans la pratique? Les fonctions fléchées doivent-elles être utilisées, par exemple:

  • "partout où ils fonctionnent", c'est-à-dire que partout où une fonction n'a pas à être agnostique à propos de la thisvariable et nous ne créons pas d'objet.
  • seulement "partout où ils sont nécessaires", c'est-à-dire les écouteurs d'événements, les délais d'attente, qui doivent être liés à une certaine portée
  • avec des fonctions "courtes" mais pas avec des fonctions "longues"
  • uniquement avec des fonctions qui ne contiennent pas d'autre fonction flèche

Ce que je recherche, c'est un guide pour sélectionner la notation de fonction appropriée dans la future version d'ECMAScript. La directive devra être claire, afin qu'elle puisse être enseignée aux développeurs dans une équipe, et être cohérente afin qu'elle ne nécessite pas de refactoring constant dans les deux sens d'une notation de fonction à l'autre.

lyschoening
la source
33
Vous considérez Fixed this bound to scope at initialisationcomme une limitation?
thefourtheye du
12
C'est un avantage, mais cela peut aussi être une limitation si vous prévoyez de réutiliser la fonction en dehors du contexte d'origine. Par exemple, lors de l'ajout dynamique d'une fonction à une classe via Object.prototype. Ce que je veux dire par «limitation», c'est que changer la valeur de thisest quelque chose que vous pouvez faire avec des fonctions régulières mais pas avec des fonctions fléchées.
lyschoening le
1
Honnêtement, je pense que les directives de style de codage sont plutôt subjectives. Ne vous méprenez pas, je pense qu'ils sont importants, mais il n'y a pas une seule ligne directrice qui convient à tout le monde.
Felix Kling
Je ne pense pas que ce Fixed this bound to scope at initialisationsoit une limitation. :) Jetez un oeil à cet article: exploringjs.com/es6/ch_arrow-functions.html
NgaNguyenDuy
3
@thefourtheye, "limitation" signifie ici "limitation car un traducteur de code automatique stupide ne pouvait pas remplacer aveuglément un par un autre et supposer que tout fonctionnerait comme prévu".
Pacerier

Réponses:

322

Il y a quelque temps, notre équipe a migré tout son code (une application AngularJS de taille moyenne) vers JavaScript compilé à l'aide de Traceur Babel . J'utilise maintenant la règle générale suivante pour les fonctions dans ES6 et au-delà:

  • Utilisation functiondans la portée globale et pour les Object.prototypepropriétés.
  • À utiliser classpour les constructeurs d'objets.
  • Utilisez =>partout ailleurs.

Pourquoi utiliser les fonctions fléchées presque partout?

  1. Sécurité de la portée: lorsque les fonctions fléchées sont utilisées de manière cohérente, tout est garanti pour utiliser la même chose thisObjectque la racine. Si même un seul rappel de fonction standard est mélangé à un tas de fonctions fléchées, il y a une chance que la portée devienne foirée.
  2. Compacité: les fonctions fléchées sont plus faciles à lire et à écrire. (Cela peut sembler opiniâtre, je vais donc donner quelques exemples plus loin).
  3. Clarté: lorsque presque tout est une fonction de flèche, tout régulier functionressort immédiatement pour définir la portée. Un développeur peut toujours rechercher la functiondéclaration suivante pour voir de quoi il thisObjects'agit.

Pourquoi toujours utiliser des fonctions régulières sur la portée globale ou la portée du module?

  1. Pour indiquer une fonction qui ne doit pas accéder au thisObject.
  2. L' windowobjet (portée globale) est mieux adressé explicitement.
  3. De nombreuses Object.prototypedéfinitions ont une portée globale (pensez, String.prototype.truncateetc.) et celles-ci doivent généralement être de type functionquand même. L'utilisation constante functionsur la portée globale permet d'éviter les erreurs.
  4. De nombreuses fonctions dans la portée globale sont des constructeurs d'objets pour les définitions de classe à l'ancienne.
  5. Les fonctions peuvent être nommées 1 . Cela présente deux avantages: (1) Il est moins gênant d'écrire function foo(){}que const foo = () => {}- en particulier en dehors des autres appels de fonction. (2) Le nom de la fonction apparaît dans les traces de pile. Bien qu'il soit fastidieux de nommer chaque rappel interne, nommer toutes les fonctions publiques est probablement une bonne idée.
  6. Les déclarations de fonctions sont hissées (ce qui signifie qu'elles sont accessibles avant d'être déclarées), ce qui est un attribut utile dans une fonction utilitaire statique.


Constructeurs d'objets

La tentative d'instanciation d'une fonction flèche lève une exception:

var x = () => {};
new x(); // TypeError: x is not a constructor

Un avantage clé des fonctions par rapport aux fonctions fléchées est donc qu'elles fonctionnent comme des constructeurs d'objets:

function Person(name) {
    this.name = name;
}

Cependant, la définition de classe de brouillon 2 ES Harmony fonctionnellement identique est presque aussi compacte:

class Person {
    constructor(name) {
        this.name = name;
    }
}

Je m'attends à ce que l'utilisation de l'ancienne notation soit finalement découragée. La notation du constructeur d'objet peut encore être utilisée par certains pour de simples usines d'objets anonymes où les objets sont générés par programme, mais pas pour beaucoup d'autre chose.

Lorsqu'un constructeur d'objet est nécessaire, il faut envisager de convertir la fonction en a classcomme indiqué ci-dessus. La syntaxe fonctionne également avec les fonctions / classes anonymes.


Lisibilité des fonctions fléchées

Le meilleur argument probablement pour s'en tenir aux fonctions régulières - que la sécurité de la portée soit maudite - serait que les fonctions fléchées sont moins lisibles que les fonctions régulières. Si votre code n'est pas fonctionnel en premier lieu, alors les fonctions fléchées peuvent ne pas sembler nécessaires, et lorsque les fonctions fléchées ne sont pas utilisées de manière cohérente, elles semblent laides.

ECMAScript a beaucoup changé depuis qu'ECMAScript 5.1 nous a donné la fonctionnalité Array.forEach, Array.mapet toutes ces fonctionnalités de programmation fonctionnelle qui nous font utiliser des fonctions où des boucles for auraient été utilisées auparavant. Le JavaScript asynchrone a beaucoup décollé. ES6 expédiera également un Promiseobjet, ce qui signifie encore plus de fonctions anonymes. Il n'y a pas de retour en arrière pour la programmation fonctionnelle. En JavaScript fonctionnel, les fonctions fléchées sont préférables aux fonctions normales.

Prenez par exemple ce morceau de code 3 (particulièrement déroutant) :

function CommentController(articles) {
    this.comments = [];

    articles.getList()
        .then(articles => Promise.all(articles.map(article => article.comments.getList())))
        .then(commentLists => commentLists.reduce((a, b) => a.concat(b)));
        .then(comments => {
            this.comments = comments;
        })
}

Le même morceau de code avec des fonctions régulières:

function CommentController(articles) {
    this.comments = [];

    articles.getList()
        .then(function (articles) {
            return Promise.all(articles.map(function (article) { 
                return article.comments.getList();
            }));
        })
        .then(function (commentLists) {
            return commentLists.reduce(function (a, b) {
                return a.concat(b); 
            });
        })
        .then(function (comments) {
            this.comments = comments;
        }.bind(this));
}

Alors que n'importe laquelle des fonctions fléchées peut être remplacée par une fonction standard, il y aurait très peu à gagner à le faire. Quelle version est plus lisible? Je dirais le premier.

Je pense que la question de l'utilisation des fonctions fléchées ou des fonctions régulières deviendra moins pertinente au fil du temps. La plupart des fonctions deviendront soit des méthodes de classe, qui font disparaître le functionmot - clé, soit elles deviendront des classes. Les fonctions resteront utilisées pour patcher les classes via le Object.prototype. En attendant, je suggère de réserver le functionmot - clé pour tout ce qui devrait vraiment être une méthode de classe ou une classe.


Remarques

  1. Les fonctions de flèche nommées ont été différées dans la spécification ES6 . Ils pourraient encore être ajoutés à une future version.
  2. Selon le projet de spécification "Les déclarations / expressions de classe créent une paire fonction constructeur / prototype exactement comme pour les déclarations de fonction" tant qu'une classe n'utilise pas le extendmot - clé. Une différence mineure est que les déclarations de classe sont des constantes, contrairement aux déclarations de fonctions.
  3. Remarque sur les blocs dans les fonctions flèches à instruction unique: j'aime utiliser un bloc partout où une fonction fléchée est appelée pour l'effet secondaire seul (par exemple, affectation). De cette façon, il est clair que la valeur de retour peut être ignorée.
lyschoening
la source
4
L'autre fois que vous voudriez utiliser, functionc'est quand vous ne voulez thispas être lié, non? Mon scénario le plus courant pour cela est les événements, où vous pouvez thisfaire référence à l'objet (généralement le nœud DOM) qui a déclenché l'événement.
Brett
13
En fait, je pense que dans l'exemple 3, les fonctions régulières sont plus lisibles. Même les non-programmeurs pourraient deviner ce qui se passe. Avec les flèches, vous devez savoir exactement comment elles fonctionnent pour comprendre cet exemple. Peut-être que plus de nouvelles lignes aideraient l'exemple de la flèche, mais je ne sais pas. Juste mes 2 cents mais les flèches me font grincer des dents (mais je ne les ai pas encore utilisées, donc je serai peut-être bientôt converti.)
Spencer
3
@Spencer, c'est un bon point. D'après ma propre expérience, =>finit par mieux paraître avec le temps. Je doute que les non-programmeurs ressentent très différemment les deux exemples. Si vous écrivez du code ES2016, vous n'allez pas non plus normalement utiliser ces nombreuses fonctions fléchées. Dans cet exemple, en utilisant async / wait et une compréhension de tableau, vous vous retrouveriez avec une seule fonction de flèche dans l' reduce()appel.
lyschoening
3
Je suis entièrement d'accord avec Spencer que les fonctions régulières sont beaucoup plus lisibles dans cet exemple.
jonschlinkert
2
Bonne réponse, merci! personnellement, j'utilise autant que possible des flèches dans la portée mondiale. Cela ne me laisse presque aucune «fonction». Pour moi, une «fonction» dans le code signifie un cas spécial qui doit ressortir et être soigneusement examiné.
kofifus
81

Selon la proposition , les flèches visaient "à aborder et à résoudre plusieurs points communs douloureux du traditionnel Function Expression". Ils avaient l'intention d'améliorer les choses en liant thislexicalement et en offrant une syntaxe concise.

cependant,

  • On ne peut pas toujours se lier thislexicalement
  • La syntaxe de la fonction flèche est délicate et ambiguë

Par conséquent, les fonctions fléchées créent des opportunités de confusion et d'erreurs et doivent être exclues du vocabulaire d'un programmeur JavaScript, remplacées par functionexclusivement.

Concernant lexical this

this est problématique:

function Book(settings) {
    this.settings = settings;
    this.pages = this.createPages();
}
Book.prototype.render = function () {
    this.pages.forEach(function (page) {
        page.draw(this.settings);
    }, this);
};

Les fonctions fléchées visent à résoudre le problème où nous devons accéder à une propriété de l' thisintérieur d'un rappel. Il y a déjà plusieurs façons de le faire: On pourrait assigner thisà une variable, utiliser bindou utiliser le 3e argument disponible sur les Arrayméthodes d'agrégation. Pourtant, les flèches semblent être la solution de contournement la plus simple, donc la méthode pourrait être refactorisée comme ceci:

this.pages.forEach(page => page.draw(this.settings));

Cependant, considérez si le code a utilisé une bibliothèque comme jQuery, dont les méthodes se lient thisspécialement. Maintenant, il y a deux thisvaleurs à gérer:

Book.prototype.render = function () {
    var book = this;
    this.$pages.each(function (index) {
        var $page = $(this);
        book.draw(book.currentPage + index, $page);
    });
};

Nous devons utiliser functionafin eachde lier thisdynamiquement. Nous ne pouvons pas utiliser de fonction de flèche ici.

Gérer plusieurs thisvaleurs peut également être source de confusion, car il est difficile de savoir de quel thisauteur parlait:

function Reader() {
    this.book.on('change', function () {
        this.reformat();
    });
}

L'auteur avait-il réellement l'intention d'appeler Book.prototype.reformat? Ou a-t-il oublié de se lier thiset avait-il l'intention d'appeler Reader.prototype.reformat? Si nous changeons le gestionnaire en une fonction de flèche, nous nous demanderons également si l'auteur voulait la dynamique this, mais a choisi une flèche car elle tient sur une seule ligne:

function Reader() {
    this.book.on('change', () => this.reformat());
}

On peut se poser la question suivante: "Est-il exceptionnel que les flèches soient parfois la mauvaise fonction à utiliser? Peut-être que si nous n'avons que rarement besoin de thisvaleurs dynamiques , il serait toujours acceptable d'utiliser des flèches la plupart du temps."

Mais demandez-vous ceci: «Serait-il« utile »de déboguer du code et de découvrir que le résultat d'une erreur a été provoqué par un« cas de bord »?» «Je préfère éviter les problèmes non seulement la plupart du temps, mais 100% du temps.

Il y a une meilleure façon: toujours utiliser function(donc thispeut toujours être lié dynamiquement), et toujours référencer thisvia une variable. Les variables sont lexicales et prennent plusieurs noms. L'affectation thisà une variable rendra vos intentions claires:

function Reader() {
    var reader = this;
    reader.book.on('change', function () {
        var book = this;
        book.reformat();
        reader.reformat();
    });
}

De plus, toujours assigner thisà une variable (même quand il y a une seule thisou aucune autre fonction) garantit que ses intentions restent claires même après que le code est changé.

De plus, la dynamique thisn'est guère exceptionnelle. jQuery est utilisé sur plus de 50 millions de sites Web (au moment de la rédaction de ce rapport en février 2016). Voici d'autres API liant thisdynamiquement:

  • Mocha (~ 120k téléchargements hier) expose les méthodes de ses tests via this.
  • Grunt (~ 63 000 téléchargements hier) expose les méthodes de création de tâches via this.
  • Backbone (~ 22k téléchargements hier) définit les méthodes d'accès this.
  • Les API d'événement (comme les DOM) font référence à un EventTargetavec this.
  • Les API prototypées corrigées ou étendues font référence aux instances avec this.

(Statistiques via http://trends.builtwith.com/javascript/jQuery et https://www.npmjs.com .)

Il est probable que vous thisayez déjà besoin de liaisons dynamiques .

Un lexical thisest parfois attendu, mais parfois non; tout comme une dynamique thisest parfois attendue, mais parfois non. Heureusement, il existe un meilleur moyen, qui produit et communique toujours la liaison attendue.

Concernant la syntaxe laconique

Les fonctions fléchées ont réussi à fournir une "forme syntaxique plus courte" pour les fonctions. Mais ces fonctions plus courtes vous rendront-elles plus efficaces?

Est x => x * x"plus facile à lire" que function (x) { return x * x; }? C'est peut-être le cas, car il est plus susceptible de produire une seule ligne de code courte. Accor à Dyson L'influence de la vitesse de lecture et de la longueur de ligne sur l'efficacité de la lecture à l'écran ,

Une longueur de ligne moyenne (55 caractères par ligne) semble prendre en charge une lecture efficace à des vitesses normales et rapides. Cela a produit le plus haut niveau de compréhension. . .

Des justifications similaires sont faites pour l'opérateur conditionnel (ternaire) et pour les ifinstructions sur une seule ligne .

Cependant, écrivez- vous vraiment les fonctions mathématiques simples annoncées dans la proposition ? Mes domaines ne sont pas mathématiques, donc mes sous-programmes sont rarement aussi élégants. Au contraire, je vois souvent que les fonctions fléchées dépassent une limite de colonne et se terminent par une autre ligne en raison de l'éditeur ou du guide de style, ce qui annule la «lisibilité» selon la définition de Dyson.

On pourrait se poser la question: «Que diriez-vous d'utiliser la version courte pour les fonctions courtes, lorsque cela est possible? Mais maintenant, une règle stylistique contredit une contrainte de langage: "Essayez d'utiliser la notation de fonction la plus courte possible, en gardant à l'esprit que parfois seule la notation la plus longue se liera thiscomme prévu." Cette confusion rend les flèches particulièrement susceptibles d'être utilisées à mauvais escient.

Il existe de nombreux problèmes avec la syntaxe de la fonction flèche:

const a = x =>
    doSomething(x);

const b = x =>
    doSomething(x);
    doSomethingElse(x);

Ces deux fonctions sont syntaxiquement valides. Mais ce doSomethingElse(x);n'est pas dans le corps de b, c'est juste une déclaration de haut niveau mal indentée.

Lors de l'expansion vers la forme bloc, il n'y a plus d'implicite return, que l'on pourrait oublier de restaurer. Mais l'expression n'a peut- être été conçue que pour produire un effet secondaire, alors qui sait si une explicite returnsera nécessaire à l'avenir?

const create = () => User.create();

const create = () => {
    let user;
    User.create().then(result => {
        user = result;
        return sendEmail();
    }).then(() => user);
};

const create = () => {
    let user;
    return User.create().then(result => {
        user = result;
        return sendEmail();
    }).then(() => user);
};

Ce qui peut être prévu comme paramètre de repos peut être analysé en tant qu'opérateur d'étalement:

processData(data, ...results => {}) // Spread
processData(data, (...results) => {}) // Rest

L'affectation peut être confondue avec les arguments par défaut:

const a = 1;
let x;
const b = x => {}; // No default
const b = x = a => {}; // "Adding a default" instead creates a double assignment
const b = (x = a) => {}; // Remember to add parens

Les blocs ressemblent à des objets:

(id) => id // Returns `id`
(id) => {name: id} // Returns `undefined` (it's a labeled statement)
(id) => ({name: id}) // Returns an object

Qu'est-ce que ça veut dire?

() => {}

L'auteur avait-il l'intention de créer un no-op, ou une fonction qui renvoie un objet vide? (Dans cet esprit, devrions-nous jamais placer {après =>? Devrions-nous nous limiter à la syntaxe d'expression uniquement? Cela réduirait davantage la fréquence des flèches.)

=>ressemble <=et >=:

x => 1 ? 2 : 3
x <= 1 ? 2 : 3

if (x => 1) {}
if (x >= 1) {}

Pour invoquer une expression de fonction flèche immédiatement, il faut placer ()à l'extérieur, mais placer ()à l'intérieur est valide et peut être intentionnel.

(() => doSomething()()) // Creates function calling value of `doSomething()`
(() => doSomething())() // Calls the arrow function

Bien que, si l'on écrit (() => doSomething()());avec l'intention d'écrire une expression de fonction immédiatement invoquée, rien ne se passera.

Il est difficile de prétendre que les fonctions fléchées sont "plus compréhensibles" compte tenu des cas ci-dessus. On pourrait apprendre toutes les règles spéciales requises pour utiliser cette syntaxe. ça en vaut vraiment la peine?

La syntaxe de functionest généralisée sans exception. Utiliser functionexclusivement signifie que le langage lui-même empêche d'écrire du code déroutant. Pour écrire des procédures qui doivent être comprises syntaxiquement dans tous les cas, je choisis function.

Concernant une ligne directrice

Vous demandez une ligne directrice qui doit être "claire" et "cohérente". L'utilisation des fonctions fléchées aboutira finalement à un code syntaxiquement valide et logiquement invalide, les deux formes de fonction étant entrelacées, de manière significative et arbitraire. Par conséquent, j'offre ce qui suit:

Directive pour la notation des fonctions dans ES6:

  • Créez toujours des procédures avec function.
  • Attribuez toujours thisà une variable. Ne pas utiliser () => {}.
Jackson
la source
5
Rédaction intéressante sur la vue d'un programmeur fonctionnel sur JavaScript. Je ne suis pas sûr d'être d'accord avec l'argument des variables privées. OMI, peu de gens en ont vraiment besoin; ceux qui le feront auront probablement également besoin d'autres fonctionnalités contractuelles et opteront pour une extension de langage comme TypeScript. Je peux certainement voir l'attrait d'un selfau lieu d'un ceci. Vos pièges de fonction de flèche indiqués sont également tous valides, et les mêmes normes que sur d'autres déclarations qui peuvent aller sans accolades s'appliquent également ici; sinon, je pense qu'avec votre argument, on pourrait tout aussi bien défendre les fonctions fléchées partout.
lyschoening du
7
"Le fait d'avoir plusieurs façons de faire crée des vecteurs inutiles d'arguments et de dissensions sur le lieu de travail et dans la communauté linguistique. Il serait préférable que la grammaire linguistique ne nous permette pas de faire de mauvais choix." D'accord. Belle rédaction! Je pense que les fonctions fléchées sont en fait un pas en arrière. Sur un sujet différent, je souhaite que mes collègues cessent d'essayer de transformer JavaScript en C # avec une série de définitions de prototypes. C'est dégoutant. Je devrais lier anonymement votre message :)
Spencer
11
Très bien écrit! Bien que je sois en désaccord avec la plupart de vos points, il est important de considérer le point de vue opposé.
minexew
4
Pas les fonctions fléchées mais le comportement bizarre de thisest le problème de Javascript. Au lieu d'être implicitement lié, thisdoit être passé comme argument explicite.
bob
5
Msgstr " Toujours utiliser la fonction (pour que cela puisse toujours être lié dynamiquement), et toujours y faire référence via une variable. ". Je ne pourrais pas être plus en désaccord!
48

Les fonctions fléchées ont été créées pour simplifier la fonction scopeet résoudre le thismot - clé en le rendant plus simple. Ils utilisent la =>syntaxe, qui ressemble à une flèche.

Remarque: il ne remplace pas les fonctions existantes. Si vous remplacez chaque syntaxe de fonction par des fonctions fléchées, cela ne fonctionnera pas dans tous les cas.

Jetons un coup d'œil à la syntaxe ES5 existante. Si le thismot - clé était à l'intérieur de la méthode d'un objet (une fonction qui appartient à un objet), à quoi se référerait-il?

var Actor = {
  name: 'RajiniKanth',
  getName: function() {
     console.log(this.name);
  }
};
Actor.getName();

L'extrait ci-dessus fait référence à un objectet imprime le nom "RajiniKanth". Explorons l'extrait ci-dessous et voyons ce que cela signifierait ici.

var Actor = {
  name: 'RajiniKanth',
  movies: ['Kabali', 'Sivaji', 'Baba'],
  showMovies: function() {
   this.movies.forEach(function(movie) {
     alert(this.name + " has acted in " + movie);
   });
  }
};

Actor.showMovies();

Et maintenant, si le thismot - clé était à l'intérieur de method’s function?

Ici, cela ferait référence à window objectla inner functioncomme à sa perte scope. Car this, fait toujours référence au propriétaire de la fonction dans laquelle il se trouve, dans ce cas - puisqu'il est désormais hors de portée - l'objet window / global.

Lorsqu'il se trouve à l'intérieur d'une objectméthode, le functionpropriétaire de l'objet est l'objet. Ainsi, le mot-clé this est lié à l'objet. Pourtant, lorsqu'il se trouve à l'intérieur d'une fonction, qu'il soit autonome ou dans une autre méthode, il se référera toujours à l' window/globalobjet.

var fn = function(){
  alert(this);
}

fn(); // [object Window]

Il existe des moyens de résoudre ce problème en ES5soi, examinons cela avant de plonger dans les fonctions fléchées ES6 pour savoir comment le résoudre.

En règle générale, vous créez une variable en dehors de la fonction interne de la méthode. Maintenant , les ‘forEach’gains de la méthode d' accès à thiset ainsi les object’spropriétés et leurs valeurs.

var Actor = {
  name: 'RajiniKanth',
  movies: ['Kabali', 'Sivaji', 'Baba'],
  showMovies: function() {
   var _this = this;
   this.movies.forEach(function(movie) {
     alert(_this.name + " has acted in " + movie);
   });
  }
};

Actor.showMovies();

utiliser bindpour attacher le thismot-clé qui fait référence à la méthode au fichier method’s inner function.

var Actor = {
  name: 'RajiniKanth',
  movies: ['Kabali', 'Sivaji', 'Baba'],
  showMovies: function() {
   this.movies.forEach(function(movie) {
     alert(this.name + " has acted in " + movie);
   }.bind(this));
  }
};

Actor.showMovies();

Maintenant, avec la ES6fonction flèche, nous pouvons traiter le lexical scopingproblème de manière plus simple.

var Actor = {
  name: 'RajiniKanth',
  movies: ['Kabali', 'Sivaji', 'Baba'],
  showMovies: function() {
   this.movies.forEach((movie) => {
     alert(this.name + " has acted in " + movie);
   });
  }
};

Actor.showMovies();

Arrow functionssont plus comme des instructions de fonction, sauf qu’elles bindle font parent scope. Si le arrow function is in top scope, l' thisargument fera référence à window/global scope, tandis qu'une fonction de flèche à l' intérieur d' une fonction régulière aura son argument le même que sa fonction extérieure.

Avec les arrowfonctions thisest lié à l'enveloppe scopeau moment de la création et ne peut pas être modifié. Le nouvel opérateur, bind, call et apply n'ont aucun effet sur cela.

var asyncFunction = (param, callback) => {
  window.setTimeout(() => {
  callback(param);
  }, 1);
};

// With a traditional function if we don't control
// the context then can we lose control of `this`.
var o = {
  doSomething: function () {
  // Here we pass `o` into the async function,
  // expecting it back as `param`
  asyncFunction(o, function (param) {
  // We made a mistake of thinking `this` is
  // the instance of `o`.
  console.log('param === this?', param === this);
  });
  }
};

o.doSomething(); // param === this? false

Dans l'exemple ci-dessus, nous avons perdu le contrôle de cela. Nous pouvons résoudre l'exemple ci-dessus en utilisant une référence variable de thisou en utilisant bind. Avec ES6, il devient plus facile de gérer le thiscomme il se doit lexical scoping.

var asyncFunction = (param, callback) => {
  window.setTimeout(() => {
  callback(param);
  }, 1);
};

var o = {
  doSomething: function () {
  // Here we pass `o` into the async function,
  // expecting it back as `param`.
  //
  // Because this arrow function is created within
  // the scope of `doSomething` it is bound to this
  // lexical scope.
  asyncFunction(o, (param) => {
  console.log('param === this?', param === this);
  });
  }
};

o.doSomething(); // param === this? true

Quand ne pas utiliser les fonctions Flèche

À l'intérieur d'un objet littéral.

var Actor = {
  name: 'RajiniKanth',
  movies: ['Kabali', 'Sivaji', 'Baba'],
  getName: () => {
     alert(this.name);
  }
};

Actor.getName();

Actor.getNameest défini avec une fonction de flèche, mais lors de l'invocation, il alerte non défini car il this.namereste undefinedle contexte window.

Cela se produit parce que la fonction flèche lie le contexte lexicalement avec la window objectportée externe ... ie. L'exécution this.nameest équivalente à window.name, ce qui n'est pas défini.

Prototype d'objet

La même règle s'applique lors de la définition de méthodes sur un prototype object. Au lieu d'utiliser une fonction de flèche pour définir la méthode sayCatName, ce qui apporte une erreurcontext window :

function Actor(name) {
  this.name = name;
}
Actor.prototype.getName = () => {
  console.log(this === window); // => true
  return this.name;
};
var act = new Actor('RajiniKanth');
act.getName(); // => undefined

Invoquer des constructeurs

thisdans une invocation de construction est l'objet nouvellement créé. Lors de l'exécution de la nouvelle Fn (), le contexte de laconstructor Fn est un nouvel objet: this instanceof Fn === true.

this est configuré à partir du contexte englobant, c'est-à-dire la portée externe qui le rend non affecté à un objet nouvellement créé.

var Message = (text) => {
  this.text = text;
};
// Throws "TypeError: Message is not a constructor"
var helloMessage = new Message('Hello World!');

Rappel avec contexte dynamique

La fonction flèche lie contextstatiquement la déclaration et n'est pas possible de la rendre dynamique. Attacher des écouteurs d'événements aux éléments DOM est une tâche courante dans la programmation côté client. Un événement déclenche la fonction de gestionnaire avec ceci comme élément cible.

var button = document.getElementById('myButton');
button.addEventListener('click', () => {
  console.log(this === window); // => true
  this.innerHTML = 'Clicked button';
});

thisest une fenêtre dans une fonction de flèche définie dans le contexte global. Lorsqu'un événement de clic se produit, le navigateur tente d'appeler la fonction de gestionnaire avec le contexte du bouton, mais la fonction flèche ne change pas son contexte prédéfini. this.innerHTMLest équivalent window.innerHTMLet n'a aucun sens.

Vous devez appliquer une expression de fonction, ce qui permet de changer cela en fonction de l'élément cible:

var button = document.getElementById('myButton');
button.addEventListener('click', function() {
  console.log(this === button); // => true
  this.innerHTML = 'Clicked button';
});

Lorsque l'utilisateur clique sur le bouton, celui-ci dans la fonction de gestionnaire est le bouton. this.innerHTML = 'Clicked button'Modifie ainsi correctement le texte du bouton pour refléter l'état cliqué.

Références: https://dmitripavlutin.com/when-not-to-use-arrow-functions-in-javascript/

Thalaivar
la source
Eh bien, je dois admettre que "le meilleur se trouve au milieu" . Voté pour la déclaration, que les fonctions fléchées ne couvriront aucun cas d'utilisation de fonction possible. Ils sont vraiment conçus pour résoudre seulement une partie des problèmes communs. Passer à eux complètement sera une exagération.
BlitZ
@DmitriPavlutin: Vérifiez mon article mis à jour, c'est une collection de beaucoup de choses ... peut-être devrais-je publier une référence.
Thalaivar
2
Votre code après la ligne «en utilisant bind pour attacher le mot-clé this qui fait référence à la méthode à la fonction interne de la méthode». contient des bogues. Avez-vous testé le reste de vos exemples?
Isaac Pak
L'un using bind to attach the this keyword that refers to the method to the method’s inner function.a des erreurs de syntaxe.
Coda Chang
Devrait êtrevar Actor = { name: 'RajiniKanth', movies: ['Kabali', 'Sivaji', 'Baba'], showMovies: function() { this.movies.forEach(function(movie){ alert(this.name + ' has acted in ' + movie); }.bind(this)) } }; Actor.showMovies();
Coda Chang
14

Fonctions fléchées - la fonctionnalité ES6 la plus utilisée jusqu'à présent ...

Utilisation: toutes les fonctions ES5 doivent être remplacées par des fonctions fléchées ES6, sauf dans les scénarios suivants:

Les fonctions fléchées ne doivent PAS être utilisées:

  1. Quand nous voulons un levage de fonction
    • car les fonctions fléchées sont anonymes.
  2. Quand on veut utiliser this/ argumentsdans une fonction
    • comme les fonctions fléchées n'ont pas this/ argumentsd'elles-mêmes, elles dépendent de leur contexte extérieur.
  3. Quand nous voulons utiliser une fonction nommée
    • car les fonctions fléchées sont anonymes.
  4. Lorsque nous voulons utiliser la fonction comme constructor
    • car les fonctions fléchées n'ont pas les leurs this.
  5. Lorsque nous voulons ajouter une fonction en tant que propriété dans un littéral d'objet et utiliser un objet dedans
    • car nous ne pouvons pas y accéder this(qui devrait être l'objet lui-même).

Comprenons certaines des variantes des fonctions fléchées pour mieux comprendre:

Variante 1 : lorsque nous voulons passer plusieurs arguments à une fonction et en renvoyer une valeur.

Version ES5 :

var multiply = function (a,b) {
    return a*b;
};
console.log(multiply(5,6)); //30

Version ES6 :

var multiplyArrow = (a,b) => a*b;
console.log(multiplyArrow(5,6)); //30

Remarque: le functionmot clé n'est PAS requis. =>est requis. {}sont facultatifs, lorsque nous ne fournissons pas {} returnest implicitement ajouté par JavaScript et lorsque nous fournissons, {}nous devons ajouter returnsi nous en avons besoin.

Variante 2 : lorsque nous voulons passer un seul argument à une fonction et en renvoyer une valeur.

Version ES5 :

var double = function(a) {
    return a*2;
};
console.log(double(2)); //4

Version ES6 :

var doubleArrow  = a => a*2;
console.log(doubleArrow(2)); //4

Remarque: Lorsque vous passez un seul argument, nous pouvons omettre les parenthèses ().

Variante 3 : lorsque nous ne voulons PAS passer d'argument à une fonction et ne voulons pas retourner de valeur.

Version ES5 :

var sayHello = function() {
    console.log("Hello");
};
sayHello(); //Hello

Version ES6 :

var sayHelloArrow = () => {console.log("sayHelloArrow");}
sayHelloArrow(); //sayHelloArrow

Variante 4 : lorsque nous voulons revenir explicitement des fonctions fléchées.

Version ES6 :

var increment = x => {
  return x + 1;
};
console.log(increment(1)); //2

Variante 5 : lorsque nous voulons renvoyer un objet à partir des fonctions fléchées.

Version ES6 :

var returnObject = () => ({a:5});
console.log(returnObject());

Remarque: Nous devons encapsuler l'objet entre parenthèses, ()sinon JavaScript ne peut pas faire la différence entre un bloc et un objet.

Variante 6 : Les fonctions fléchées n'ont PAS arguments(un objet de type tableau) qui leur sont propres, elles dépendent du contexte extérieur pour arguments.

Version ES6 :

function foo() {
  var abc = i => arguments[0];
  console.log(abc(1));
};    
foo(2); // 2

Note: fooest une fonction ES5, avec un argumentstableau comme objet et un argument qui lui est passé est 2donc arguments[0]pour fooest 2.

abcest une fonction ES6 flèche car il ne dispose pas de son propre argumentsoù elle imprime arguments[0]de fooce contexte extérieur de la place.

Variante 7 : Les fonctions fléchées n'ont PAS thisleur propre fonction, elles dépendent du contexte extérieur pourthis

Version ES5 :

var obj5 = {
  greet: "Hi, Welcome ",
  greetUser : function(user) {
        setTimeout(function(){
        console.log(this.greet + ": " +  user); // "this" here is undefined.
        });
     }
};

obj5.greetUser("Katty"); //undefined: Katty

Remarque: Le rappel passé à setTimeout est une fonction ES5 et elle a sa propre thisqui n'est pas définie dans l' use-strictenvironnement, donc nous obtenons une sortie:

undefined: Katty

Version ES6 :

var obj6 = {
  greet: "Hi, Welcome ",
  greetUser : function(user) {
    setTimeout(() => console.log(this.greet + ": " +  user)); 
      // this here refers to outer context
   }
};

obj6.greetUser("Katty"); //Hi, Welcome: Katty

Remarque: Le rappel est passé à setTimeoutest une fonction ES6 flèche et il ne dispose pas de son propre thisil qu'il faut à partir de son contexte extérieur qui est ce greetUserqui a thisqui est par obj6conséquent nous obtenons sortie:

Hi, Welcome: Katty

Divers: Nous ne pouvons pas utiliser les newfonctions fléchées. Les fonctions fléchées n'ont pas de prototypepropriété. Nous n'avons PAS de liaison thislorsque la fonction flèche est invoquée via applyou call.

Manishz90
la source
6

En plus des excellentes réponses jusqu'à présent, je voudrais présenter une raison très différente pour laquelle les fonctions fléchées sont dans un certain sens fondamentalement meilleures que les fonctions JavaScript "ordinaires". Pour les besoins de la discussion, supposons temporairement que nous utilisons un vérificateur de type tel que TypeScript ou "Flow" de Facebook. Considérez le module jouet suivant, qui est un code ECMAScript 6 valide plus des annotations de type Flow: (Je vais inclure le code non typé, qui résulterait de manière réaliste de Babel, à la fin de cette réponse, afin qu'il puisse réellement être exécuté.)

export class C {
  n : number;
  f1: number => number; 
  f2: number => number;

  constructor(){
    this.n = 42;
    this.f1 = (x:number) => x + this.n;
    this.f2 = function (x:number) { return  x + this.n;};
  }
}

Voyons maintenant ce qui se passe lorsque nous utilisons la classe C à partir d'un module différent, comme ceci:

let o = { f1: new C().f1, f2: new C().f2, n: "foo" };
let n1: number = o.f1(1); // n1 = 43
console.log(n1 === 43); // true
let n2: number = o.f2(1); // n2 = "1foo"
console.log(n2 === "1foo"); // true, not a string!

Comme vous pouvez le voir, le vérificateur de type a échoué ici: f2 était censé retourner un nombre, mais il a renvoyé une chaîne!

Pire encore, il semble qu'aucun vérificateur de type concevable ne puisse gérer les fonctions JavaScript ordinaires (sans flèche), car le "this" de f2 ne se produit pas dans la liste d'arguments de f2, donc le type requis pour "this" n'a pas pu être ajouté. comme une annotation à f2.

Ce problème affecte-t-il également les personnes qui n'utilisent pas de vérificateurs de type? Je pense que oui, car même lorsque nous n'avons pas de types statiques, nous pensons qu'ils sont là. ("Les premiers paramètres doivent être un nombre, le second une chaîne", etc.) Un argument "ce" caché qui peut ou non être utilisé dans le corps de la fonction rend notre comptabilité mentale plus difficile.

Voici la version exécutable non typée, qui serait produite par Babel:

class C {
    constructor() {
        this.n = 42;
        this.f1 = x => x + this.n;
        this.f2 = function (x) { return x + this.n; };
    }
}

let o = { f1: new C().f1, f2: new C().f2, n: "foo" };
let n1 = o.f1(1); // n1 = 43
console.log(n1 === 43); // true
let n2 = o.f2(1); // n2 = "1foo"
console.log(n2 === "1foo"); // true, not a string!

Carsten Führmann
la source
4

Je reste fidèle à tout ce que j'ai écrit dans ma première réponse dans ce fil. Cependant, mon opinion sur le style de code s'est développée depuis lors, j'ai donc une nouvelle réponse à cette question qui s'appuie sur ma dernière.

Concernant lexical this

Dans ma dernière réponse, j'ai délibérément renoncé à une croyance sous-jacente que j'ai au sujet de cette langue, car elle n'était pas directement liée à l'argument que je faisais. Néanmoins, sans que cela soit explicitement indiqué, je peux comprendre pourquoi beaucoup de gens rechignent simplement à ma recommandation de ne pas utiliser de flèches, quand ils trouvent les flèches si utiles.

Ma conviction est la suivante: nous ne devrions pas utiliser thisen premier lieu. Par conséquent, si une personne évite délibérément d'utiliser thisdans son code, la thiscaractéristique «lexicale » des flèches est de peu ou pas de valeur. De plus, selon la prémisse qui thisest une mauvaise chose, le traitement de Arrow thisest moins une «bonne chose»; il s'agit plutôt d'une forme de contrôle des dommages pour une autre fonctionnalité de langage incorrect.

Je pense que cela non plus ne se produit pas pour certaines personnes, mais même pour ceux à qui cela se produit, ils doivent toujours se retrouver à travailler dans des bases de code où thisapparaît cent fois par fichier, et un peu (ou beaucoup) de contrôle des dommages est tout. une personne raisonnable pouvait espérer. Les flèches peuvent donc être bonnes, d'une certaine manière, lorsqu'elles améliorent une mauvaise situation.

Même s'il est plus facile d'écrire du code avec thisdes flèches que sans elles, les règles d'utilisation des flèches restent très complexes (voir: thread actuel). Ainsi, les directives ne sont ni «claires» ni «cohérentes», comme vous l'avez demandé. Même si les programmeurs connaissent les ambiguïtés des flèches, je pense qu'elles haussent les épaules et les acceptent quand même, car la valeur du lexical les thiséclipse.

Tout cela est une préface à la réalisation suivante: si l'on n'utilise pas this, alors l'ambiguïté à propos de ce thisque les flèches provoquent normalement devient inutile. Les flèches deviennent plus neutres dans ce contexte.

Concernant la syntaxe laconique

Lorsque j'ai écrit ma première réponse, j'étais d'avis que même l'adhésion servile aux meilleures pratiques était un prix intéressant à payer si cela signifiait que je pouvais produire un code plus parfait. Mais j'ai finalement réalisé que la concision peut également servir de forme d'abstraction qui peut également améliorer la qualité du code - suffisamment pour justifier parfois de s'écarter des meilleures pratiques.

En d'autres termes: bon sang, je veux aussi des fonctions à une ligne!

Concernant une ligne directrice

Avec la possibilité de thisfonctions de flèche -neutre et la justesse valant la peine d'être poursuivie, j'offre la ligne directrice plus clémente suivante:

Directive pour la notation des fonctions dans ES6:

  • Ne pas utiliser this.
  • Utilisez des déclarations de fonctions pour les fonctions que vous appelleriez par nom (car elles sont hissées).
  • Utilisez les fonctions fléchées pour les rappels (car elles ont tendance à être terser).
Jackson
la source
D'accord à 100% avec votre section "Guide pour la notation des fonctions dans ES6" en bas - en particulier avec les fonctions de levage et de rappel en ligne. Bonne réponse!
Jeff McCloud
1

D'une manière simple,

var a =20; function a(){this.a=10; console.log(a);} 
//20, since the context here is window.

Un autre exemple:

var a = 20;
function ex(){
this.a = 10;
function inner(){
console.log(this.a); //can you guess the output of this line.
}
inner();
}
var test = new ex();

Rép: La console afficherait 20.

La raison étant que chaque fois qu'une fonction est exécutée, sa propre pile est créée, dans cet exemple, la exfonction est exécutée avec l' newopérateur afin qu'un contexte soit créé, et quand il innerest exécuté, JS crée une nouvelle pile et exécute la innerfonction a global contextbien qu'il y ait un contexte local.

Donc, si nous voulons que la innerfonction ait un contexte local, exalors nous devons lier le contexte à la fonction interne.

Les flèches résolvent ce problème, au lieu de prendre le, Global contextils prennent le local contexts'il existe. Dans le given example,cela prendra new ex()comme this.

Ainsi, dans tous les cas où la liaison est explicite, les flèches résolvent le problème par défaut.

Rajendra kumar Vankadari
la source
1

Les fonctions fléchées ou Lambdas, ont été introduites dans ES 6. Outre son élégance dans la syntaxe minimale, la différence fonctionnelle la plus notable est la portée de l' this intérieur d'une fonction fléchée

Dans les expressions de fonction régulières , le thismot clé est lié à différentes valeurs en fonction du contexte dans lequel il est appelé.

Dans les fonctions flèches , thisest lié lexicalement , ce qui signifie qu'il se ferme thisde la portée dans laquelle la fonction flèche a été définie (portée parent) et ne change pas, peu importe où et comment il est appelé / appelé.

Limitations Fonctions fléchées comme méthodes sur un objet

// this = global Window
let objA = {
 id: 10,
 name: "Simar",
 print () { // same as print: function() 
  console.log(`[${this.id} -> ${this.name}]`);
 }
}
objA.print(); // logs: [10 -> Simar]
objA = {
 id: 10,
 name: "Simar",
 print: () => {
  // closes over this lexically (global Window)
  console.log(`[${this.id} -> ${this.name}]`);
 }
};
objA.print(); // logs: [undefined -> undefined]

Dans le cas objA.print()où la print()méthode définie à l'aide de regular function , cela fonctionnait en se résolvant thiscorrectement à l' objAinvocation de la méthode mais échouait lorsqu'elle était définie comme une =>fonction de flèche . C'est parce que thisdans une fonction régulière lorsqu'elle est invoquée comme méthode sur un objet ( objA), c'est l'objet lui-même. Cependant, dans le cas d'une fonction flèche, thisse lie lexicalement à l' thisétendue englobante où elle a été définie (global / Window dans notre cas) et reste la même pendant son invocation en tant que méthode objA.

Avantages des fonctions fléchées par rapport aux fonctions régulières dans les méthodes d'un objet MAIS uniquement lorsque l' thison s'attend à ce qu'il soit fixé et lié à la définition de l'heure.

/* this = global | Window (enclosing scope) */

let objB = {
 id: 20,
 name: "Paul",
 print () { // same as print: function() 
  setTimeout( function() {
    // invoked async, not bound to objB
    console.log(`[${this.id} -> ${this.name}]`);
  }, 1)
 }
};
objB.print(); // logs: [undefined -> undefined]'
objB = {
 id: 20,
 name: "Paul",
 print () { // same as print: function() 
  setTimeout( () => {
    // closes over bind to this from objB.print()
    console.log(`[${this.id} -> ${this.name}]`);
  }, 1)
 }
};
objB.print(); // logs: [20 -> Paul]

Dans le cas objB.print()où la print()méthode est définie comme une fonction qui appelle console.log([$ {this.id} -> {this.name}] de )manière asynchrone comme rappel setTimeout , thisrésolue correctement objBlorsqu'une fonction de flèche a été utilisée comme rappel mais a échoué lorsque le rappel a été défini comme une fonction régulière. C'est parce que la =>fonction de flèche est passée à setTimeout(()=>..)fermée sur thislexicalement de son parent ie. invocation objB.print()qui l'a défini. En d'autres termes, la =>fonction flèche est passée à à setTimeout(()==>...liée à objBcar c'est thisparce que l'invocation de objB.print() thisétait objBelle-même.

Nous pourrions facilement utiliser Function.prototype.bind(), pour faire fonctionner le rappel défini comme une fonction régulière, en le liant à la bonne this.

const objB = {
 id: 20,
 name: "Singh",
 print () { // same as print: function() 
  setTimeout( (function() {
    console.log(`[${this.id} -> ${this.name}]`);
  }).bind(this), 1)
 }
}
objB.print() // logs: [20 -> Singh]

Cependant, les fonctions fléchées sont utiles et moins sujettes aux erreurs dans le cas des rappels asynchrones où nous connaissons thisau moment de la définition des fonctions auxquelles elles sont et doivent être liées.

Limitation des fonctions fléchées là où cela doit changer d'une invocation à l'autre

À tout moment, nous avons besoin d'une fonction qui thispeut être modifiée au moment de l'invocation, nous ne pouvons pas utiliser les fonctions fléchées.

/* this = global | Window (enclosing scope) */

function print() { 
   console.log(`[${this.id} -> {this.name}]`);
}
const obj1 = {
 id: 10,
 name: "Simar",
 print // same as print: print
};
obj.print(); // logs: [10 -> Simar]
const obj2 = {
 id: 20,
 name: "Paul",
};
printObj2 = obj2.bind(obj2);
printObj2(); // logs: [20 -> Paul]
print.call(obj2); // logs: [20 -> Paul]

Rien de ce qui précède ne fonctionnera avec la fonction flèche const print = () => { console.log([$ {this.id} -> {this.name}] );}car elle thisne peut pas être modifiée et restera liée à la thisportée englobante où elle a été définie (global / Window). Dans tous ces exemples, nous avons invoqué la même fonction avec des objets différents ( obj1et obj2) l'un après l'autre, tous deux créés après la print()déclaration de la fonction.

Ce sont des exemples artificiels, mais réfléchissons à des exemples plus réels. Si nous devions écrire notre reduce()méthode de manière similaire à celle qui fonctionne arrays , nous ne pouvons pas la définir à nouveau comme un lambda, car elle doit être déduite thisdu contexte d'invocation, c'est-à-dire. le tableau sur lequel il a été invoqué

Pour cette raison, les constructorfonctions ne peuvent jamais être définies comme des fonctions flèches, comme thispour une fonction constructeur ne peut pas être définie au moment de sa déclaration. Chaque fois qu'une fonction constructeur est invoquée avec un newmot clé, un nouvel objet est créé qui est ensuite lié à cette invocation particulière.

De plus, lorsque les frameworks ou les systèmes acceptent une ou plusieurs fonctions de rappel à invoquer ultérieurement avec un contexte dynamique this , nous ne pouvons pas utiliser les fonctions fléchées, car il thispeut encore être nécessaire de changer à chaque appel. Cette situation se produit généralement avec les gestionnaires d'événements DOM

'use strict'
var button = document.getElementById('button');
button.addEventListener('click', function {
  // web-api invokes with this bound to current-target in DOM
  this.classList.toggle('on');
});
var button = document.getElementById('button');
button.addEventListener('click', () => {
  // TypeError; 'use strict' -> no global this
  this.classList.toggle('on');
});

C'est aussi la raison pour laquelle dans des cadres comme Angular 2+ et Vue.js s'attendent à ce que les méthodes de liaison de composant de modèle soient des fonctions / méthodes régulières thiscar leur invocation est gérée par les cadres pour les fonctions de liaison. (Angular utilise Zone.js pour gérer le contexte asynchrone pour les appels de fonctions de liaison de modèle de vue).

D'autre part, dans React , lorsque nous voulons passer la méthode d'un composant en tant que gestionnaire d'événements par exemple, <input onChange={this.handleOnchange} />nous devons définir handleOnchanage = (event)=> {this.props.onInputChange(event.target.value);}comme une fonction de flèche comme pour chaque invocation, nous voulons que ce soit la même instance du composant qui a produit le JSX pour le rendu Élément DOM.


Cet article est également disponible sur ma publication Medium . Si vous aimez l'artile, ou si vous avez des commentaires et suggestions, veuillez applaudir ou laisser des commentaires sur Medium .

Simar Singh
la source