En JavaScript, une fonction nest pas une structure de langage magique, mais un type de valeur particulier.
La syntaxe utilise prcdemment sappelle une dclaration de fonction :
function sayHi() {
alert( "Hello" );
}
Il existe une autre syntaxe pour crer une fonction appele Expression de Fonction.
Cela nous permet de crer une nouvelle fonction au milieu de nimporte quelle expression.
Par exemple :
let sayHi = function() {
alert( "Hello" );
};
Ici, nous pouvons voir une variable sayHi obtenir une valeur, la nouvelle fonction, cre en tant que function() { alert("Hello"); }.
Comme la cration de la fonction se produit dans le contexte de lexpression daffectation ( droite de =), il sagit dune Fonction Expression.
Veuillez noter quil ny a pas de nom aprs le mot cl function. Lomission dun nom est autorise pour les fonctions expressions.
Ici, nous lassignons immdiatement la variable, donc la signification de ces exemples de code est la mme: crer une fonction et la mettre dans la variable sayHi.
Dans des situations plus avances, que nous verrons plus tard, une fonction peut tre cre et immdiatement appele ou planifie pour une excution ultrieure, non stocke nulle part, restant ainsi anonyme.
La fonction est une valeur
Rptons-le: quelle que soit la manire dont la fonction est cre, une fonction est une valeur. Les deux exemples ci-dessus stockent une fonction dans la variable sayHi.
La signification de ces exemples de code est la mme : crer une fonction et la placer dans la variable sayHi.
Nous pouvons mme afficher cette valeur en utilisant alert :
function sayHi() {
alert( "Hello" );
}
alert( sayHi ); // affiche le code de la fonction
Veuillez noter que la dernire ligne nexcute pas la fonction, car il ny a pas de parenthses aprs sayHi. Il y a des langages de programmation o toute mention dun nom de fonction provoque son excution, mais JavaScript nest pas comme a.
En JavaScript, une fonction est une valeur, nous pouvons donc la traiter comme une valeur. Le code ci-dessus montre sa reprsentation sous forme de chane de caractres, qui est le code source.
Certes, une fonction est une valeur spciale, en ce sens que nous pouvons lappeler comme cela sayHi().
Mais cest toujours une valeur. Nous pouvons donc travailler avec comme avec dautres types de valeurs.
Nous pouvons copier une fonction dans une autre variable :
function sayHi() { // (1) crer
alert( "Hello" );
}
let func = sayHi; // (2) copier
func(); // Hello // (3) excuter la copie (a fonctionne)!
sayHi(); // Hello // cela fonctionne toujours aussi (pourquoi pas)
Voici ce qui se passe ci-dessus en dtail :
- La Dclaration de Fonction
(1)cre la fonction et la place dans la variable nommesayHi. - La ligne
(2)la copie dans la variablefunc. Veuillez noter nouveau : il ny a pas de parenthses aprssayHi. Sil y en avait, alorsfunc = sayHi()crirait le rsultat de lappelsayHi()dansfunc, et non la fonctionsayHielle-mme. - Maintenant, la fonction peut tre appele la fois en tant que
sayHi()etfunc().
Nous aurions aussi pu utiliser une Fonction Expression pour dclarer sayHi, la premire ligne :
let sayHi = function() { // (1) create
alert( "Hello" );
};
let func = sayHi;
// ...
Tout fonctionnerait de la mme manire.
Il peut y avoir une question, pourquoi la Fonction Expression a un point-virgule ; la fin, et la Fonction Dclaration non :
function sayHi() {
// ...
}
let sayHi = function() {
// ...
};
La rponse est simple: une expression de fonction est cre ici en tant que function() {} lintrieur de linstruction daffectation: let sayHi = ;. Le point-virgule ; est recommand la fin de linstruction, il ne fait pas partie de la syntaxe de la fonction.
Le point-virgule serait l pour une affectation plus simple, telle que let sayHi = 5;, et il est galement l pour une affectation de fonction.
Fonctions callback (de rappel)
Examinons plus dexemples de fonctions passes en tant que valeurs et utilisant des expressions de fonction.
Nous allons crire une fonction ask(question, yes, no) avec trois paramtres :
question- Texte de la question
yes- Fonction excuter si la rponse est Yes
no- Fonction excuter si la rponse est No
La fonction doit poser la question et, en fonction de la rponse de lutilisateur, appeler yes() ou no() :
function ask(question, yes, no) {
if (confirm(question)) yes();
else no();
}
function showOk() {
alert( "You agreed." );
}
function showCancel() {
alert( "You canceled the execution." );
}
// utilisation: les fonctions showOk, showCancel sont transmises en tant qu'arguments ask
ask("Do you agree?", showOk, showCancel);
En pratique, ces fonctions sont trs utiles. La principale diffrence entre une demande relle (ask) et lexemple ci-dessus est que les fonctions relles utilisent des moyens dinteragir avec lutilisateur plus complexes que la simple confirmation (confirm). Dans le navigateur, une telle fonction dessine gnralement une belle fentre de questions. Mais cest une autre histoire.
Les arguments showOk et showCancel de ask sappellent des fonctions callback (fonctions de rappel) ou simplement des callbacks (rappels).
Lide est que nous passions une fonction et attendions quelle soit rappele plus tard si ncessaire. Dans notre cas, showOk devient le rappel pour la rponse oui et showCancel pour la rponse non.
Nous pouvons utiliser les Fonctions Expressions pour crire la mme fonction mais plus courte :
function ask(question, yes, no) {
if (confirm(question)) yes();
else no();
}
ask(
"Do you agree?",
function() { alert("You agreed."); },
function() { alert("You canceled the execution."); }
);
Ici, les fonctions sont dclares directement dans lappel ask(...). Elles nont pas de nom et sont donc appeles anonymes. De telles fonctions ne sont pas accessibles en dehors de ask (car elles ne sont pas affectes des variables), mais cest exactement ce que nous voulons ici.
Ce genre de code apparat dans nos scripts trs naturellement, cest dans lesprit de JavaScript.
Des valeurs rgulires telles que des chanes de caractres ou des nombres reprsentent les donnes.
Une fonction peut tre perue comme une action.
Nous pouvons tout aussi bien la passer en tant que variable ou lexcuter si nous le voulons.
Fonction Expression vs Fonction Dclaration
Formulons les principales diffrences entre les dclarations de fonction et les expressions de fonctions.
Tout dabord, la syntaxe : comment les diffrencier dans le code.
-
La Fonction Dclaration une fonction dclare sparment dans le flux de code principal.
// Function Declaration function sum(a, b) { return a + b; } -
La Fonction Expression : une fonction cre dans une expression ou dans une autre construction de syntaxe. Ici, la fonction est cre droite de laffectation de lexpression
=:// Function Expression let sum = function(a, b) { return a + b; };
La diffrence la plus subtile est quand une fonction est cre par le moteur JavaScript.
Une Fonction Expression est cre lorsque lexcution latteint.
Une fois que le flux dexcution passe droite de laffectation, let sum = function , la fonction est cre et peut dsormais tre utilise (assigne, appele, etc.).
Les dclarations de fonction sont diffrentes.
Une Fonction Dclaration peut tre appele plus tt que sa dfinition.
Par exemple, une fonction dclaration globale est visible dans tout le script, peu importe o elle se trouve.
Cela est d aux algorithmes internes. Lorsque JavaScript se prpare excuter le script, il recherche dabord les fonctions dclarations globales et les cre. Nous pouvons considrer cela comme une tape dinitialisation.
Une fois que toutes les dclarations de fonctions ont t traites, le reste du code est excut. Ainsi, il a accs ces fonctions pour les appeler.
Par exemple, cela fonctionne :
sayHi("John"); // Hello, John
function sayHi(name) {
alert( `Hello, ${name}` );
}
La dclaration de fonction sayHi est cre lorsque JavaScript est sur le point de dmarrer le script et est visible partout dans celui-ci.
Sil sagissait dune Fonction Expression, cela ne fonctionnerait pas :
sayHi("John"); // erreur!
let sayHi = function(name) { // (*) plus de magie
alert( `Hello, ${name}` );
};
Les expressions de fonction sont cres lorsque lexcution les atteint. Cela ne se produirait que dans la ligne (*). Trop tard.
Une autre particularit des Fonctions Declaration est leur porte de bloc.
En mode strict, quand une Fonction Dclaration se trouve dans un bloc de code, elle est visible partout dans ce bloc. Mais pas en dehors.
Par exemple, imaginons que nous ayons besoin de dclarer une fonction welcome() en fonction de la variable dage obtenue lors de lexcution. Et ensuite, nous prvoyons de lutiliser quelque temps plus tard.
Si nous utilisons la fonction dclaration, cela ne fonctionnera pas comme prvu :
let age = prompt("Quel est votre age ?", 18);
// dclarer conditionnellement une fonction
if (age < 18) {
function welcome() {
alert("Hello!");
}
} else {
function welcome() {
alert("Greetings!");
}
}
// ...l'utiliser plus tard
welcome(); // Error: welcome is not defined
Cest parce quune dclaration de fonction nest visible que dans le bloc de code dans lequel elle rside.
Voici un autre exemple :
let age = 16; // prendre 16 comme exemple
if (age < 18) {
welcome(); // \ (excution)
// |
function welcome() { // |
alert("Hello!"); // | La dclaration de fonction est disponible
} // | partout dans le bloc o elle est dclare
// |
welcome(); // / (excution)
} else {
function welcome() {
alert("Greetings!");
}
}
// Ici, nous sommes en dehors des accolades,
// nous ne pouvons donc pas voir les dclarations de fonction faites l'intrieur de celles-ci.
welcome(); // Error: welcome is not defined
Que pouvons-nous faire pour rendre welcome visible en dehors de if ?
Lapproche correcte consisterait utiliser une expression de fonction et attribuer welcome la variable dclare en dehors de if et offrant la visibilit approprie.
Ce code fonctionne comme prvu :
let age = prompt("What is your age?", 18);
let welcome;
if (age < 18) {
welcome = function() {
alert("Hello!");
};
} else {
welcome = function() {
alert("Greetings!");
};
}
welcome(); // ok maintenant
Ou nous pourrions simplifier encore davantage en utilisant un oprateur conditionnel ternaire ? :
let age = prompt("What is your age?", 18);
let welcome = (age < 18) ?
function() { alert("Hello!"); } :
function() { alert("Greetings!"); };
welcome(); // ok maintenant
En rgle gnrale, lorsque nous devons dclarer une fonction, la premire chose prendre en compte est la syntaxe de la fonction dclaration. Cela donne plus de libert dans lorganisation de notre code, car nous pouvons appeler de telles fonctions avant quelles ne soient dclares.
Cest galement meilleur pour la lisibilit, car il est plus facile de rechercher la fonction f() {} dans le code que let f = function() {};. Les fonction dclarations sont plus accrocheuses.
Mais si une dclaration de fonction ne nous convient pas pour une raison quelconque (nous en avons vu un exemple ci-dessus), alors il convient dutiliser une Fonction Expression.
Rsum
- Les fonctions sont des valeurs. Elles peuvent tre attribues, copies ou dclares nimporte quel endroit du code.
- Si la fonction est dclare comme une instruction distincte dans le flux de code principal, cela sappelle une dclaration de fonction.
- Si la fonction est cre dans le cadre dune expression, elle est appele expression de fonction.
- Les dclarations de fonctions sont traites avant lexcution du bloc de code. Elles sont visibles partout dans le bloc.
- Les expressions de fonction sont cres lorsque le flux dexcution les atteint.
Dans la plupart des cas, lorsque nous devons dclarer une fonction, une fonction dclaration est prfrable parce quelle est visible avant la dclaration elle-mme. Cela nous donne plus de flexibilit dans lorganisation du code et il est gnralement plus lisible.
Nous devrions donc utiliser une fonction expression uniquement lorsquune fonction dclaration nest pas adapte la tche. Nous en avons vu quelques exemples dans ce chapitre et nous en verrons dautres lavenir.
Commentaires
<code>, pour plusieurs lignes enveloppez-les avec la balise<pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepen)