2012-10-05 15 views
5

Citazione da Stoyan Stefanov di JavaScript Object-Oriented (pagina 84):Questa è una dichiarazione corretta per la chiusura?

enter image description here

Se siete a punto una, sei dentro lo spazio globale. Se ci si trova al punto b, che è all'interno dello spazio della funzione F, allora si ha accesso allo spazio globale e a lo spazio F. Se si è al punto c, che si trova all'interno della funzione N, è possibile accedere allo spazio globale, allo spazio F e allo spazio N Non è possibile raggiungere da a a b, perché b è invisibile all'esterno di F Ma puoi ottenere da c a b se vuoi, o da N a b. La interessante cosa-chiusura-accade quando qualche modo N scoppia di F e finisce fino nello spazio globale "

penso che la frase in grassetto di cui sopra dovrebbe essere cambiato in" Se sei al punto c , che si trova all'interno della funzione N, allora puoi accedere allo spazio globale e allo spazio N "(lo spazio F non dovrebbe essere contenuto, perché il punto c ha accesso solo allo spazio N e allo scopo globale G.) .

ho ragione? grazie.

+0

Perché non dovresti accedere a F? N è all'interno di F. Penso che il disegno debba trasmettere che N è stato dichiarato all'interno di _ E _returned from_ function F. – jahroy

+0

Non necessariamente "restituito da" @jahroy. Esistono altri meccanismi per creare un riferimento esterno a una funzione interna, ad esempio l'assegnazione diretta a un membro esterno o al suo allegato, come gestore di eventi, a un elemento DOM. –

risposta

1

Come altri hanno già detto, no.

Quasi tutto il punto su una chiusura è che un riferimento esterno a una funzione interna mantiene attiva non solo la funzione interna, ma consente anche di accedere all'ambiente esterno in cui è stata creata, anche se quell'ambiente esterno è sorto da una funzione eseguita che ha completato e restituito.

ritengo diagramma sarebbe meglio illustrare chiusura se il blu N stati mostrati all'interno F e la versione tratteggiata (il riferimento N) sono stati mostrati fuori F.

L'ultima frase del comunicato citato potrebbe anche essere migliorato:

La cosa interessante - una chiusura - accade quando un riferimento esterno al N esiste, al di fuori F.

Si noti che questa versione evita di menzionare lo spazio globale. Qualsiasi ambito esterno sarà sufficiente per formare una chiusura.

La dichiarazione potrebbe andare oltre per dire che il meccanismo che consente di formare chiusure è la soppressione della Garbage Collection.

Avviso: ci sono molte definizioni e descrizioni errate di "chiusura", sia sul Web che nei libri. La voce wiki di tag "Overflow" di Stack Overflow è un esempio calzante.

+0

Certo, ci sono troppe descrizioni errate di "chiusura", ma la tua descrizione ("una chiusura ... che è stata creata") è la migliore che abbia mai letto. Inoltre, ritengo che la chiusura dovrebbe essere presa dalla prospettiva della "portata della catena", piuttosto che dal confronto dell'implementazione con altri linguaggi (ad esempio, variabili dello stack in stile C). Sei d'accordo? –

+0

@MattElson, grazie per il tuo gentile commento. Il mio sentimento più forte su questo argomento è che ogni definizione che inizia con "Una chiusura è una funzione ..." è condannata perché tali definizioni non sono fedeli al concetto originale di Landin di chiusura "che ha una parte ambientale e una parte di controllo". Qui non c'è posto, ma c'è un'altra ragione convincente per allontanarsi dall'onnipresente tipo di definizione "... è una funzione ...". Un giorno scriverò tutto in un foglio e lo presenterò a una conferenza. –

2

No, penso che quello che sta dicendo è che N è una funzione che è stato restituito fr om funzione F, e quindi ha accesso (tramite una chiusura) alla variabile b che è stata dichiarata all'interno di F. Per esempio (live example):

function F() { 
    var b = 10; 
    return function() { 
     console.log(b); 
    };  
} 

var N = F(); //N is a reference to the anonymous function returned from F 

N(); //logs '10' because we still have access to b (because of the closure) 
+0

È esattamente come l'ho letto: il cerchio blu (disegnato fuori dal cerchio rosso, ma puntato indietro verso di esso) dovrebbe rappresentare una funzione che è stata _stampata_ da F. – jahroy

1

No, non hai ragione.

Il cerchio tratteggiato rappresenta il campo reale di N come interno F.

1

No, al punto c si ha effettivamente accesso allo spazio F.

Un esempio di questo:

function F() { 

    var b = 42; 

    function N() { 
    alert(b); 
    } 

    return N; 

} 

// get a reference to the function N in the global scope: 
var n = F(); 
n(); // shows 42 
1

No, non hai ragione, guarda il codice qui sotto.

// the global space 
var g = 'g'; 

function F() { 
    // the F space 
    var a = 'a'; 
    function N() { 
    // the N space 
    // here you could access g in the global space and a in the F space. 
    var c = 'c'; 
    console.log(g, a); 
    } 
} 
Problemi correlati