javascript - ejemplo - innerhtml
¿Qué estado se mantiene entre las líneas de JavaScript? (2)
Me preguntaba qué estados se mantienen entre dos líneas de código JavaScript enviadas a babel-node
. Mi confusión surge porque si escribe dos líneas de código, puede anular una definición de variable sin un error. Por ejemplo, con babel-node --presets es2015
, puedes hacer:
> const a = 1;
undefined
> let a = 2;
undefined
Ahora si lo escribe en una línea, obtiene un error:
> const a = 1; let a = 2;
TypeError: repl: Duplicate declaration "a"
...
Parece que en el primer caso, el estado que a
se define como 1
(asignación de variable const
) se pierde (pero no hasta la segunda asignación), mientras que en el segundo caso, se mantiene.
¿Qué causa las diferencias aquí? y qué estados se mantienen?
Dado que const
y let
son sintaxis nuevas, se deben transponer al único mecanismo de enlace disponible antes de ES6: var
. En ese caso, var
permite todo tipo de reasignaciones al azar sin generar ningún tipo de advertencia.
Por lo tanto, cuando escribe una expresión en babel-node
, babel la transporta, la evalúa y luego muestra el resultado. Babel puede verificar el uso indebido de un enlace de const
en el momento de transpile, por lo que está viendo el error para const a = 1; let a = 2
const a = 1; let a = 2
. Pero const a = 1
y let a = 2
, cuando se transporta / evalúa como expresiones separadas, no exhibirá el error porque babel no puede detectar un problema en ninguna expresión sola.
Una demostración más visual del problema: por cada expr
expresión que escriba en el REPL babel-node
, esto es esencialmente lo que está sucediendo
evaluate(transpile(expr))
// => someResult
Entonces no verás un error aquí
evaluate(transpile(''const a = 1''))
evaluate(''var a = 1'')
// bind a to 1
// return undefined
evaluate(transpile(''let a = 2''))
evaluate(''var a = 2'')
// bind a to 2
// return undefined
Pero verás un error aquí
evaluate(transpile(''const a = 1; let a = 2''))
// ERROR during transpile: const a has already been declared
No uso babel-repl
, pero debe tener algo que ver con la conversión que está haciendo porque todo funciona como se espera con el REPL regular:
$ node -v
v7.4.0
$ node
> const a = 1;
undefined
> let a = 1;
SyntaxError: Identifier ''a'' has already been declared
> const b = 1; let b = 1;
const b = 1; let b = 1;
^
SyntaxError: Identifier ''b'' has already been declared
> .editor
// Entering editor mode (^D to finish, ^C to cancel)
const c = 1;
let c = 1;
let c = 1;
^
SyntaxError: Identifier ''c'' has already been declared