Maison >interface Web >js tutoriel >Maîtriser les fermetures en JavaScript : un guide complet avec des exemples

Maîtriser les fermetures en JavaScript : un guide complet avec des exemples

Linda Hamilton
Linda Hamiltonoriginal
2024-11-21 11:46:14538parcourir

Mastering Closures in JavaScript: A Complete Guide with Examples

Introduction

Imaginez que vous créez une application, tard dans la nuit, un café à la main, tout en débogant un morceau de code JavaScript qui se comporte... mystérieusement. Cela appelle une fonction dans une autre fonction, en conservant des valeurs d'une manière à laquelle vous ne vous attendiez pas, et vos instructions console.log ne rendent pas les choses plus claires. Soudain, vous réalisez que le problème est quelque chose dont vous n’avez entendu parler que : les fermetures.

Les fermetures en JavaScript sont souvent présentées comme un concept quelque peu magique ou abstrait. Mais ils constituent en réalité un élément fondamental de la façon dont JavaScript gère les fonctions et la portée, et les comprendre peut transformer cette session de codage de minuit en un « aha ! moment plutôt qu’une expérience frustrante. Ce guide décomposera les fermetures de manière à les rendre accessibles, utiles et même agréables, avec des informations et des exemples qui vont au-delà des bases.

Que sont les fermetures ?

Les fermetures sont une fonctionnalité de JavaScript où une fonction interne a accès aux variables de la fonction externe (englobante), même une fois l'exécution de la fonction externe terminée. Cela se produit parce que JavaScript « ferme » l'environnement (la portée lexicale) dans lequel la fonction a été créée, préservant ainsi le contexte en mémoire. Le résultat ? Des fonctions qui peuvent « se souvenir » de l'environnement dans lequel elles ont été créées, permettant des fonctionnalités puissantes telles que la confidentialité des données, la mémorisation, etc.

Définition concrète des fermetures

Imaginez que vous vivez dans une maison avec plusieurs pièces et que vous disposez d'une clé qui déverrouille une pièce spécifique – appelons-la la « salle de données ». La clé symbolise une fermeture. Même si la porte principale (la fonction qui a créé la clé) est verrouillée, vous avez toujours accès à la Data Room car vous avez conservé la clé. De même, une fermeture conserve l'accès aux variables dans sa fonction d'origine, même lorsque cette fonction est déjà terminée.

Pourquoi les fermetures sont importantes pour les développeurs

Les fermetures sont fondamentales pour créer des variables privées et des modèles fonctionnels tels que le curry et la mémorisation. Selon l'enquête auprès des développeurs de Stack Overflow, JavaScript est le langage de programmation le plus populaire, utilisé par près de 65 % des développeurs professionnels. Une solide maîtrise des fermetures est donc essentielle pour utiliser efficacement JavaScript.


Comment fonctionnent les fermetures en JavaScript : exemples et modèles

Exemple de fermeture de base

Commençons par un exemple simple qui montre comment les fermetures fonctionnent en action.

function createCounter() {
  let count = 0;
  return function() {
    count++;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // Output: 1
console.log(counter()); // Output: 2

Voici ce qui se passe dans ce code :

  1. La fonction createCounter définit un nombre de variables locales.
  2. La fonction interne (la fermeture) incrémente la variable count et la renvoie.
  3. Même si createCounter a fini de s'exécuter, la fonction interne a toujours accès au count — c'est une fermeture en action.

Cet exemple peut paraître simple, mais il met en valeur une caractéristique importante des fermetures : la préservation de l'état.


Aller plus loin : cas d'utilisation avancés des fermetures

1. Confidentialité des données avec fermetures

L'un des cas d'utilisation les plus puissants des fermetures est la création de confidentialité des données, une technique qui nous permet de restreindre l'accès direct à certaines variables ou fonctions.

function createCounter() {
  let count = 0;
  return function() {
    count++;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // Output: 1
console.log(counter()); // Output: 2

Ici, le solde est privé et ne peut être consulté ou modifié que via un dépôt et getBalance. Ceci est similaire à la façon dont fonctionnent les champs privés en POO, mais en JavaScript, nous utilisons des fermetures pour y parvenir.

2. Fonctions de curry avec fermetures

Le currying est un modèle de programmation fonctionnel qui exploite les fermetures pour permettre aux fonctions d'être partiellement appliquées.

function bankAccount(initialBalance) {
  let balance = initialBalance;

  return {
    deposit(amount) {
      balance += amount;
    },
    getBalance() {
      return balance;
    }
  };
}

const myAccount = bankAccount(1000);
myAccount.deposit(500);
console.log(myAccount.getBalance()); // Output: 1500
console.log(myAccount.balance); // Output: undefined

Dans cet exemple, le multiplicateur crée une fermeture qui conserve l'accès au facteur, nous permettant de créer des fonctions spécialisées comme le double ou le triple en passant simplement différents facteurs.


Pièges courants et comment les éviter

Fermetures en boucles

Les fermetures peuvent trébucher les développeurs lorsqu'elles sont utilisées dans des boucles. Un problème typique implique des fermetures capturant la variable de la boucle plutôt que sa valeur actuelle.

Considérez cet exemple :

function multiplier(factor) {
  return function(number) {
    return number * factor;
  };
}

const double = multiplier(2);
console.log(double(5)); // Output: 10

Sortie :

for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}

Parce que i est partagé sur toutes les itérations de la boucle, la valeur finale de i (3) est imprimée trois fois. Pour résoudre ce problème, utilisez let pour créer une variable de portée bloc ou créez une fermeture dans la boucle :

3
3
3

Maintenant, la sortie sera 0, 1, 2 comme prévu, car chaque fonction a sa propre copie de i (ici j).


Considérations relatives aux performances

Les fermetures peuvent consommer de la mémoire car elles conservent des variables provenant de portées externes. Dans les applications hautes performances, soyez attentif aux fuites de mémoire en nettoyant les fermetures lorsqu'elles ne sont plus nécessaires, en particulier dans les applications à exécution longue. Des outils tels que Chrome DevTools fournissent des outils de profilage de la mémoire qui peuvent aider à identifier et à optimiser l'utilisation de la mémoire.


Applications pratiques dans les frameworks JavaScript

Les fermetures sont fondamentales dans les frameworks populaires comme React, où des hooks tels que useState et useEffect utilisent des fermetures pour « mémoriser » les valeurs et l'état entre les rendus. Comprendre les fermetures peut démystifier le fonctionnement de ces hooks sous le capot, facilitant ainsi l'écriture de code optimisé et sans bug.


Réflexions finales : tirer le meilleur parti des fermetures

Maîtriser les fermetures peut ouvrir la porte à de nombreuses techniques de programmation avancées. Ils sont essentiels pour écrire du code JavaScript propre, modulaire et efficace. Plutôt que de fuir les fermetures, adoptez-les comme un outil puissant dans votre boîte à outils JavaScript.


Sources

  1. Mozilla Developer Network (MDN) : fermetures
  2. JavaScript : Le guide définitif par David Flanagan

Comprendre les fermetures vous aide non seulement à déboguer le code plus rapidement, mais constitue également une base solide pour maîtriser la structure basée sur les fonctions de JavaScript, vous aidant ainsi à passer en douceur aux frameworks, à la programmation backend avec Node.js, et bien plus encore. Que vous construisiez une application évolutive ou créiez des interfaces hautement interactives, les fermetures sont une compétence qui mérite d'être maîtrisée.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn