En JavaScript, une fonction n’est pas une « structure magique du langage », mais un type spécial de valeur.

La syntaxe que nous avons utilisée auparavant s’appelle une déclaration de fonction:

function sayHi() { alert( "Hello" );}

Il existe une autre syntaxe pour créer une fonction qui s’appelle une expression de fonction.

Elle ressemble à ceci :

let sayHi = function() { alert( "Hello" );};

Ici, la fonction est créée et assignée à la variable explicitement, comme toute autre valeur. Peu importe comment la fonction est définie, c’est juste une valeur stockée dans la variable sayHi.

La signification de ces échantillons de code est la même : « créer une fonction et la mettre dans la variable sayHi« .

Nous pouvons même imprimer cette valeur en utilisant alert:

function sayHi() { alert( "Hello" );}alert( sayHi ); // shows the function code

Veuillez noter que la dernière ligne n’exécute pas la fonction, car il n’y a pas de parenthèses après sayHi. Il existe des langages de programmation où toute mention du nom d’une fonction entraîne son exécution, mais JavaScript n’est pas comme cela.

En JavaScript, une fonction est une valeur, nous pouvons donc la traiter comme une valeur. Le code ci-dessus montre sa représentation en chaîne, qui est le code source.

Certes, une fonction est une valeur spéciale, dans le sens où nous pouvons l’appeler comme sayHi().

Mais c’est toujours une valeur. Nous pouvons donc travailler avec elle comme avec d’autres types de valeurs.

On peut copier une fonction dans une autre variable:

function sayHi() { // (1) create alert( "Hello" );}let func = sayHi; // (2) copyfunc(); // Hello // (3) run the copy (it works)!sayHi(); // Hello // this still works too (why wouldn't it)

Voici ce qui se passe ci-dessus en détail:

  1. La déclaration de fonction (1) crée la fonction et la place dans la variable nommée sayHi.
  2. La ligne (2) la copie dans la variable func. Notez encore une fois : il n’y a pas de parenthèses après sayHi. S’il y en avait, alors func = sayHi() écrirait le résultat de l’appel sayHi() dans func, et non la fonction sayHi elle-même.
  3. Maintenant la fonction peut être appelée à la fois comme sayHi() et func().

Notez que nous aurions également pu utiliser une expression de fonction pour déclarer sayHi, à la première ligne :

let sayHi = function() { alert( "Hello" );};let func = sayHi;// ...

Tout fonctionnerait de la même manière.

Pourquoi y a-t-il un point-virgule à la fin ?

Vous pourriez vous demander, pourquoi l’expression de fonction a un point-virgule ; à la fin, mais pas la déclaration de fonction :

function sayHi() { // ...}let sayHi = function() { // ...};

La réponse est simple :

  • Il n’y a pas besoin de ; à la fin des blocs de code et des structures syntaxiques qui les utilisent comme if { ... }, for { }, function f { }, etc.
  • Une expression de fonction est utilisée à l’intérieur de l’énoncé : let sayHi = ...;, comme une valeur. Ce n’est pas un bloc de code, mais plutôt une affectation. Le point-virgule ; est recommandé à la fin des déclarations, quelle que soit la valeur. Donc, le point-virgule ici n’est pas lié à l’expression de fonction elle-même, il termine simplement l’instruction.

Fonctions de rappel

Regardons d’autres exemples de passage de fonctions comme valeurs et d’utilisation d’expressions de fonction.

Nous allons écrire une fonction ask(question, yes, no) avec trois paramètres :

question Texte de la question yes Fonction à exécuter si la réponse est « Oui » no Fonction à exécuter si la réponse est « Non »

La fonction doit demander la question et, selon la réponse de l’utilisateur, 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." );}// usage: functions showOk, showCancel are passed as arguments to askask("Do you agree?", showOk, showCancel);

En pratique, de telles fonctions sont assez utiles. La principale différence entre une ask réelle et l’exemple ci-dessus est que les fonctions réelles utilisent des moyens plus complexes pour interagir avec l’utilisateur qu’une simple confirm. Dans le navigateur, une telle fonction dessine généralement une jolie fenêtre de questions. Mais c’est une autre histoire.

Les arguments showOk et showCancel de ask sont appelés fonctions de rappel ou simplement callbacks.

L’idée est que nous passons une fonction et nous attendons à ce qu’elle soit « rappelée » plus tard si nécessaire. Dans notre cas, showOk devient le callback pour la réponse « oui », et showCancel pour la réponse « non ».

Nous pouvons utiliser les expressions de fonction pour écrire la même fonction beaucoup 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 déclarées juste à l’intérieur de l’appel ask(...). Elles n’ont pas de nom, et sont donc dites anonymes. De telles fonctions ne sont pas accessibles en dehors de ask (car elles ne sont pas affectées à des variables), mais c’est justement ce que nous voulons ici.

Un tel code apparaît dans nos scripts très naturellement, c’est dans l’esprit de JavaScript.

Une fonction est une valeur représentant une « action »

Des valeurs ordinaires comme des chaînes de caractères ou des nombres représentent les données.

Une fonction peut être perçue comme une action.

Nous pouvons la passer entre des variables et l’exécuter quand nous le voulons.

Expression de fonction vs déclaration de fonction

Formulons les différences essentielles entre les déclarations de fonction et les expressions.

D’abord, la syntaxe : comment les différencier dans le code.

  • Déclaration de fonction : une fonction, déclarée comme une déclaration séparée, dans le flux de code principal.

    // Function Declarationfunction sum(a, b) { return a + b;}

  • Expression de fonction : une fonction, créée à l’intérieur d’une expression ou d’une autre construction syntaxique. Ici, la fonction est créée à droite de « l’expression d’affectation » =:

    // Function Expressionlet sum = function(a, b) { return a + b;};

La différence plus subtile est lorsqu’une fonction est créée par le moteur JavaScript.

Une expression de fonction est créée lorsque l’exécution l’atteint et n’est utilisable qu’à partir de ce moment.

Une fois que le flux d’exécution passe à droite de l’affectation let sum = function… – nous y voilà, la fonction est créée et peut être utilisée (affectée, appelée, etc. ) à partir de maintenant.

Les déclarations de fonction sont différentes.

Une déclaration de fonction peut être appelée avant d’être définie.

Par exemple, une déclaration de fonction globale est visible dans tout le script, peu importe où elle se trouve.

C’est dû à des algorithmes internes. Lorsque JavaScript se prépare à exécuter le script, il recherche d’abord les déclarations de fonctions globales dans celui-ci et crée les fonctions. Nous pouvons penser à cela comme à une « étape d’initialisation ».

Et après que toutes les Déclarations de Fonction soient traitées, le code est exécuté. Il a donc accès à ces fonctions.

Par exemple, cela fonctionne :

sayHi("John"); // Hello, Johnfunction sayHi(name) { alert( `Hello, ${name}` );}

La déclaration de fonction sayHi est créée lorsque JavaScript se prépare à lancer le script et est visible partout dans celui-ci.

…Si c’était une expression de fonction, alors cela ne fonctionnerait pas :

sayHi("John"); // error!let sayHi = function(name) { // (*) no magic any more alert( `Hello, ${name}` );};

Les expressions de fonction sont créées lorsque l’exécution les atteint. Cela ne se produirait que dans la ligne (*). Trop tard.

Une autre particularité des déclarations de fonction est leur portée de bloc.

En mode strict, lorsqu’une déclaration de fonction se trouve dans un bloc de code, elle est visible partout à l’intérieur de ce bloc. Mais pas à l’extérieur de celui-ci.

Par exemple, imaginons que nous devons déclarer une fonction welcome() en fonction de la variable age que nous obtenons pendant l’exécution. Et puis nous prévoyons de l’utiliser quelque temps plus tard.

Si nous utilisons la déclaration de fonction, cela ne fonctionnera pas comme prévu :

let age = prompt("What is your age?", 18);// conditionally declare a functionif (age < 18) { function welcome() { alert("Hello!"); }} else { function welcome() { alert("Greetings!"); }}// ...use it laterwelcome(); // Error: welcome is not defined

C’est parce qu’une déclaration de fonction n’est visible qu’à l’intérieur du bloc de code dans lequel elle réside.

Voici un autre exemple :

let age = 16; // take 16 as an exampleif (age < 18) { welcome(); // \ (runs) // | function welcome() { // | alert("Hello!"); // | Function Declaration is available } // | everywhere in the block where it's declared // | welcome(); // / (runs)} else { function welcome() { alert("Greetings!"); }}// Here we're out of curly braces,// so we can not see Function Declarations made inside of them.welcome(); // Error: welcome is not defined

Que pouvons-nous faire pour rendre welcome visible en dehors de if ?

L’approche correcte serait d’utiliser une expression de fonction et d’assigner welcome à la variable qui est déclarée en dehors de if et qui a la visibilité appropriée.

Ce code fonctionne comme prévu:

let age = prompt("What is your age?", 18);let welcome;if (age < 18) { welcome = function() { alert("Hello!"); };} else { welcome = function() { alert("Greetings!"); };}welcome(); // ok now

Ou nous pourrions le simplifier encore plus en utilisant un opérateur point d’interrogation ? :

let age = prompt("What is your age?", 18);let welcome = (age < 18) ? function() { alert("Hello!"); } : function() { alert("Greetings!"); };welcome(); // ok now

Quand choisir la déclaration de fonction par rapport à l’expression de fonction ?

En règle générale, lorsque nous devons déclarer une fonction, la première à considérer est la syntaxe Function Declaration. Elle donne plus de liberté dans la façon d’organiser notre code, car nous pouvons appeler de telles fonctions avant qu’elles ne soient déclarées.

C’est aussi meilleur pour la lisibilité, car il est plus facile de chercher function f(…) {…} dans le code que let f = function(…) {…};. Les déclarations de fonction sont plus « accrocheuses ».

…Mais si une déclaration de fonction ne nous convient pas pour une raison quelconque, ou si nous avons besoin d’une déclaration conditionnelle (nous venons de voir un exemple), alors il faut utiliser l’expression de fonction.

Sommaire

  • Les fonctions sont des valeurs. Elles peuvent être assignées, copiées ou déclarées à n’importe quel endroit du code.
  • Si la fonction est déclarée comme une déclaration séparée dans le flux de code principal, cela s’appelle une « Déclaration de fonction ».
  • Si la fonction est créée comme une partie d’une expression, cela s’appelle une « Expression de fonction ».
  • Les Déclarations de fonction sont traitées avant l’exécution du bloc de code. Elles sont visibles partout dans le bloc.
  • Les expressions de fonction sont créées lorsque le flux d’exécution les atteint.

Dans la plupart des cas où nous devons déclarer une fonction, une déclaration de fonction est préférable, car elle est visible avant la déclaration elle-même. Cela nous donne plus de flexibilité dans l’organisation du code, et est généralement plus lisible.

Donc nous devrions utiliser une expression de fonction seulement quand une déclaration de fonction n’est pas adaptée à la tâche. Nous avons vu quelques exemples de cela dans ce chapitre, et nous en verrons d’autres dans le futur.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.