JavaScript行之间保持什么状态?

时间:2017-05-31 03:37:44

标签: javascript node.js ecmascript-6 babeljs

我想知道在提交给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被定义为1const变量赋值)的状态丢失(但直到第二次赋值),而在第二种情况,它是维持的。

导致这些差异的原因是什么?以及维持哪些州?

2 个答案:

答案 0 :(得分:6)

由于constlet是新语法,因此必须将它们转换为ES6之前唯一可用的绑定机制:var。在这种情况下,var允许各种随意重新分配,而不会产生任何形式的警告。

因此,当您在babel-node中键入表达式时,babel会对其进行转换,对其进行求值,然后显示结果。 Babel可以在转换时检查是否滥用了const绑定,这就是您查看const a = 1; let a = 2错误的原因。但是const a = 1let 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