ELEPHANT technologies, l’ESN locale et à taille humaine spécialisée sur 2 métiers : le développement et le pilotage autour de 4 expertises : hardware, embarqué, software et web.
Aujourd'hui retrouvez un article rédigé par Antoine développeur fullstack, qui nous explique les fonctions classiques et les fonctions fléchées dans le code javascript.
Let’s go !
➜ Vous avez sûrement vu passer dans du code javascript des fonctions classiques et des fonctions appelées “fonctions fléchées”. Ces fonctions fléchées sont apparues dans la version ECMAScript 2015 de Javascript. Mais quelle est vraiment la différence entre ces deux types de fonctions, dans quels cas les utiliser?
Dans cet article nous considérons que le mode strict de javascript n’est pas activé.
Les fonctions “classiques” sont celles déclarées à l’aide du mot clé function apparu dès la première version de javascript en 1997. Il est possible d’utiliser ce mot clé de deux façons pour définir des fonctions:
// En utilisant les déclarations de fonctions |
Dans le bloc de code ci-dessous, même si l’appel est fait avant la définition de la fonction, le programme se déroule sans erreur car les déclarations de fonctions sont chargées avant et donc la fonction helloWorld() est bien connue.Ces deux définitions de fonction seront appelées de la même façon à un détail près: les déclarations de fonctions sont chargées avant que le code soit exécuté.
helloWorld(); |
Cependant dans la même situation avec les expressions de fonctions une erreur sera jetée : ReferenceError: Cannot access 'helloNewWorld' before initialization
La fonction helloNewWorld() n’est pas encore connue car les expressions de fonctions sont chargées à l'exécution.
helloNewWorld(); // <-- ERREUR |
Voyons maintenant une limite à ces fonctions dites classiques (on se basera sur les déclarations et non les expressions de fonctions). On considère le code suivant:
const Avion = { |
On crée donc un objet Avion qui est à 32000 pieds, en appelant la fonction atterrir() on met l’altitude à zéro après 1 seconde et on affiche un message. On vérifie ensuite si l’avion est bien au sol avec une altitude à 0 en affichant sa valeur.
Lorsqu’on lance ce code voilà ce qu’affiche la console:
Atterrissage réussi. |
Arf, à 32000 pieds ouvrir les portes pour faire descendre les passagers c’est pas la meilleur idée.
Voyons ce qu’il c’est passé: ajoutons un log.
const Avion = { |
La console affiche:
Timeout { |
Ce qui signifie que le this dans le setTimeout est un objet de type Timeout mais pas notre objet attendu Avion.
➜ Ce fonctionnement est un des points à bien comprendre. Dans les fonctions “classique” le mot clé this dépends de la façon dont elle est appelée:
Dans notre exemple plus haut:
setTimeout(function () { |
La fonction n’est pas appelée directement par notre fichier app.js mais elle le sera dans l’objet Timeout ce qui explique la valeur de this.
Une des façons de pallier à ce problème de this est d’utiliser les fonctions fléchées.
Les fonctions fléchées permettent dans un premier temps de simplifier l’écriture du code dans certaines situations. Par exemple si l’on souhaite récupérer un tableau contenant le nombre de lettres de chaque mot présent dans un tableau donné, on peut faire avec les fonctions classiques:
const avions = [ |
Dans cette situation, bien que le code fonctionne, il est plus approprié d’utiliser une première particularité des fonctions fléchées: le retour implicite. Le code précédent peut donc être résumé de la façon suivante :
const avions = [ |
Le mot clé return n’est donc pas nécessaire ici. Il est important de savoir que pour utiliser le retour implicite avec des objets littéraux il est nécessaire de les entourer de parenthèses.
Cet usage est plutôt intéressant dans ce cas, mais comment ces fonctions fléchées peuvent-elles nous aider à résoudre notre problème de this?
Une autre propriété de ce type de fonctions se situe dans la gestion du this qui n’est pas gérée de la même façon que les fonctions classiques. En effet, les fonctions fléchées
ne créent pas de nouveau contexte et utilisent le this du contexte courant.
Ce qui signifie que dans notre exemple plus haut si on remplace la fonction classique par une fonction fléchée dans le callback de setTimeout, le this utilisé sera bien l’objet Avion :
const Avion = { console.log(this); |
Ici tout fonctionnera correctement car à l’intérieur du setTimeout, le this sera celui du contexte courant c'est-à-dire l’objet Avion. Notre console nous affiche :
{ altitude: 32000, atterrir: [Function: atterrir] } Altitude: 0 |
Le this.altitude fait bien référence à la propriété de notre objet Avion et sa valeur est donc correctement mise à zéro.
Nous avons vu ici l 'usage des deux types de fonctions ainsi que leurs utilités dans certaines situations. Quand vous jetez un coup d'œil à la documentation MDN sur les fonctions fléchées vous verrez qu’ils conseillent de ne pas utiliser ces fonctions pour déclarer des méthodes. En effet les fonctions fléchées sont plutôt utilisées en tant que fonction anonyme notamment dans le cas de callback ou de manipulation de tableau par exemple comme vu plus haut.
Chaque type de fonction a donc des avantages et inconvénients qu’il est important de connaître. Si vous souhaitez en savoir plus sur le sujet, je vous invite à aller consulter la documentation des fonctions fléchées et fonctions classiques sur MDN. J’en n’ai volontairement pas parlé ici mais il est également possible de contrer le this capricieux des fonctions classique en appelant les fonctions via apply ou call.
Sources :
https://developer.mozilla.org/fr/docs/Web/JavaScript/Guide/Functions
https://medium.com/@mandeep1012/function-declarations-vs-function-expressions-b43646042052
https://www.youtube.com/watch?v=IudrkWwOw8Y
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Operators/this
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Pour découvrir d'autres articles techniques c'est par ici :
Les object calisthenics : https://www.elephant-technologies.fr/actualite/43
Les tests dans une application : https://www.elephant-technologies.fr/actualite/42