Apprendre à coder sur pierre-giraud.com

DES COURS COMPLETS ET GRATUITS POUR TOUS

SOMMAIRE

Introduction

  1. Présentation du cours
  2. Introduction au JavaScript
  3. Environnement de travail

Les bases en JavaScript

  1. Où écrire le JavaScript
  2. Syntaxe et commentaires
  3. Découverte des variables
  4. Les types de valeurs
  5. Opérations sur les variables
  6. La concaténation
  7. Présentation des conditions
  8. Les conditions if, if...else, if...else if...else
  9. Opérateurs logiques
  10. Evaluation / Simplification des conditions
  11. Conditions ternaires
  12. Switch
  13. Les boucles
  14. Découverte des fonctions
  15. Test n°1

Les objets en JavaScript

  1. Définition et découverte
  2. Valeurs primitives et objets
  3. Créer des objets
  4. Les méthodes de l’objet String
  5. Les méthodes de l’objet Number
  6. Découverte de l’objet Array
  7. Les méthodes de l’objet Array
  8. Découverte de l’objet Date
  9. Les méthodes de l’objet Date
  10. L’objet Math et ses méthodes
  11. Test n°2

Notions avancées sur les fonctions

  1. La portée en JavaScript
  2. Les fonctions anonymes
  3. Les fonctions auto-invoquées
  4. Les closures JavaScript
  5. Test n°3

Le DOM HTML

  1. Découverte du DOM HTML
  2. Accéder à un élément HTML
  3. Modifier du contenu HTML
  4. Ajouter et insérer des éléments HTML
  5. Modifier ou supprimer des éléments HTML
  6. Naviguer dans le DOM
  7. Les évènements en JavaScript
  8. AddEventListener()
  9. Propagation des évènements
  10. L'objet Event
  11. Test n°4

Le BOM - Browser Object Model

  1. Le BOM et l'objet Window
  2. L'objet Screen
  3. L'objet Navigator
  4. L'objet Location
  5. L'objet History
  6. Test n°5

Les expressions régulières

  1. Découverte des regex en JavaScript
  2. Recherches et remplacements
  3. Les quantifieurs et les options
  4. Les classes de caractères et les méta-caractères
  5. Test n°6

JavaScript et formulaires

  1. Rappels sur les formulaires en HTML
  2. Validation HTML des formulaires
  3. Validation JavaScript des formulaires
  4. Test n°7

L'élément HTML canvas

  1. Découverte de l'élément canvas
  2. Dessiner des rectangles
  3. Dessiner des lignes
  4. Dessiner des arcs de cercle
  5. Créer des dégradés
  6. Insérer du texte et des images
  7. Incliner un dessin
  8. Test n°8

Notions avancées

  1. Gestion du délai d'exécution
  2. La gestion des erreurs
  3. Le mode strict
  4. Test n°9

Conclusion

  1. Conclusion - Aller plus loin

LES CLOSURES EN JAVASCRIPT

Un chapitre qui demande de l’attention

Je vous préviens avant tout : les closures constituent malheureusement bien souvent un morceau difficilement digérable pour les débutants comme pour certains développeurs expérimentés.

Ne soyez donc pas étonnés si cette partie vous semble floue au premier abord ou si vous ne comprenez pas tout d’un coup. Accrochez vous et n’hésitez pas à reprendre ce chapitre à tête reposée plus tard si c’est le cas.

Nous allons essayer de comprendre véritablement comment fonctionnent les closures et de montrer leur intérêt grâce à des exemples.

Rappel sur la portée

Pour bien comprendre le principe des closures, il est au préalable indispensable de maîtriser parfaitement les concepts de portée et de « temps de vie » des variables en JavaScript.

Rappelez vous : en JavaScript, les variables peuvent être déclarées dans le contexte global ou local (c’est-à-dire à l’intérieur d’une fonction).

Les variables déclarées globalement dans le script sont accessibles depuis n’importe où dans le script et « vivent » tant que la page web est ouverte.

Les variables locales, en revanche, ne sont accessibles qu’à l’intérieur de la fonction dans laquelle elles ont été déclarées et ne « vivent » que durant l’exécution de cette fonction à priori. Attention : je dis bien à priori.

Les closures en théorie

Une closure (de « close », « fermé » en anglais) est une fonction qui va récupérer et pouvoir utiliser des variables d’environnement dans laquelle elle a été créée.

Autrement dit, une closure va nous permettre d’isoler ou d’enfermer une partie de code et de pouvoir utiliser et récupérer des variables qui ne sont accessibles normalement que depuis l’intérieur de ce code.

Voilà tout pour la théorie. Maintenant, il est temps de passer aux exemples afin d’illustrer ce que nous venons de dire et de bien vous faire comprendre l’intérêt des closures.

Les closures en pratique

Lorsque l’on explique le principe de closures, il est coutume de prendre l’exemple de la création d’un compteur. Commencez donc par observer le code ci-dessous.

On crée une fonction qui en retourne une autre

Notre fonction retourne bien une autre fonction

Essayer ce code !

Concentrez vous bien sur l’explication de ce que fait ce code : c’est tout à fait à votre portée.

Comme vous le voyez, on crée une fonction compteur(). Cette fonction initialise une variable i et retourne une fonction anonyme.

Soyez bien attentif par rapport à cette fonction anonyme : on remarque que celle-ci se ressert de la variable i définie dans sa fonction parente et retourne la valeur de i incrémentée.

Commencez déjà par noter qu’en JavaScript il est tout à fait normal et naturel qu’une fonction ait accès aux variables de sa fonction parente (on parle de parent car on voit bien que notre fonction anonyme est enfermée dans notre fonction compteur).

Cependant, notez ici un point très intéressant : si jamais on appelle compteur(), la fonction anonyme va être renvoyée mais pas exécutée immédiatement.

En effet, rappelez vous que pour exécuter une fonction anonyme il faut soit l’enfermer dans une variable soit la transformer en fonction auto-invoquée en lui ajoutant deux couples de parenthèses.

Résumons donc la situation : si on appelle compteur(), une variable i est initialisée et notre fonction anonyme est renvoyée mais pas exécutée.

Ici, la logique voudrait que si on exécute ENSUITE notre fonction anonyme, la variable i ne soit plus accessible et donc que la fonction anonyme ne renvoie rien du tout puisque notre fonction compteur() dans laquelle la variable i a été déclarée a déjà fini son exécution.

Eh bien non, et c’est là toute la magie des closures. Même après la fin de l'exécution de notre fonction compteur(), notre fonction anonyme va toujours pouvoir se servir de cette variable i.

Cela peut vous sembler assez minime pour le moment, mais je vous assure que ça va nous permettre de faire énormément de choses, notamment lorsqu’on saura comment modifier le code HTML d’une page web.

Il est maintenant temps de terminer notre closure à proprement parler en utilisant une nouvelle variable pour « fermer » le code ci-dessus et exécuter notre fonction anonyme.

Notez que j'aurais tout à fait pu utiliser une fonction auto-inovquée à la place de ma fonction compteur() ci-dessous.

Création de notre première closure

Notre variable i est inaccessible depuis l’extérieur et pourtant notre closure peut s’en servir

Essayer ce code !

Ce code comporte deux immenses avantages : d’une part, notre variable i est « protégée » au sens où elle ne peut pas être modifiée par l’environnement extérieur. D’autre part, on va pouvoir créer autant d’instances de notre fonction compteur() que l’on souhaite.

Typiquement, notre variable (qui contient une fonction et qu’on peut donc également appeler fonction tout simplement) plusUn est ce qu’on appelle une closure.

plusUn peut utiliser i à loisir, en se souvenant à chaque fois de sa valeur ce qui fait que notre compteur va s’incrémenter correctement.

De plus, on va pouvoir créer de nouvelles instances en rappelant notre fonction compteur(), et donc travailler avec plusieurs variables i aux valeurs différentes.

Regardez plutôt l’exemple ci-dessous pour vous en persuader :

Le grand avantage des closures

On peut créer autant d’instance de notre fonction que l’on souhaite

Essayer ce code !

Chapitre précédent

Chapitre suivant