2015-04-02 11 views
8

Se si dichiara una variabile in una funzione utilizzando var, uno spazio per tale variabile viene aggiunto allo LexicalEnvironment definito da tale funzione.Come viene gestito l'ambito dei blocchi nell'ambiente lessicale?

function() { 
    var foo; 
} 

Nel codice sopra il LexicalEnvironment associato alla funzione contiene una scanalatura con una chiave foo e un valore di undefined.

Se si utilizza una dichiarazione con ambito a blocchi, come è interessato l'ambiente circostante LexicalEnvironment?

function() { 
    { 
    let foo; // How does this affect the LexicalEnvironment? 
    } 
} 

risposta

3
function() { 
    var foo; 
} 

Come lei ha ricordato, foo è disponibile nella LexicalEnvironment è globale a tutte le funzioni interne all'interno di quella funzione.

Ma

function() { 
    { 
    let foo; // How does this affect the LexicalEnviroinment? 
    } 
} 

Qui foo è locale al solo quel blocco. Non sarà visibile al di fuori di quel blocco.

In che modo ha effetto sullo LexicalEnvironment?

Se si fa riferimento, foo in qualsiasi punto all'interno di tale blocco, il locale let foo sostituirà il valore globale var foo definito in quella funzione.

Rispetto a ES6,

function example(x) { 
    console.log(y); // ReferenceError: y is not defined 
    if (x) { 
     let y = 5; 
    } 
} 

variabili dichiarate con un'istruzione let vengono creati come binding sull'ambiente lessicale, piuttosto che la variabile di ambiente, del contesto di esecuzione corrente. Una modifica alle specifiche delle istruzioni di blocco in ES6 significa che ogni blocco ha il proprio ambiente lessicale. Nell'esempio precedente, viene creato un nuovo ambiente lessicale quando viene valutato il blocco (il corpo dell'istruzione if). Quando viene valutata l'istruzione let viene aggiunto un legame a questo ambiente lessicale ed è innaccessibile dall'ambiente lessicale esterno (quello della dichiarazione della funzione stessa).

Refer

+0

Quindi, in ES6, i blocchi possono introdurre nuovi 'LexicalEnvironment's? O c'è un cambiamento in modo che un 'LexicalEnvironment' possa avere più di uno' [[Scope]] '? – Ben

+0

'LexicalEnvironment' avrà più di un' [[ambito]] 'basato sul contesto. – mohamedrias

+0

... che è un cambiamento da ES5? – Ben

1

Domande come questa sono meglio rispondere osservando il spec:

Block: {StatementList}

  1. Let oldEnv b e lo running execution context’sLexicalEnvironment.
  2. Let blockEnv be NewDeclarativeEnvironment (oldEnv).
  3. Eseguire BlockDeclarationInstantiation (StatementList, blockEnv).
  4. Impostare il running execution context’sLexicalEnvironment a blockEnv.
  5. Let blockValue essere il risultato della valutazione StatementList.
  6. Impostare il running execution context’sLexicalEnvironment a oldEnv.
  7. Ritorno blockValue.

NOTA: indipendentemente dal modo in cui il controllo lascia il blocco, il sistema LexicalEnvironment viene sempre riportato allo stato precedente.

Quindi cosa succede qui?

Quando il blocco viene valutato, viene creato un nuovo ambiente lessicale, con l'ambiente lessicale corrente come "padre". Il nuovo ambiente sostituisce l'ambiente corrente per la durata della valutazione del blocco.

Se si utilizza una dichiarazione con ambito a blocchi, come è interessato l'ambiente circostante LexicalEnvironment?

Oltre a essere temporaneamente sostituito, non viene toccato affatto.

Problemi correlati