Fermetures de fonctions JavaScript


Table des matières

    Afficher la table des matières


Les variables JavaScript peuvent appartenir au local ou Portée mondiale.

Les variables globales peuvent être rendues locales (privées) avec des fermetures.


Variables globales

Une fonction peut accéder à toutes les variables définies à l'intérieur de la fonction, comme ceci :

Exemple

function myFunction() {
    let a = 4;
    return a * a;
}

Essayez-le vous-même →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Functions</h2>
<p>A function can access variables defined inside the function:</p>

<p id="demo"></p>

<script>
myFunction();

function myFunction() {
  let a = 4;
  document.getElementById("demo").innerHTML = a * a;
}
</script>

</body>
</html>

Mais une fonction peut également accéder à des variables définies en dehors de la fonction, comme ceci :

Exemple

let a = 4;
function myFunction() {
    return a * a;
}

Essayez-le vous-même →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Functions</h2>
<p>A function can access variables defined outside the function:</p>

<p id="demo"></p>

<script>
let a = 4;
myFunction();

function myFunction() {
  document.getElementById("demo").innerHTML = a * a;
} 
</script>

</body>
</html>

Dans le dernier exemple, a est un global variable.

Dans une page Web, les variables globales appartiennent à la page.

Les variables globales peuvent être utilisées (et modifiées) par tous les autres scripts de la page.

Dans le premier exemple, a est un local variable.

Une variable locale ne peut être utilisée qu'à l'intérieur de la fonction où elle est définie. Il est masqué des autres fonctions et autres codes de script.

Mondial et les variables locales du même nom sont différentes variables. Modifier l’un ne modifie pas l’autre.

Note

Variables créées sans un mot-clé de déclaration (var, let, ou const) sont toujours global, même s’ils sont créés à l’intérieur d’une fonction.

Exemple

function myFunction() {
  a = 4;
}

Essayez-le vous-même →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Functions</h2>
<p>Variables created without a declaration keyword (var, let, or const) are always global,
even if they are created inside a function.:</p>

<p id="demo"></p>

<script>
myFunction();
document.getElementById("demo").innerHTML = a * a;

function myFunction() {
  a = 4;
} 
</script>

</body>
</html>


Durée de vie variable

Les variables globales restent actives jusqu'à ce que la page soit supprimée, comme lorsque vous naviguez vers une autre page ou fermez la fenêtre.

Locale les variables ont une durée de vie courte. Ils sont créés lorsque la fonction est invoqué et supprimé lorsque la fonction est terminée.


Un contre-dilemme

Supposons que vous souhaitiez utiliser une variable pour compter quelque chose et que vous vouliez ceci compteur pour être disponible pour toutes les fonctions.

Vous pouvez utiliser une variable globale et une fonction pour augmenter le compteur :

Exemple

 // Initiate counter
let counter = 0;
// Function to increment 
  counter
function add() {
  counter += 1;
}
// Call add() 3 times
add();
add();
add();
// The counter should now be 3

Essayez-le vous-même →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Function Closures</h2>
<p>Counting with a global variable.</p>

<p id="demo"></p>

<script>
// Initiate counter
let counter = 0;

// Function to increment counter
function add() {
  counter += 1;
}

// Call add() 3 times
add();
add();
add();

// The counter should now be 3
document.getElementById("demo").innerHTML = "The counter is: " + counter;
</script>

</body>
</html>

Il y a un problème avec la solution ci-dessus : n'importe quel code sur la page peut modifier le compteur, sans en appelant add().

Le compteur doit être local à la fonction add(), pour empêcher tout autre code de changer il:

Exemple

 // Initiate counter
let counter = 0;
// Function to increment 
  counter
function add() {
  let counter = 0; 
  
  counter += 1;
}
// 
  Call add() 3 times
add();
add();
add();
//The counter should 
  now be 3. But it is 0

Essayez-le vous-même →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Function Closures</h2>
<p>Counting with a local variable.</p>

<p id="demo"></p>

<script>
// Initiate counter
let counter = 0;

// Function to increment counter
function add() {
  let counter = 0; 
  counter += 1;
}

// Call add() 3 times
add();
add();
add();

// The result is not 3 because you mix up the globaland local counter
document.getElementById("demo").innerHTML = "The counter is: " + counter;
</script>

</body>
</html>

Cela n'a pas fonctionné car nous affichons le compteur global au lieu du local comptoir.

Nous pouvons supprimer le compteur global et accéder au compteur local en laissant le la fonction le renvoie :

Exemple

 // Function to increment 
  counter
function add() {
  let counter = 0; 
  
  counter += 1;
  return counter;
}
// 
  Call add() 3 times
add();
add();
add();
//The counter should 
  now be 3. But it is 1.

Essayez-le vous-même →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Closures</h2>
<p>Counting with a local variable.</p>

<button type="button" onclick="myFunction()">Count!</button>

<p id="demo">0</p>

<script>
// Function to increment counter
function add() {
  let counter = 0;
  counter += 1;
  return counter;
}
// Trying to increment the counter
function myFunction(){
  document.getElementById("demo").innerHTML = add();
}
</script>

</body>
</html>

Cela n'a pas fonctionné car nous réinitialisons le compteur local à chaque fois que nous appelons le fonction.

Une fonction interne JavaScript peut résoudre ce problème.


Fonctions imbriquées JavaScript

Toutes les fonctions ont accès à la portée globale.

En fait, en JavaScript, toutes les fonctions ont accès à la portée « au-dessus » d’elles.

JavaScript prend en charge les fonctions imbriquées. Les fonctions imbriquées ont accès aux portée "au-dessus" d'eux.

Dans cet exemple, la fonction interne plus() a accès à la variable counter dans la fonction parent :

Exemple

function add() {
    let counter = 0;
    function plus() {counter += 1;}
  plus();   
 
  return counter; 
}

Essayez-le vous-même →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Function Closures</h2>
<p>Counting with a local variable.</p>

<p id="demo">0</p>

<script>
document.getElementById("demo").innerHTML = add();
function add() {
  let counter = 0;
  function plus() {counter += 1;}
  plus();  
  return counter; 
}
</script>

</body>
</html>

Cela aurait pu résoudre le dilemme du compteur, si nous avions pu atteindre le plus() fonctionner de l’extérieur.

Nous devons également trouver un moyen d'exécuter counter=0 une seule fois.

Nous avons besoin d'une clôture.


Fermetures JavaScript

Vous vous souvenez des fonctions auto-invoquantes ? A quoi sert cette fonction ?

Exemple

const add = (function () {
  let counter = 0;
  return function () {counter += 1; return counter}
})();
add();
add();
add();

// the counter is now 3

Essayez-le vous-même →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Closures</h2>

<p>Counting with a local variable.</p>

<button type="button" onclick="myFunction()">Count!</button>

<p id="demo">0</p>

<script>
const add = (function () {
  let counter = 0;
  return function () {counter += 1; return counter;}
})();

function myFunction(){
  document.getElementById("demo").innerHTML = add();
}
</script>

</body>
</html>

Exemple expliqué

La variable add est affectée à la valeur de retour d'un auto-appelant fonction.

La fonction d'auto-invocation ne s'exécute qu'une seule fois. Il remet le compteur à zéro (0), et renvoie une expression de fonction.

De cette façon, add devient une fonction. Ce qui est "merveilleux", c'est qu'il peut accéder le compteur dans la portée parent.

C'est ce qu'on appelle une fermeture JavaScript. Cela permet pour qu'une fonction ait des variables "privées".

Le compteur est protégé par le périmètre de la fonction anonyme, et ne peut être modifié qu'à l'aide de la fonction add.

Une fermeture est une fonction ayant accès à la portée parent, même après la fermeture de la fonction parent.