Si en JavaScript vous vous êtes déjà demandé quand utiliser les fonctions fléchées et quand utiliser les fonctions traditionnelles, ou bien alors tout simplement quelle est la différence entre les deux options, vous êtes au bon endroit !
Notes :
quand je parlerai d'une fonction traditionnelle, je parlerai d'une fonction déclarée avec le mot clé 'function'
une fonction fléchée (ou arrow function en anglais) est une fonction déclarée avec la syntaxe compacte () => {}
Partie 1 : This
La première différence entre les deux options est la gestion de "this", en effet les fonctions fléchées conservent le "this" du contexte dans lequel la fonction a été appelée, ce qui n'est pas forcément le cas avec une fonction traditionnelle. Voici un exemple pour illustrer : class MyClass { prop = "hehe"; testArrow() { const f = () => { console.log(this.prop); }; f(); } testFunction() { function f() { console.log(this.prop); } f(); } } const instance = new MyClass();
Lorsqu'on va faire l'appel à :instance.testArrow()
il n'y aura pas d'erreur car le this de l'instance de la classe est conservé par contre si on essaie : instance.testFunction()
Il y aura une belle erreur JavaScript "Cannot read properties of undefined" ...
Pour comprendre cette erreur, il faut en savoir un peu plus sur le mot clé this et JavaScript de manière générale :
dans une fonction traditionnelle "this" correspond à l'objet global
dans une fonction traditionnelle ET en mode strict ("use strict";) "this" sera undefined
le corps d'une classe est toujours exécuté en mode strict
Or, dans notre cas, la fonction est déclarée dans une classe donc en mode strict, donc "this" sera undefined, d'où notre erreur JavaScript "Cannot read properties of undefined".
Bonus :
Si on remplace notre méthode "testFunction" dans la classe "MyClass" par le code suivant :
testFunctionBinded() { function f() { console.log(this.prop); } f.bind(this)(); }
Cette méthode est identique à l'exception de l'appel de f().
En effet en appelant f et en la liant manuellement au bon "this" avec la syntaxe suivante : f.bind(this)();
On aura pas d'erreur lors de l'appel à instance.testFunctionBinded()
Partie 2 : JavaScript Hoisting
En JavaScript lorsqu'on utilise le mot clé "function", on peut utiliser cette fonction avant sa déclaration (tant que l'on reste dans le même bloc), c'est ce que l'on appelle le hoisting.
Dans certains cas, c'est assez agréable, mais bien souvent, ça mène à des erreurs difficiles à déboguer, par exemple :
if (true) { function a() { console.log("1"); } if (true) { a(); function a() { console.log("2"); } } }
Ici, on déclare une premiere fonction "a", puis dans le bloc suivant, au début du bloc on appelle a() et à la fin du bloc on déclare une autre fonction "a". Lors de l'appel à a(), ce n'est pas la fonction que l'on pensait qui est appelée puisque la deuxième fonction "a" est "hoisted"...
Souvent on garde les fonctions fléchées dans un "const" ou un "let", ce qui permet d'avoir une lecture du code bien plus facile car lisible du haut vers le bas et donc de supprimer le bug vu plus haut.
Voilà ! Personnellement, je préfère utiliser les fonctions fléchées, car le comportement est beaucoup facile à prévoir et le code plus facile à lire !