È vero che ogni funzione in JavaScript è una chiusura?

Comprendo che ogni funzione in JavaScript è un object di prima class e ha una proprietà interna [[scope]] che ospita i record di binding delle variabili libere della funzione. Tuttavia, ci sono due casi speciali.

  1. La funzione creata dalla funzione Costruttore è anche una chiusura? L’object 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. Per 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 interiore non ha variabili libere, possiamo dire che una chiusura si forma quando viene creata la funzione interiore? Per 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 object funzione vuoto creato come funzione interna. Non ha variabili libere. In questo caso possiamo dire che si è formata una chiusura?

La funzione creata dalla funzione Costruttore è 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 alla nostra definizione di chiusura . Nel tuo esempio, a è una variabile libera e si risolve in a in un altro ambito quando la funzione inner / fn è chiamata da qualche parte.

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

Dipende a chi lo chiedi. Alcuni dicono Sì, altri li chiamano “chiusure poco interessanti”, personalmente dico No perché non fanno riferimento a un ambito esterno.

Nota: le funzioni create con il costruttore di funzioni non creano chiusure ai loro contesti di creazione; sono sempre creati nell’ambito globale. Quando li eseguono, saranno in grado di accedere alle proprie variabili locali e globali, non a quelle nell’ambito in cui è stato chiamato il costruttore Function. Questo è diverso dall’usare eval con il codice per un’espressione di funzione.

da https://developer.mozilla.org