2010-07-20 11 views
13

Sto chiudendo la testa intorno alle chiusure di JavaScript e sono in un punto in cui le cose stanno cadendo sul posto; vale a dire una chiusura è le variabili locali per una funzione, mantenuta in vita dopo che la funzione è ritornata, oppure una chiusura è uno stack-frame che non viene deallocato quando la funzione restituisce.Perché abbiamo le chiusure in JavaScript?

Sto iniziando a capire questo concetto, ma più capisco e più continuo a chiedermi perché dobbiamo usarli.

Un esempio come questo mi fa capire il concetto ma mi lascia chiedere, c'è un modo più semplice per farlo!

function sayHello(name) { 
    var text = 'Hello ' + name; 
    var sayAlert = function() { alert(text); } 
    sayAlert(); 
} 
sayHello('Gath'); 

Mi chiedo solo perché devo mantenere in vita la variabile locale? dopo che la funzione è stata chiusa?

Dove posso trovare esempi di soluzioni implementate tramite la chiusura e che nient'altro avrebbe funzionato ma chiusure?

+7

Cerca qui una grande quantità di risposte: http://stackoverflow.com/questions/111102/how-does-a-javascript-closure-work –

risposta

7

Le chiusure aggiungono potenza espressiva alla lingua. Ci sono alcuni modelli che possono essere implementati molto facilmente a causa delle chiusure. Alcuni esempi che vengono in mente sono:

0

L'esempio che hai scelto viene visualizzato su this page, quindi presumo che tu l'abbia preso da lì. Hai guardato tutti gli altri esempi che fornisce? Spiegano le motivazioni per chiusure meglio di quanto io possa.

+0

Sì, l'ho fatto, ma ancora non mostrano uno scenario in cui tutto il resto è fallito e la chiusura era l'unica cosa che poteva fare il trucco – gath

+0

@gath - sì, lo fanno. Molti di questi esempi sono funzioni che hanno altre funzioni come valore di ritorno. Se si chiama la funzione esterna, si salva un riferimento alla funzione restituita e quindi si chiama la funzione restituita in un momento successivo, quegli esempi non potrebbero funzionare senza chiusure. –

+0

@gath: tutto può essere scritto in assembler. Le chiusure non sono state inventate per risolvere problemi che non potrebbero mai essere risolti prima, quindi non troverete alcun problema che possa essere risolto solo con chiusure. Rendono alcuni problemi molto più semplici da risolvere, e se rivedi questi esempi con questo in mente, potrebbero iniziare a dare più senso a te. –

2

Una chiusura è una funzione con tutto l'ambiente necessario per l'esecuzione. In javascript, è quando viene creata una funzione anonima (= lambda), utilizzando una variabile da un ambito esterno.

si può meglio capire perché con un codice del genere:

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

bar = foo(); 

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

Qui, si restituisce una funzione che utilizza la variabile locale "testo". Pertanto, si sta abbandonando l'ambito della funzione foo, distruggendo le sue variabili. Tuttavia, poiché abbiamo una funzione anonima che utilizza il testo, dobbiamo tenere traccia di questa variabile. Questo può essere ottenuto per valore o per riferimento, a seconda della lingua (mantenendo la variabile in vita (con la possibilità di modificarla successivamente o di copiarne il valore quando viene creata la funzione)).

Spero che questo aiuti!

0

una funzione normale fa il suo cosa, calcola un risultato e lo restituisce. Restituendo una chiusura, è possibile impacchettare il lavoro a metà e lasciare che i chiamanti ottengano di più quando sono pronti per farlo. Da quando ho provato l'università Scheme, ho desiderato ardentemente chiusure in tutte le lingue con cui ho lavorato da quando ... si stanno pericolosamente formando!

Sono anche probabilmente una parte importante del futuro: insieme ad altri meccanismi programmazione funzionale che ti una buona misura per la programmazione parallela di sistemi multi-core.

2

"Una chiusura è un oggetto da povero: un oggetto è la chiusura di un povero." (Scusa, ho dimenticato la fonte).

A volte abbiamo bisogno di variabili che sono necessarie solo per un blocco di codice. Mettiamo quel blocco di codice in una funzione e abbiamo quelle variabili come variabili locali per quella funzione.

A volte sono necessarie le variabili necessarie per tutte le funzioni/i blocchi di codice nel programma. Possiamo avere queste variabili come variabili globali.

A volte sono necessarie le variabili necessarie per alcune funzioni/blocchi di codice. Ad esempio, abbiamo un'entità chiamata Sales e vogliamo mettere insieme tutti i nostri codici relativi alle vendite. Quindi abbiamo un gruppo di funzioni e un gruppo di variabili che si occupa delle vendite. Possiamo mettere insieme queste funzioni e variabili in un oggetto, in modo che siano isolate (sia le funzioni che le variabili) da altre parti del codice.

Nelle lingue che non supportano direttamente gli oggetti, possiamo avere funzioni annidate. La funzione esterna agisce come classe, le funzioni interne agiscono come metodi. Le variabili locali alla funzione esterna agiscono come i campi, sono accessibili solo alle funzioni interne. Nelle chiamate successive alle funzioni interne, vogliamo mantenere lo stato delle variabili funzione locale-esterno, questo è dove sono necessarie le chiusure. Tutto ciò che dobbiamo fare è passare il riferimento a qualsiasi funzione interna tramite l'output della funzione esterna, per codificare all'esterno della funzione esterna, in modo che le variabili della funzione esterna accessibili dalla funzione interna siano preservate anche dopo che la funzione esterna è stata chiusa.

+0

questa è un'eccellente analogia – qodeninja

Problemi correlati