493 votes

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

La question s'adresse aux personnes qui ont pensé de style de code dans le contexte de la prochaine ECMAScript 6 (Harmonie) et qui ont déjà travaillé avec la langue.

Avec () => {} et function () {} , nous obtenons deux façons très semblables à écrire des fonctions dans l'ES6. Dans d'autres langues lambda fonctions souvent se distinguer par le fait d'être anonyme, mais en ECMAScript toute fonction peut être anonyme. Chacun des deux types d'utilisation unique de domaines (notamment lorsqu' this doit être lié explicitement ou explicitement de ne pas être lié). Entre ces domaines, il ya un grand nombre de cas où la notation va faire.

Flèche fonctions dans l'ES6 ont au moins deux limites:

  • Ne pas travailler avec des new
  • Fixe this lié à portée lors de l'initialisation

Ces deux limitations de côté, flèche fonctions pourraient théoriquement remplacer régulièrement les fonctions de presque n'importe où. Quelle est la bonne approche à l'aide de leur dans la pratique? Devrait flèche fonctions être utilisé, par exemple:

  • "partout", c'est à dire partout, une fonction ne doit pas être agnostique à propos de la this variable et nous ne sommes pas la création d'un objet.
  • seulement "partout où ils sont nécessaires", c'est à dire des écouteurs d'événement, les délais d'attente, qui ont besoin d'être lié à une certaine portée
  • avec "court" mais pas avec "long" fonctions
  • seulement avec des fonctions qui ne contiennent pas d'une autre flèche en fonction de

Ce que je recherche est un guide pour la sélection de la fonction de la notation dans la future version de ECMAScript. La directive devra être claire, de sorte qu'il peut être enseigné à des développeurs au sein d'une équipe, et pour être cohérent, de sorte qu'il ne nécessite pas un refactoring et-vient à partir d'une fonction de la notation à l'autre.

370voto

lyschoening Points 1079

Notre équipe a récemment migré l'ensemble de ses code (de taille moyenne AngularJS app) à partir de CoffeeScript pour JavaScript compilé à l'aide de Traceur. Je suis maintenant à l'aide de la règle suivante pour l'Harmonie des fonctions:

  • Utiliser function dans la portée globale et pour Object.prototype propriétés.
  • Utiliser class pour l'objet des constructeurs.
  • Utiliser => partout ailleurs.

Pourquoi utiliser la flèche fonctions presque partout?

  1. Périmètre de sécurité: Lorsque la flèche de fonctions sont utilisés de manière cohérente, tout est garanti à utiliser le même thisObject comme la racine. Si même une seule norme de la fonction de rappel est mélangé avec un tas de flèche fonctions il y a un risque que le champ d'application deviendra foiré.
  2. Compacité: Flèche de fonctions sont plus faciles à lire et à écrire. (Cela peut paraître opiniâtre alors je vais donner quelques exemples plus loin).
  3. Clarté: Quand presque tout est une flèche fonction, tout function immédiatement bâtons permettant de définir la portée. Un développeur peut toujours regarder vers le haut le côté supérieur function déclaration de voir ce que l' thisObject .

Pourquoi toujours utiliser des fonctions sur la portée globale ou de la portée de module?

  1. Pour indiquer une fonction qui ne doit pas accéder à l' thisObject.
  2. L' window objet (de portée mondiale) il est préférable d'aborder de manière explicite.
  3. Nombre Object.prototype définitions de vivre dans la portée globale (pensez - String.prototype.truncate etc.) et ceux qui ont généralement pour être de type function de toute façon. L'utilisation systématique function sur la portée globale permet d'éviter les erreurs.
  4. De nombreuses fonctions dans la portée mondiale sont l'objet les constructeurs de style ancien définitions de classe.
  5. Les fonctions peuvent être nommés de1. Ceci a deux avantages: (1) Il est moins difficile à écrirefunction foo(){} que const foo = () => {} - en particulier en dehors des autres appels de fonction. (2) le nom de La fonction montre dans les traces de pile. Alors qu'il serait fastidieux de nom tous les internes de rappel, le nom de toutes les fonctions publiques est probablement une bonne idée.


Objet constructeurs

D'une tentative d'instancier une flèche fonction lève une exception:

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

Un des principaux avantages de fonctions sur la flèche fonctions est donc que les fonctions de la double objet constructeurs:

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

La fonctionnellement identiques2 ES Harmonie projet de définition de classe est presque aussi compact:

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

J'attends l'ancienne notation finira par être mal vu. Le constructeur de l'objet de la notation peut être encore utilisée par certains pour simple objet anonyme des usines où les objets sont généré par programmation, mais pas beaucoup d'autre.

Lorsqu'un constructeur de l'objet est nécessaire, on devrait envisager la conversion de la fonction à un class comme indiqué ci-dessus. La syntaxe fonctionne avec les fonctions anonymes/classes.


La lisibilité de la flèche fonctions

Probablement le meilleur argument pour s'en tenir à des fonctions classiques - champ d'application la sécurité des damnés - serait que la flèche fonctions sont moins lisibles que les fonctions. Si votre code n'est pas fonctionnel en premier lieu, puis flèche fonctions peuvent ne pas sembler nécessaire, et lorsque la flèche fonctions ne sont pas utilisés de manière cohérente, ils moche.

ECMAScript a un peu changé depuis ECMAScript 5.1 nous a donné la fonctionnelle Array.forEach, Array.map et l'ensemble de ces fonctionnelles, fonctionnalités de programmation que nous utilisons des fonctions où, pour des boucles aurait été utilisé avant. Asynchronous JavaScript a pris son envol un peu. ES6 sera également expédier un Promise objet, ce qui signifie encore plus de fonctions anonymes. Il n'y a pas de retour en arrière pour la programmation fonctionnelle. Fonctionnelle JavaScript, flèche fonctions sont préférables plus des fonctions classiques.

Prenez par exemple cette (particulièrement déroutant) morceau de code3:

function CommentCtrl($scope, articles) {
    $scope.comments = [];

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

Le même bout de code avec des fonctions classiques:

function CommentCtrl($scope, articles) {
    $scope.comments = [];

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

Tout en un de la flèche fonctions peut être remplacé par une fonction standard, il y aurait très peu à gagner à le faire. La version est plus lisible? Je dirais que la première.

Je pense que la question de savoir si l'utilisation de la flèche fonctions ou des fonctions classiques deviennent moins pertinentes au fil du temps. La plupart des fonctions sera les méthodes de la classe, qui font de loin avec l' function mot-clé, ou ils deviennent des classes. Fonctions resteront en usage pour patcher les classes par le biais de l' Object.prototype. En attendant je vous suggérons de réserver à l' function mot-clé pour tout ce qui doit vraiment être une méthode d'une classe ou d'une classe.


Notes

  1. Nommé flèche fonctions ont été reportés dans l'ES6 spec. Ils pourraient encore être ajoutés une future version.
  2. Selon le projet de norme "déclarations de Classe/les expressions de créer une fonction constructeur/prototype paire exactement comme pour les déclarations de fonction" tant qu'une classe n'utilise pas l' extend mot-clé.
  3. Note sur des blocs dans un état unique flèche fonctions: j'aime utiliser un bloc où une flèche fonction est appelée pour le côté effet seul (par exemple, la cession). De cette façon, il est clair que la valeur de retour peut être mis au rebut.

1voto

Kamil Tomšík Points 1181

Flèche fonctions ont été inventé en raison existants function(){} littérale suce juste.

  • il ne se lie lui-même à portée actuelle qui conduit à de mauvaises erreurs parfois même pour les programmeurs expérimentés.

  • à cause de cela, vous aurez besoin d' .bind(this) fonction à la portée de beaucoup de personnes le font et ce n'est pas très lisible

  • en outre, il est court et a fait de la "cartographie" peu plus facile plutôt que de soulignement, vous pouvez maintenant utiliser la fonctionnalité native qui est comparable en taille, lisibilité et devrait être encore plus rapide. _.map(people, 'name') vs people.map(p => p.name)

Il suffit de mettre, Flèche fonctions sont destinés à être de remplacement pour function(){}

  • donc, vous devriez vraiment utiliser partout où vous le pouvez
  • dans quelques très rares cas où vous avez besoin de votre code à exécuter à chaque fois dans différents this (ce qui semble vraiment très bizarre), vous pouvez vouloir function(){}

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