web-dev-qa-db-fra.com

Comment écrire une fonction de flèche nommée dans ES2015?

J'ai une fonction que j'essaye de convertir à la nouvelle syntaxe de flèche dans ES6. C'est une fonction nommée:

function sayHello(name) {
    console.log(name + ' says hello');
}

Est-il possible de lui donner un nom sans instruction var:

var sayHello = (name) => {
    console.log(name + ' says hello');
}

De toute évidence, je ne peux utiliser cette fonction qu'après l'avoir définie. Quelque chose comme suit:

sayHello = (name) => {
        console.log(name + ' says hello');
    }

Existe-t-il une nouvelle façon de faire cela dans ES6?

185
jhamm

Comment écrire une fonction de flèche nommée dans ES2015?

Vous le faites comme vous l'avez exclu dans votre question: vous le placez du côté droit d'un initialiseur d'affectation ou de propriété, où le nom de la variable ou de la propriété peut raisonnablement être utilisé comme nom par le moteur JavaScript. Il n'y a pas de autre moyen de le faire, mais cela est correct et entièrement couvert par la spécification.

Par spécification, cette fonction a un vrai nom, sayHello:

var sayHello = name => {
    console.log(name + ' says hello');
};

Ceci est défini dans Opérateurs d'assignation> Sémantique d'exécution: Evaluation où il appelle l'opération _ abstraite SetFunctionName (cet appel est en cours) 1.e.iii).

De manière similaire, --- [Sémantique d'exécution: PropertyDefinitionEvaluation ) == appelle SetFunctionName et donne ainsi à cette fonction un vrai nom:

let o = {
    sayHello: name => {
        console.log(`${name} says hello`);
    }
};

Les moteurs modernes définissent déjà le nom interne de la fonction pour de telles déclarations; Edge a toujours le bit le rendant disponible en tant que name sur l'instance de fonction derrière un indicateur d'exécution.

Par exemple, dans Chrome ou Firefox, ouvrez la console Web, puis exécutez le fragment suivant:

"use strict";
let foo = () => { throw new Error(); };
console.log("foo.name is: " + foo.name);
try {
  foo();
} catch (e) {
  console.log(e.stack);
}

Sur Chrome 51 et supérieur et Firefox 53 et supérieur (et Edge 13 et supérieur avec un drapeau expérimental), lorsque vous l'exécutez, vous verrez:

 foo.name est: foo 
 Erreur 
 à foo (http://stacksnippets.net/js:14:23)
 à http: // stacksnippets .net/js: 17: 3 

Notez le foo.name is: foo et Error...at foo.

Sur Chrome 50 et versions antérieures, Firefox 52 et versions antérieures, et Edge sans l'indicateur expérimental, vous verrez ceci car ils ne possèdent pas encore la propriété Function#name:

 foo.name est: 
 Erreur 
 à foo (http://stacksnippets.net/js:14:23)
 à http: // stacksnippets. net/js: 17: 3 

Notez que le nom est manquant dans foo.name is:, mais il est affiché dans la trace de la pile. En réalité, la mise en œuvre de la namepropriété sur la fonction était moins prioritaire que certaines autres fonctionnalités d'ES2015; Chrome et Firefox l'ont maintenant; Edge l’a derrière un drapeau, probablement pas longtemps.

Évidemment, je ne peux utiliser cette fonction qu'après l'avoir définie

Correct. Il n’existe pas de syntaxe de fonction déclaration pour les fonctions de flèche, mais uniquement de syntaxe de fonction expression, et il n’existe aucune flèche équivalente au nom d’une expression de fonction nommée de style ancien (var f = function foo() { };). Donc, il n'y a pas d'équivalent à:

console.log(function fact(n) {
    if (n < 0) {
        throw new Error("Not defined for negative numbers");
    }
    return n == 0 ? 1 : n * fact(n - 1);
}(5)); // 120

Vous devez le diviser en deux expressions (je dirais que vous devriez le faire de toute façon ):

let fact = n => {
    if (n < 0) {
      throw new Error("Not defined for negative numbers.");
    }
    return n == 0 ? 1 : n * fact(n - 1);
};
console.log(fact(5));

Bien sûr, si vous avez pour placer ceci lorsqu'une seule expression est requise, vous pouvez toujours ... utiliser une fonction de flèche:

console.log((() => {
    let fact = n => {
        if (n < 0) {
            throw new Error("Not defined for negative numbers.");
        }
        return n == 0 ? 1 : n * fact(n - 1);
    };
    return fact(5);
})()); // 120

Je ne dis pas que c'est joli, mais ça marche si vous avez absolument besoin d'un simple wrapper d'expression.

187
T.J. Crowder

La syntaxe des flèches est une forme abrégée pour les fonctions anonymes. Les fonctions anonymes sont anonymes.

Les fonctions nommées sont définies avec le mot clé function.

86
Jörg W Mittag

Si vous voulez que la propriété .name de votre fonction de flèche soit définie, vous avez de la chance.

Si une fonction de flèche est définie à droite d'une expression d'affectation, le moteur prend le nom situé à gauche et l'utilise pour définir le .name de la flèche, par exemple.

var sayHello = (name) => {
    console.log(name + ' says hello');
}

sayHello.name //=== 'sayHello'

Cela dit, votre question semble être plus: "puis-je obtenir une fonction flèche pour hisser?". La réponse à cette question est un grand "non", j'en ai bien peur.

44
hughfdjackson

Il semble que cela sera possible avec ES7: https://babeljs.io/blog/2015/06/07/react-on-es6-plus#arrow-functions

L'exemple donné est:

class PostInfo extends React.Component {
  handleOptionsButtonClick = (e) => {
    this.setState({showOptionsModal: true});
  }
}

Le corps des fonctions de flèche ES6 partage le même lexical que le code qui les entoure, ce qui nous donne le résultat souhaité en raison de la portée des initialiseurs de propriété ES7.

Notez que pour que cela fonctionne avec babel, je devais activer la syntaxe la plus expérimentale de l’étape 0 de l’ES7. Dans mon fichier webpack.config.js, j'ai mis à jour le chargeur Babel comme suit:

{test: /\.js$/, exclude: /node_modules/, loader: 'babel?stage=0'},
0
Hamish Currie