我想知道在提交给babel-node
的两行JavaScript代码之间保留了哪些状态。我的困惑是因为如果你编写两行代码,你可以覆盖变量定义而不会出错。例如,使用babel-node --presets es2015
,您可以执行以下操作:
> const a = 1;
undefined
> let a = 2;
undefined
现在如果你用一行写它,就会出错:
> const a = 1; let a = 2;
TypeError: repl: Duplicate declaration "a"
...
似乎在第一种情况下,a
被定义为1
(const
变量赋值)的状态丢失(但直到第二次赋值),而在第二种情况,它是维持的。
导致这些差异的原因是什么?以及维持哪些州?
答案 0 :(得分:6)
由于const
和let
是新语法,因此必须将它们转换为ES6之前唯一可用的绑定机制:var
。在这种情况下,var
允许各种随意重新分配,而不会产生任何形式的警告。
因此,当您在babel-node
中键入表达式时,babel会对其进行转换,对其进行求值,然后显示结果。 Babel可以在转换时检查是否滥用了const
绑定,这就是您查看const a = 1; let a = 2
错误的原因。但是const a = 1
和let a = 2
在被转换/评估为单独的表达式时,不会出现错误,因为babel无法单独检测任何一个表达式中的问题。
该问题的更直观的演示:对于您在expr
REPL中输入的每个表达式babel-node
,这基本上是发生的事情
evaluate(transpile(expr))
// => someResult
所以你不会在这里看到错误
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
但你会在这里看到错误
evaluate(transpile('const a = 1; let a = 2'))
// ERROR during transpile: const a has already been declared
答案 1 :(得分:2)
我不使用babel-repl
,但它必须与它正在进行的转换有关,因为一切都按照预期的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