I was wondering what states are kept between two lines of JavaScript code submitted to babel-node
. My confusion arises because if you write two lines of code, you can override an variable definition without an error. For example, with babel-node --presets es2015
, you can do:
> const a = 1;
undefined
> let a = 2;
undefined
Now if you write it in one line, you get an error:
> const a = 1; let a = 2;
TypeError: repl: Duplicate declaration "a"
...
It seems that in the first case, the state that a
is defined as 1
(const
variable assignment) is lost (yet not until the second assignment), while in the second case, it is maintained.
What causes the differences here? and which states are maintained?
A block statement is used to group zero or more statements. The block is delimited by a pair of braces ("curly brackets") and contains a list of zero or more statements and declarations.
Node. js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node. js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.
Because const
and let
are new syntaxes, they must be transpiled to the only binding mechanism that was available before ES6: var
. In which case, var
allows all sorts of haphazard reassignment without generating any kind of warning.
So when you type an expression in babel-node
, babel transpiles it, evaluates it, then displays the result. Babel can check for misuse of a const
binding at transpile time, which is why you're seeing the error for const a = 1; let a = 2
. But const a = 1
and let a = 2
, when transpiled/evaluated as separate expressions, will not exhibit the error because babel is not able to detect a problem in either expression alone.
A more visual demonstration of the issue: For every expression expr
you type in the babel-node
REPL, this is essentially what's happening
evaluate(transpile(expr))
// => someResult
So you won't see an error here
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
But you will see an error here
evaluate(transpile('const a = 1; let a = 2'))
// ERROR during transpile: const a has already been declared
I do not use babel-repl
, but it must be something to do with the conversion it is doing because everything works as expected with the regular REPL:
$ 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With