2015-02-27 17 views
23

In JavaScript, var dichiarazioni creare proprietà sull'oggetto globale:Le istruzioni let creano proprietà sull'oggetto globale?

var x = 15; 
console.log(window.x); // logs 15 in browser 
console.log(global.x); // logs 15 in Node.js 

ES6 introduce scoping lessicale con let dichiarazioni che hanno portata blocco.

let x = 15; 
{ 
    let x = 14; 
} 
console.log(x); // logs 15; 

Tuttavia, queste dichiarazioni creano proprietà sull'oggetto globale?

let x = 15; 
// what is this supposed to log in the browser according to ES6? 
console.log(window.x); // 15 in Firefox 
console.log(global.x); // undefined in Node.js with flag 
+0

@ jfriend00 sì, e si comporta _differentemente_ in Firefox e in io.js che sono i due ambienti con cui posso testarlo. –

+0

In repl di node.js, se si esegue 'var x = 15', lo si circoscriverà all'ambito globale che è possibile verificare facilmente digitando' global.x' nella riga seguente. –

+1

Domanda: Esiste un 'LexicalEnvironment' e 'EnvironmentRecord' associato all'ambito globale? – Ben

risposta

19

fare let istruzioni creano proprietà dell'oggetto globale?

Secondo la spec, no:

Un record ambiente globale è logicamente un singolo record ma viene specificato come un composito incapsulare un object environment record e declarative environment record. Lo object environment record ha come oggetto base l'oggetto globale associato Realm. Questo oggetto globale è il valore restituito dal metodo concreto del record di ambiente globale GetThisBinding. Il componente annotazione ambiente oggetto di un record ambiente globale contiene le associazioni per tutti incorporati globali (clause 18) e tutte le associazioni introdotte da un FunctionDeclaration, GeneratorDeclaration, o VariableStatement contenuta nel codice globale. I binding per tutte le altre dichiarazioni ECMAScript nel codice globale sono contenuti nel componente declarative environment record del record di ambiente globale.

Alcuni ulteriori spiegazioni:

  • A dichiarativa ambiente di registrazione memorizza le associazioni in una struttura dati interna. È impossibile ottenere una sospensione di tale struttura dati in qualsiasi modo (si pensi all'ambito della funzione).

  • Un oggetto record di ambiente utilizza un oggetto JS effettivo come struttura di dati. Ogni proprietà dell'oggetto diventa vincolante e viceversa. L'ambiente globale ha un oggetto ambiente oggetto il cui "oggetto vincolante" è l'oggetto globale. Un altro esempio è with.

Ora, come gli Stati parte citati, solo FunctionDeclaration s, GeneratorDeclaration s, e VariableStatement s creare binding in oggetto registrare l'ambiente del ambiente globale. Cioè solo questi binding diventano proprietà dell'oggetto globale.

Tutte le altre dichiarazioni (ad esempio const e let) sono memorizzati in dichiarativa annotazione ambiente dell'ambiente globale, che non si basa sul oggetto globale.

+1

Ma 8.1.1.1 (https://people.mozilla.org/~jorendorff/es6-draft.html#sec-declarative-environment-records) indica che 'let' e' var' creano record di ambiente dello stesso tipo (cioè entrambi creano 'record dichiarativi dell'ambiente'), suggerendo che le posizioni 'let' e' var' sull'oggetto globale potrebbero corrispondere. Suppongo che il caso globale potrebbe essere speciale, comunque. – Ben

+1

'let' e' var' non creano record. 'let' e' var' bindings ** sono "memorizzati" in ** record di ambiente. E ci sono diversi tipi di record di ambiente: dichiarativo (a cosa ti sei collegato), oggetto, funzione, modulo e globale, dove i record dichiarativi e oggetto sono i due tipi principali (e tutti gli altri sono derivati). –

+0

Per favore, puoi chiarire lo scopo del tuo fare la distinzione. Se dichiaro una variabile nell'ambito globale, viene creato un record di ambiente (e la variabile è memorizzata al suo interno come dici tu). Quindi siamo entrambi "corretti" no? Stai dicendo che il tipo di record ambientale utilizzato dipende dal fatto che siamo nell'ambito di applicazione globale o no? – Ben

3

Per the specification:

"lasciare e le dichiarazioni const definiscono le variabili che hanno come ambito per LexicalEnvironment del contesto di esecuzione in esecuzione."

Ciò significa che è possibile accedere alla variabile all'interno dello scope di esecuzione, ma non all'esterno. Questo espande l'ambito dell'esecuzione oltre la classica struttura di chiusura JS di sola funzione o globale.

La definizione di una variabile let a livello globale lascia aperta all'interpretazione, come si vede in Firefox, che associa una variabile globale a V8/iojs.

Vale la pena ricordare che console.log(typeof x) verrà ripresentato nel number in iojs. In pratica non si dovrebbe definire le variabili al di fuori dei moduli, o funzioni quanto più possibile ... soprattutto con const e let

+1

* "La definizione di una variabile let lascia globalmente aperta all'interpretazione" * Come puoi vedere dalla mia risposta, non lo è. Quello che dici è vero, abbiamo davvero più cose che creano scope (anche i moduli), tuttavia, da solo non risponde alla domanda posta. –

Problemi correlati