2015-10-31 12 views
8

Oggi mi imbatto in un bizzarro bug JS, che funziona con const all'interno di un blocco try/catch, e vorrei capire meglio che cosa sta causando. sguardoJavaScript: definire una costante all'interno di try/catch con la modalità strict

Let ad un esempio di codice, che vale più di mille parole:

try { 
    const FOO = 'bar'; 
    console.log('inside:', FOO); 
} catch (e) {} 
console.log('outside:', FOO); 

Questo registrerà:

inside: bar 
outside: bar 

Se si passa a "modalità rigorosa", anche se:

Ora lo stesso codice genera un errore:

ReferenceError: FOO is not defined 

Se cambiamo const con var però:

'use strict'; 
try { 
    var foo = 'bar'; 
    console.log('inside:', foo); 
} catch (e) {} 
console.log('outside:', foo); 

Poi tutto funziona di nuovo bene, anche in "rigorosa modalità":

inside: bar 
outside: bar 

Qualcuno può aiutarmi a capire il motivo per cui il const l'assegnazione non funziona all'interno di un blocco try/catch in "strict mode"?

Grazie!

+0

Confronta 'const' con' let', non 'var' –

risposta

15

const, come definito da ECMAScript 6, è un block-level variable declaration. Ottiene un ReferenceError perché non è compreso nell'ambito di try.

Tuttavia, const è stato introdotto in some engines molto prima di ES6, come equivalente immutabile a var, con comportamento a livello di funzione (e senza TDZ). Se sei in modalità sciatta (che non dovresti essere), potresti comunque sperimentare questo aspetto come parte del supporto legacy del tuo browser.

+0

Non avevo idea di legacy" 'const'". Nota in calce MDN: "Nelle precedenti versioni di Firefox e Chrome e in Safari 5.1.7 e Opera 12.00, se si definisce una variabile con const, è comunque possibile modificarne il valore in seguito." – joews

+0

@joews: sì, non era niente di meglio di un alias per 'var', quindi gli script scritti per FF (nella convinzione di una caratteristica standard) funzionerebbero almeno senza errori di sintassi in Safari e Opera, anche se non garantiscono unassignability. – Bergi

+1

"continuerà a funzionare in questo modo" - V8 in Chrome 48 (attuale Canary) applica l'ambito del blocco in entrambe le modalità (testato in console/snippet; non riesco a trovare un riferimento). Immagino che questo potrebbe cambiare prima del rilascio. – joews

4

Il runtime JavaScript ha un'implementazione parziale di ES6 const.

ReferenceError è il comportamento previsto per il primo esempio, perché const is block scoped e si accede FOO al di fuori della definizione try blocco.

Il motore in uso supporta la sintassi const, ma applica solo la semantica degli ambiti di blocco in modalità rigorosa.

L'attuale Chrome stabile (46) fa questo. Tuttavia, Chrome 48 applica l'ambito del blocco con o senza la modalità rigorosa.

var non è a blocchi, quindi l'ultimo esempio funziona come previsto.

Problemi correlati