2015-05-15 14 views
6

Capisco che ogni funzione in JavaScript è un oggetto di prima classe e ha una proprietà interna [[scope]] che ospita i record di binding delle variabili libere della funzione. Tuttavia, ci sono due casi speciali.È vero che ogni funzione in JavaScript è una chiusura?

  1. La funzione creata dal costruttore Funzione ha anche una chiusura? L'oggetto funzione creato dal costruttore di funzioni è speciale, poiché il suo [[scope]] potrebbe non riferirsi agli ambienti lessicali delle sue funzioni esterne, ma solo al contesto globale. Ad esempio,

    var a = 1; 
    var fn = (function outer() { 
        var a = 2; 
        var inner = new Function('alert(a); '); 
        return inner; 
    })(); 
    fn(); // will alert 1, not 2. 
    

    Questo non è intuitivo. Si chiama anche chiusura?

  2. Se una funzione interna non ha variabili libere, possiamo dire che una chiusura si forma quando viene creata la funzione interna? Ad esempio,

    // This is a useless case only for academic study 
    var fn = (function outer() { 
        var localVar1 = 1, 
         localVar2 = 2; 
        return function() {}; 
    })(); 
    

    In questo caso, fn si riferisce a un oggetto funzione vuoto creato come funzione interna. Non ha variabili libere. In questo caso possiamo dire che si è formata una chiusura?

+3

Allora, qual è la tua definizione di "chiusura"? – Bergi

+2

Ulteriori commenti su questo comportamento sono disponibili qui: http://www.bennadel.com/blog/1909-javascript-function-constructor-does-not-create-a-closure.htm Il comportamento sembra correlato al comportamento di 'eval' (chiamata indiretta vs. diretta). Vedi anche: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function --- * "Le funzioni create con il costruttore Function non creano chiusure ai loro contesti di creazione; sempre vengono creati nell'ambito globale."* –

+1

La domanda n. 2 è più di una domanda filosofica" se un albero cade in una foresta " – JJJ

risposta

7

È la funzione creato da costruzione funzione anche una chiusura?

Sì, si chiude sull'ambito globale. Ciò potrebbe non essere intuitivo perché tutte le altre chiusure di JavaScript si chiudono nel loro ambito lessicale, ma corrispondono ancora al nostro definition of a closure. Nell'esempio, a è una variabile libera e risolve lo a in un altro ambito quando la funzione inner/fn viene richiamata da qualche parte.

Se una funzione interna non ha variabili libere, possiamo ancora chiamarla chiusura?

Dipende da chi chiedi. Some dire Sì, others chiamali "chiusure poco interessanti", personalmente dico No perché they don't reference un ambito esterno.

+0

Grazie @Bergi, spiegazione meravigliosa. Nel secondo caso, il la funzione outer() sarà raccolta dopo aver eseguito il codice, poiché non è più referenziato, ma cosa c'è nella proprietà interna di [[scope]] di fn? O semplicemente, la funzione oggetto fn si riferisce a ricordare che è stata creata in ambito esterno()? –

+0

Bene, se si segue la specifica ES5 il [[scope]] di 'inner' memorizza l'ambiente lessicale di' outer', con le sue variabili 'outer' e' a' - quindi tutto è ancora accessibile e ricorda: se segui un'implementazione ES effettiva e controlli 'inner' con il tuo debugger, non vedi alcun riferimento allo scope - non ne ha bisogno, in quanto non ci sono variabili libere. – Bergi

4

Nota: le funzioni create con il costruttore Funzione non creano chiusure ai relativi contesti di creazione; vengono sempre creati nell'ambito globale . Durante l'esecuzione, saranno in grado di accedere solo alle variabili locali e a quelle globali e non all'ambito in cui è stato chiamato il costruttore Funzione. Questo è diverso da utilizzando eval con codice per un'espressione di funzione.

da https://developer.mozilla.org

Problemi correlati