JavaScript étant un langage basé sur les fonctions, la gestion de la portée des variables est essentielle à son fonctionnement. Deux concepts clés en découlent : la portée lexicale et les closures. Pour bien les comprendre, il est utile de maîtriser la portée des variables (var
, let
et const
), les fonctions imbriquées, ainsi que la différence entre les fonctions classiques et fléchées (arrow functions en anglais). Ces notions sont fondamentales pour écrire un code plus structuré, éviter les effets de bord et tirer parti de la puissance de JavaScript.
La portée lexicale, aussi appelée lexical scope en anglais ou portée statique, désigne l’endroit où une variable peut être accédée dans le code en fonction de son emplacement lors de la déclaration. En JavaScript, une fonction conserve toujours un accès à sa portée externe, ce qui signifie qu’elle peut utiliser des variables définies en dehors de son propre bloc. Cette notion est essentielle, car elle détermine la manière dont les fonctions peuvent interagir avec les variables déclarées en dehors de leur propre contexte, influençant ainsi la structure et l’organisation du code.
Le problème est que n
est uniquement accessible à l'intérieur de la fonction multen
, car nous l'avons déclarée dans la portée de cette fonction.
Attention ! En JavaScript, les fonctions fléchées (arrow functions) ne définissent pas leur propre portée interne comme celles créées avec la syntaxe function mon_nom_de_fonction....
.
Nous ne pouvons pas accéder aux variables définies dans une portée interne depuis une portée externe. Cependant, nous pouvons accéder aux éléments définis dans une portée externe depuis une portée interne.
Ici, la fonction multiply_by
accède à la variable a
définie dans la portée externe sans générer d'erreur, car les fonctions ont toujours accès à leur portée externe.
Une closure est une fonction (nous l'appellerons inner_func
) qui est définie à l'intérieur d'une autre fonction (nous l'appellerons outer_func
) et qui peut se souvenir (référencer) des variables locales de outer_func
, même après que outer_func
ait été appelée.
En d'autres termes, une closure est une fonction interne qui garde une référence aux variables locales d'une fonction externe dans laquelle elle (inner_func
) a été définie. Parce que, comme nous l'avons vu dans l'Exemple I ci-dessus, lorsque nous avons voulu utiliser la variable n
de la fonction multen
, cela nous a renvoyé une ReferenceError car elle était en dehors de sa portée.
Même avec les closures, nous ne pourrons pas directement accéder à une variable définie dans la portée d'une fonction depuis une portée externe, mais nous pourrons y faire référence et la suivre grâce à la closure (inner_func
).
En JavaScript, nous utilisons les closures principalement pour renforcer l'encapsulation des données, car la restriction des données et les méthodes privées n'existent pas nativement en JS. Ainsi, nous imitons ces concepts avec les closures.
Pour mieux comprendre cela, prenons un exemple simple : vous avez un site web et vous souhaitez savoir combien de visiteurs ont consulté une page spécifique. Pour cela, vous décidez de créer une fonction qui compte le nombre de visites sur cette page. De la manière la plus simple, vous feriez probablement quelque chose comme ceci :
Même si le code est correct et fonctionne sans erreur, vous pouvez toujours mettre à jour ou écraser la variable contenant le nombre réel de visites depuis n'importe où, ce qui n'est pas sécurisé.
Pour cela, vous devez le rendre plus sécurisé et isolé. La première solution à laquelle vous pourriez penser serait probablement de définir la variable à l'intérieur de la fonction, comme ceci :
Après trois appels de la fonction update_number_of_visits
, au lieu d'obtenir 3, nous obtenons toujours 1
. C'est parce que la fonction réinitialise la variable number_of_visits
à chaque appel.
Pour éviter le dernier problème que nous avons rencontré, nous devons utiliser une closure.
Vous pouvez copier/coller ce code et l’exécuter dans la console du navigateur et appeler la visits()
plusieurs fois pour voir ce que ça donne.
Vous souhaitez pouvoir vous former au développement informatique et maîtriser ce concept ? Rejoignez Holberton !
Coach Technique
Student Success Manager