Déclaration et définition de fonctions en Javascript

Dans ce premier article de notre série consacrée aux fonctions en Javascript, nous allons lister les différentes façons de déclarer et de définir une fonction, pour mieux comprendre l’éventail de possibilités qui s’offrent à nous.

Avant toute chose, il faut distinguer la déclaration d’une fonction de sa simple définition.

La définition touche au corps de la fonction, c’est-à-dire à l’écriture du code qui sera exécuté lors de son appel, et n’implique pas forcément l’initialisation d’une variable accueillant cette définition.

La déclaration, de son côté, comprend également son initialisation. Attention que la déclaration pure, telle la déclaration d’une variable non initialisée, n’induit pas de valeur obligatoire, ce qui n’est pas possible avec une fonction.

Fonction déclarative

Une fonction déclarative (function declaration statement) est un « statement », c’est-à-dire une commande en devenir qui pourra être appelée grâce à un identifiant. En réalité, Javascript déclare une variable au nom de la fonction et lui assigne cette dernière.

Expression de fonction anonyme

Une expression de fonction (function definition expression) est une valeur à évaluer. Il ne s’agit donc pas d’une déclaration, mais d’une simple définition, laquelle peut être stockée dans une variable, comme toute autre valeur. Pour l’évaluer, il suffit d’utiliser la variable tel un appel de fonction déclarative. La variable contient la fonction en elle-même et non son évaluation.

Expression de fonction nominative

Une expression de fonction peut également posséder un nom (named function definition expression), qui représentera une variable connue uniquement au sein de cette fonction.

Attention toutefois que MSIE ne réagit pas toujours correctement. Premièrement, ce navigateur ne reconnaît pas l’attribut name, et il n’est donc pas possible de s’en servir de manière standard.

Ensuite, certaines versions déclareraient deux fonctions à la fois, l’une au-travers de la variable qui accueille la fonction, l’autre au-travers de l’identifiant de la fonction. Aussi, dans l’exemple précédent, foo et bar seraient deux fonctions différentes mais contenant le même code. A ce sujet, je vous recommande l’article de Juriy « kangax » Zaytsev sur les expressions de fonction. Pour ma part, j’ai testé ces bugs sous IE9 et ils semblent avoir été corrigés.

Méthode

Une méthode n’est rien d’autre qu’une fonction rattachée à un objet, qui, dans ce cadre, bénéficie d’un accès à ce dernier via le mot-clé this, comme je l’ai expliqué dans mon article sur le contexte.

Une méthode se déclare comme une expression de fonction, anonyme ou non, passée à un attribut de l’objet.

Par ailleurs, les fonctions étant elles-mêmes des objets, il est possible de leur assigner des méthodes.

Expression de fonction directe

Une IIFE (Immediately-Invoked Function Expression), que j’ai traduite, de manière quelque peu abrupte, par fonction directe, est une expression de fonction appelée directement après sa définition. Cette expression peut être anonyme ou nominative.

Attention toutefois que si la fonction est rattachée à une variable, celle-ci, contrairement à un usage classique d’expression de fonction, ne contient pas la fonction en elle-même, mais bien le résultat de son évaluation. Par défaut, si la fonction ne retourne rien, la variable vaudra donc undefined.

Si la fonction n’est pas rattachée à une variable, elle doit être contenue à l’intérieur de parenthèses pour pouvoir être évaluée au préalable.

Cette notation n’empêche néanmoins pas d’assigner le résultat de la fonction à une variable.

EDIT: Il existe une notation alternative bien que celle-ci ne puisse par contre pas retourner de valeur utilisable: !function () {}();

Enfin, cette dernière forme d’écriture fonctionne mais entraîne une certaine confusion quant à sa lecture.

Attention toutefois qu’une IIFE rattachée à un attribut d’objet ne constitue pas une méthode qui s’exécute automatiquement. En effet, comme nous l’avons vu pour une simple variable, l’IIFE s’exécute indépendamment de l’attribut pour finalement ne lui assigner que sa valeur en retour.

Cela a deux conséquences. Premièrement, l’attribut contient donc le retour de l’IIFE et non l’IIFE en tant que telle. En cela, il s’agit d’un comportement tel que nous l’avons décrit précédemment.

Mais ce qu’il ne faut pas perdre de vue c’est que l’IIFE s’exécute comme une fonction et non comme une méthode, avec un contexte indépendant de l’objet courant.

Instanciation de fonction

Enfin, il est possible d’utiliser le constructeur Function pour instancier une fonction, bien que cette méthode ne soit sans doute pas la plus lisible, alors qu’elle correspond en tout point à une définition de fonction anonyme.

Le constructeur reçoit une série d’arguments qui déterminent autant de noms de paramètres de la fonction, ainsi qu’un ultime argument qui contient, quant à lui, le corps même de la fonction. Tous ces arguments étant passés sous la forme de chaînes de caractères, il s’agit en quelque sorte d’une évaluation de fonction.

Conclusion

Au final, une fonction se caractérise toujours par au moins une définition de son corps, qu’il s’agisse de déclaration, d’expression de fonction ou que l’on passe par le constructeur.

Ce corps peut être évalué ensuite soit par l’intermédiaire d’une variable qui stocke la définition de la fonction, soit de manière directe si des parenthèses suivent la définition, comme dans une IIFE.

Une fonction peut posséder un identifiant interne, et n’est alors plus anonyme, quoique que cette méthode ne soit pas standard.

Enfin, une méthode n’est jamais qu’un attribut d’objet contenant une fonction.

Dans notre prochain article, consacré au hoisting, nous analyserons ce qu’impliquent les différentes façons de déclarer une fonction que nous venons de voir, car leur comportement peut différer quelque peu.

5 réflexions au sujet de « Déclaration et définition de fonctions en Javascript »

  1. Ping : Hoisting de fonctions en Javascript | The Dark Side Of The Web

  2. Ping : Appel et retour de fonctions en Javascript | The Dark Side Of The Web

  3. Ping : Arguments et paramètres de fonctions en Javascript | The Dark Side Of The Web

  4. Ping : Les fonctions en Javascript | The Dark Side Of The Web

  5. Ping : Les closure en PHP | The Dark Side Of The Web

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>