web-dev-qa-db-fra.com

Qu'est-ce que plusieurs fonctions de flèche signifient en javascript?

J'ai lu un tas de code react et je vois des choses comme ça que je ne comprends pas:

handleChange = field => e => {
  e.preventDefault();
  /// Do something here
}
301
jhamm

Comprendre les syntaxes disponibles des fonctions de flèches vous permettra de comprendre le comportement qu’elles présentent lorsqu’elles sont chaînées, comme dans les exemples que vous avez fournis.

Lorsqu'une fonction de flèche est écrite sans accolades de bloc, avec ou sans plusieurs paramètres, l'expression constituant le corps de la fonction est implicitement est renvoyée. Dans votre exemple, cette expression est une autre fonction de flèche.

No arrow funcs              Implicitly return `e=>{…}`    Explicitly return `e=>{…}` 
---------------------------------------------------------------------------------
function (field) {         |  field => e => {            |  field => {
  return function (e) {    |                             |    return e => {
      e.preventDefault()   |    e.preventDefault()       |      e.preventDefault()
  }                        |                             |    }
}                          |  }                          |  }

Un autre avantage de l’écriture de fonctions anonymes à l’aide de la syntaxe flèche est qu’elles sont liées lexicalement à la portée dans laquelle elles sont définies. De 'Fonctions de flèche' sur MDN }:

Une expression de fonction flèche a une syntaxe plus courte comparée à expressions de fonction et lie lexicalement la valeur ceci . Les fonctions de flèche sont toujours anonyme .

Ceci est particulièrement pertinent dans votre exemple, étant donné qu’il provient d’une application reactjs . Comme l'a souligné @naomik, dans React, vous accédez souvent à un fonctions membres du composant } à l'aide de this. Par exemple:

Unbound                     Explicitly bound            Implicitly bound 
------------------------------------------------------------------------------
function (field) {         |  function (field) {       |  field => e => {
  return function (e) {    |    return function (e) {  |    
      this.setState(...)   |      this.setState(...)   |    this.setState(...)
  }                        |    }.bind(this)           |    
}                          |  }.bind(this)             |  }
48
sdgluck

Un conseil général: si vous avez du mal à comprendre la nouvelle syntaxe JS et son compilation, vous pouvez vérifier babel . Par exemple, copier votre code dans babel et sélectionner le préréglage es2015 donnera un résultat comme celui-ci

handleChange = function handleChange(field) {
 return function (e) {
 e.preventDefault();
  // Do something here
   };
 };

 babel

39
Rahil Ahmad

Pensez-y comme ceci: chaque fois que vous voyez une flèche, vous la remplacez par function.
function parameters sont définis avant la flèche.
Donc dans votre exemple:

field => // function(field){}
e => { e.preventDefault(); } // function(e){e.preventDefault();}

et puis ensemble:

function (field) { 
    return function (e) { 
        e.preventDefault(); 
    };
}

À partir de la documentation :

// Basic syntax:
(param1, param2, paramN) => { statements }
(param1, param2, paramN) => expression
   // equivalent to:  => { return expression; }

// Parentheses are optional when there's only one argument:
singleParam => { statements }
singleParam => expression
32
LifeQuery

Bref et simple ????

C'est une fonction qui renvoie une autre fonction écrite de manière abrégée.

const handleChange = field => e => {
  e.preventDefault()
  // Do something here
}

// is equal to 
function handleChange(field) {
  return function(e) {
    e.preventDefault()
    // Do something here
  }
}

Pourquoi les gens le font

Avez-vous fait face lorsque vous avez besoin d’écrire une fonction qui peut être personnalisée? Ou vous devez écrire une fonction de rappel qui a des paramètres fixes (arguments), variables? Si votre réponse "yes" alors c'est la façon de le faire.

Par exemple, nous avons un button avec rappel onClick. Et nous devons passer id à la fonction, mais onClick n'accepte qu'un paramètre event, nous ne pouvons pas passer de paramètres supplémentaires dans les cas suivants:

const handleClick = (event, id) {
  event.preventDefault()
  // Dispatch some delete action by passing record id
}

Ça ne marchera pas!

Par conséquent, nous créons une fonction qui renverra une autre fonction avec son propre champ de variables sans aucune variable globale, car les variables globales sont mauvaises ????.

En dessous de la fonction handleClick(props.id)} sera appelée et retournera une fonction et aura id dans son étendue! Peu importe le nombre de fois où vous appuierez, les identifiants ne se modifieront pas, ils sont totalement isolés.

const handleClick = id => event {
  event.preventDefault()
  // Dispatch some delete action by passing record id
}

const Confirm = props => (
  <div>
    <h1>Are you sure to delete?</h1>
    <button onClick={handleClick(props.id)}>
      Delete
    </button>
  </div
)

2
sultan

L'exemple de votre question est celui d'un curried function qui utilise arrow function et qui a un implicit return pour le premier argument.

La fonction flèche lie lexicalement cette i.e, ils n'ont pas leur propre argument this mais prennent la valeur this de la portée englobante

Un équivalent du code ci-dessus serait

const handleChange = (field) {
  return function(e) {
     e.preventDefault();
     /// Do something here
  }.bind(this);
}.bind(this);

Une autre chose à noter à propos de votre exemple est que définir handleChange en tant que const ou une fonction. Vous l’utilisez probablement dans le cadre d’une méthode de classe et il utilise un class fields syntax

donc au lieu de lier directement la fonction externe, vous le lieriez dans le constructeur de la classe

class Something{
    constructor(props) {
       super(props);
       this.handleChange = this.handleChange.bind(this);
    }
    handleChange(field) {
        return function(e) {
           e.preventDefault();
           // do something
        }
    }
}

Une autre chose à noter dans l'exemple est la différence entre le retour implicite et explicite.

const abc = (field) => field * 2;

Ci-dessus est un exemple de retour implicite ie. il prend le champ value en argument et renvoie le résultat field*2 qui spécifie explicitement la fonction à renvoyer

Pour un retour explicite, vous indiquez explicitement à la méthode de renvoyer la valeur

const abc = () => { return field*2; }

Une autre chose à noter concernant les fonctions de flèche est qu’elles ne possèdent pas leur propre variable arguments, mais qu’elles héritent également de la portée des parents.

Par exemple, si vous définissez simplement une fonction de flèche comme

const handleChange = () => {
   console.log(arguments) // would give an error on running since arguments in undefined
}

Comme alternative, les fonctions de flèche fournissent les paramètres de repos que vous pouvez utiliser

const handleChange = (...args) => {
   console.log(args);
}
1
Shubham Khatri
 var handleChange = field => e => {
  e.preventDefault();
  /// Do something here
 }

Dans Ecma5, le traducteur:

 "use strict";

 var handleChange = function handleChange(field) {
   return function (e) {
     e.preventDefault(); /// Do something here
   };
 };

 var f = function(x,y) { return x+y }
 var g = function(x) { return function(y) { return x+y }}

 f: (T x T) -> T
 g: T -> T -> T

T: type générique

Cela changera le type de la fonction, mais le résultat no.

0
koλzar