web-dev-qa-db-fra.com

À quoi fait exactement référence la «fermeture» en JavaScript?

Je comprends ce que sont les fermetures, mais j'ai du mal à comprendre exactement à quoi se réfère le terme closure. J'ai vu le terme utilisé dans de nombreux sites Web, mais ils s'accordent rarement sur sa définition réelle.

  • Est-ce que ce sont les variables qui sont conservées sur le cadre de pile?
  • Est-ce la fonction qui est renvoyée?
  • Est-ce la portée de la fonction extérieure?
  • Est-ce la portée de la fonction interne (renvoyée)?
  • Est-ce peut-être le concept de garder les variables sur le stack-frame après avoir renvoyé la fonction?

Quelqu'un peut-il me dire exactement à quoi se réfère closure?

71
Andreas Grech

De fermetures JavaScript

Deux résumés d'une phrase:

Une fermeture correspond aux variables locales d'une fonction - maintenues en vie après le retour de la fonction, ou

Une fermeture est un cadre de pile qui n'est pas désalloué lorsque la fonction revient. (comme si un 'stack-frame' était mallocé au lieu d'être sur la pile!)

Un très bon article sur les fermetures

fermetures Javascript

Une "fermeture" est une expression (généralement une fonction) qui peut avoir des variables libres avec un environnement qui lie ces variables (qui "ferme" l'expression).

L'explication simple d'une fermeture est que ECMAScript autorise les fonctions internes; définitions de fonction et expressions de fonction qui se trouvent à l'intérieur des corps de fonction d'autres fonctions. Et que ces fonctions internes sont autorisées à accéder à toutes les variables locales, les paramètres et les fonctions internes déclarées dans leurs fonctions externes. Une fermeture est formée lorsque l'une de ces fonctions internes est rendue accessible en dehors de la fonction dans laquelle elle était contenue, afin qu'elle puisse être exécutée après le retour de la fonction externe. À ce stade, il a toujours accès aux variables locales, aux paramètres et aux déclarations de fonction interne de sa fonction externe. Ces variables locales, paramètres et déclarations de fonctions (initialement) ont les valeurs qu'elles avaient lorsque la fonction externe est retournée et peuvent être interagies avec la fonction interne.

Un bon exemple ici

JavaScript, il est temps de fermer les portes

45
rahul

C'est une fonction qui "détient" une référence ou des références à quelque chose dans une autre portée. Par exemple:

var myArrayOfFunctions = [];

for(var i = 0; i<3: i++)
{
    //Note how the function being defined uses i, 
    //where i lives in the parent's scope, this creates a closure
    myArrayOfFunctions[i] = function(a) { return a + i;}    
}

myArrayOfFunctions[0](5);   //Prints 8 WTF!
myArrayOfFunctions[1](5);   //8 again
myArrayOfFunctions[2](5);   //Well, this 8 was expected

Cela se produit parce que lorsque les fonctions sont "créées", elles ne copient pas la valeur de i, elles contiennent une référence à i, donc lorsque nous appelons les fonctions, elles utilisent la valeur actuelle de i qui est 3.

Voici une explication graphique.

6
Daniel Rodriguez

Pour moi, les fermetures dans JS vous permettent de faire ce qui suit.
"a" reste disponible dans la fonction interne lorsqu'il est ajouté à "b" bien qu'il soit déclaré à l'extérieur.

function adder(a){
  return function(b){
    return a + b;
  };
}
var add5 = adder(5);
alert( add5(10) );

Pour une utilisation extrême des fermetures JS, vous pouvez jeter un œil au code source de la bibliothèque PURE (un moteur de template JS)

4
Mic

Considérez le code suivant qui crée une fermeture avec les variables a et b

closure=(function(){ 

    var a=3
    var b=5 

return  function(operation){ 
          return operation(a,b)
      }
 }())


// The variables a and b are now part of the closure (They are retained even after the outer function returns)


closure(function(x,y){return x+y})  // outputs 8

closure(function(x,y){return x*y}) // outputs 15`

Cette fermeture particulière peut maintenant prendre n'importe quelle fonction qui opère sur les variables a et b

2
sarath joseph

Pour autant que je sache, une fermeture est une fonction définie dans une autre fonction qui survit à la portée de la fonction parent. Un exemple courant est les rappels:

function delay_message(msg)
{
     setTimeout(function closure() { alert(msg); }, 1000);
}

Dans ce cas, le function closure Ci-dessus est défini dans le corps de delay_message, Mais la définition de la fonction - ainsi que la variable de la fonction parent msg - survivent à la portée de l'appel de la fonction delay_message.

2
intgr

Une fermeture est une valeur de fonction créée à partir d'une déclaration de fonction imbriquée ou d'une expression de fonction (c'est-à-dire une expression lambda) dont le corps contient une ou plusieurs références à des variables déclarées dans une portée externe (mais pas globale).

1
Theodore Norvell

Une fermeture est essentiellement un corps de fonction fermé sur ses identifiants (variables) dans son environnement local.

1
Mark Ursino

La fermeture signifie une fonction (fonction externe) contenant une autre fonction (fonction interne).

La fermeture est utilisée pour protéger les données.

l'utilisation de plus près est démontrée dans le lien vidéo ci-dessous:

https://www.youtube.com/watch?v=w1s9PgtEoJs

0
Abhishek-Saini