2010-07-20 16 views
13

Enveloppant ma tête autour des fermetures JavaScript et suis à un point où les choses se mettent en place; une fermeture est les variables locales pour une fonction - maintenue en vie après le retour de la fonction, ou une fermeture est une pile-cadre qui n'est pas désaffectée lorsque la fonction retourne. Je commence à comprendre ce concept, mais plus je comprends, plus je continue à me demander pourquoi nous devons les utiliser.Pourquoi avons-nous des fermetures en JavaScript?

Un exemple comme celui-ci me fait comprendre le concept mais me laisse poser, il y a une façon plus simple de le faire! Je me demande pourquoi dois-je conserver la variable locale vivante? après la sortie de la fonction?

Où puis-je obtenir des exemples montrant des solutions mises en œuvre par la fermeture et que rien d'autre aurait fonctionné mais des fermetures?

+7

Regardez ici pour un grand nombre de réponses: http://stackoverflow.com/questions/111102/how-does-a-javascript-closure-work –

Répondre

7

Les fermetures ajoutent une puissance expressive à la langue. Certains modèles peuvent être mis en œuvre très facilement en raison des fermetures. Quelques exemples qui viennent à l'esprit sont:

0

L'exemple que vous avez choisi apparaît sur this page, donc je suppose que vous l'avez pris à partir de là. Avez-vous examiné tous les autres exemples qu'il fournit? Ils expliquent les motivations des fermetures mieux que je ne le pourrais.

+0

Oui je l'ai fait, mais ils ne présentent toujours pas un scénario où tout le reste a échoué et la fermeture était la seule chose qui pourrait faire l'affaire – gath

+0

@gath - oui ils le font. Beaucoup de ces exemples sont des fonctions qui ont d'autres fonctions comme valeur de retour. Si vous appelez la fonction externe, enregistrez une référence à la fonction renvoyée, puis appelez la fonction retournée ultérieurement, ces exemples ne peuvent pas fonctionner sans fermetures. –

+0

@gath: Tout peut être écrit en assembleur. Les fermetures n'ont pas été inventées pour résoudre des problèmes qui n'auraient jamais pu être résolus auparavant, donc vous ne trouverez pas de problèmes qui ne peuvent être résolus qu'avec des fermetures. Ils rendent certains problèmes beaucoup plus simples à résoudre, et si vous revenez sur ces exemples en gardant ceci à l'esprit, ils pourraient vous sembler plus compréhensibles. –

2

Une fermeture est une fonction avec tout l'environnement nécessaire à son exécution. En javascript, c'est lorsqu'une fonction anonyme (= lambda) est créée, en utilisant une variable d'une portée externe.

Vous pouvez mieux comprendre pourquoi avec un code comme ça:

function foo() 
{ 
    var text = computeFromOutside(); 
    // ... other lines of code 
    return function(otherText) { return text + otherText; } 
} 

bar = foo(); 

function baz(fun) 
{ 
    return fun("some text"); 
} 

Ici, vous retournez une fonction qui utilise la variable locale « texte ». Par conséquent, vous quittez la portée de la fonction foo, en détruisant ses variables. Cependant, puisque nous avons une fonction anonyme utilisant du texte, nous devons garder une trace de cette variable. Ceci peut être obtenu par valeur ou par référence, en fonction de la langue (Garder la variable en vie (avec la possibilité de la modifier par la suite, ou de copier sa valeur lorsque la fonction est créée)).

J'espère que cela aide!

0

Une fonction normale fait son chose, calcule un résultat et le renvoie. En retournant une fermeture, vous pouvez emballer votre travail à mi-chemin et laisser les appelants obtenir plus quand ils sont prêts pour cela. Depuis que j'ai essayé Scheme à l'université, j'ai toujours rêvé de fermetures dans toutes les langues avec lesquelles j'ai travaillé depuis ... ils forment dangereusement des habitudes! Ils sont aussi sans doute une partie importante de l'avenir: avec d'autres mécanismes de programmation fonctionnelle qui semblent bien adaptés à la programmation parallèle de systèmes multi-cœurs.

2

"Une fermeture est un objet de pauvre, un objet est une fermeture de pauvre." (Désolé, j'ai oublié la source).

Parfois, nous avons besoin de variables qui ne sont nécessaires que par un bloc de code. Nous mettons ce bloc de code dans une fonction et avons ces variables comme variables locales à cette fonction.

Parfois, nous avons besoin de variables qui sont nécessaires par tous les les fonctions/blocs-de-code dans le programme. Nous pouvons avoir ces variables comme variables globales.

Parfois, nous avons besoin de variables qui sont nécessaires par certains fonctions/blocs-de-code. Par exemple, nous avons une entité appelée Ventes et nous voulons mettre tout notre code lié aux ventes ensemble. Nous avons donc un groupe de fonctions et un groupe de variables qui traitent des ventes. Nous pouvons regrouper ces fonctions et ces variables dans un objet, afin qu'elles soient isolées (à la fois les fonctions et les variables) des autres parties du code.

Dans les langues qui ne prennent pas directement en charge les objets, nous pouvons avoir des fonctions imbriquées. La fonction externe agit comme une classe, les fonctions internes agissent comme des méthodes. Les variables locales à la fonction externe agissent comme des champs, elles ne sont accessibles qu'aux fonctions internes. Dans les appels ultérieurs aux fonctions internes, nous voulons maintenir l'état des variables de la fonction locale vers la fonction externe, c'est là que les fermetures sont nécessaires. Tout ce que nous avons à faire est de passer la référence à toute fonction interne via la sortie de la fonction externe, de coder en dehors de la fonction externe, de sorte que les variables de fonction externe accédées par la fonction interne soient préservées même après la sortie de la fonction externe.

+0

c'est une excellente analogie – qodeninja