Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What state is kept between JavaScript lines?

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?

like image 714
thor Avatar asked May 31 '17 03:05

thor


People also ask

What is code block in JavaScript?

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.

Which JavaScript engine is node js based on?

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.


2 Answers

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
like image 64
Mulan Avatar answered Oct 23 '22 23:10

Mulan


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
like image 27
Tyler Avatar answered Oct 24 '22 01:10

Tyler