Que signifie javascript pour plusieurs fonctions de flèche?
j'ai lu un tas de code react
et je vois des trucs comme ça que je ne comprends pas:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
4 réponses
Qui est une au curry fonction
tout d'abord, examiner cette fonction avec deux paramètres ...
let add = (x,y) => x + y;
add(2,3); //=> 5
la voici de nouveau en forme de curry ...
let add = x => y => x + y;
voici le même code 1 sans fonctions de flèche ...
let add = function (x) {
return function (y) {
return x + y;
};
};
Focus sur return
cela pourrait aider à le visualiser d'une autre manière. Nous savons que les fonctions de flèche fonctionnent comme ceci – portons une attention particulière à la valeur de retour .
let f = someParam => returnValue
ainsi notre add
renvoie une fonction – nous pouvons utiliser des parenthèses pour plus de clarté. Le en caractères gras texte est la valeur de retour de notre fonction add
let add = x => (y => x + y)
En d'autres termes add
d'un nombre renvoie une fonction
add(2) // returns (y => 2 + y)
appelant les fonctions courantes
donc pour utiliser notre fonction curried, nous devons l'appeler un peu différemment ...
add(2)(3); // returns 5
c'est parce que le premier appel de fonction (externe) renvoie une seconde fonction (interne). Ce n'est qu'après avoir appelé la deuxième fonction que nous en fait obtenir le résultat. Cela est plus évident si nous séparons les appels sur deux lignes ...
let add2 = add(2); // returns function(y) { return 2 + y }
add2(3); // returns 5
appliquer notre nouvelle compréhension à votre code
related: "Quelle est la différence entre la liaison, l'application partielle, et de nourrissage?"
OK, maintenant que nous comprenons comment cela fonctionne, regardons votre code
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
nous allons commencer par le représenter sans utiliser les fonctions de flèche ...
handleChange = function(field) {
return function(e) {
e.preventDefault();
// Do something here
// return ...
};
};
cependant, parce que les fonctions de la flèche lient lexicalement this
, il serait en fait ressemblent plus à cela ...
handleChange = function(field) {
return function(e) {
e.preventDefault();
// Do something here
// return ...
}.bind(this);
}.bind(this);
peut-être que maintenant nous pouvons voir ce que cela fait plus clairement. La fonction handleChange
crée une fonction pour un field
spécifié . C'est une technique de réaction pratique car vous devez configurer vos propres écouteurs sur chaque entrée afin de mettre à jour l'état de vos applications. En utilisant la fonction handleChange
, nous pouvons éliminer tout le code dupliqué qui résulterait en mettant en place des écouteurs change
pour chaque champ.
Cool !
1 ici, je n'ai pas eu à lier lexicalement this
parce que l'original La fonction add
n'utilise aucun contexte, il n'est donc pas important de la préserver dans ce cas.
comprendre les syntaxes disponibles des fonctions de flèche vous donnera une compréhension du comportement qu'ils introduisent quand "enchaîné" comme dans les exemples que vous avez fournis.
Lorsqu'une fonction de flèche est écrite sans attelles de bloc, avec ou sans paramètres multiples, l'expression qui constitue le corps de la fonction est implicitement retourné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 d'écrire des fonctions anonymes en utilisant la syntaxe des flèches est qu'elles sont liées lexicalement à la portée dans laquelle elles sont définies. De "Flèche fonctions de" MDN :
An arrow function expression a une syntaxe plus courte que function expressions et lie lexicalement la valeur this . Flèche les fonctions sont toujours anonyme .
ceci est particulièrement pertinent dans votre exemple étant donné qu'il est tiré d'une demande reactjs . Comme le souligne @naomik, dans React vous accédez souvent à un component's member functions en utilisant 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) | }
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.
Ainsi 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
un conseil général , si vous êtes confus par une nouvelle syntaxe JS et comment elle se compilera , vous pouvez cocher babel . Par exemple, copier votre code dans babel et sélectionner le preset es2015 donnera une sortie comme celle-ci
handleChange = function handleChange(field) {
return function (e) {
e.preventDefault();
// Do something here
};
};