JavaScript代码块之间保持什么状态?

时间:2017-05-31 13:02:40

标签: javascript node.js ecmascript-6 babeljs

我读(从“JavaScript,好的部分”)JavaScript没有块作用域,甚至建议在函数内部而不是在{ }内部声明变量以避免混淆

但是,我对我刚刚遇到并使用babel-node --presets es2015进行测试的一个示例(此处简化)感到困惑:

> {const a = 1;}; {const a = 2;};
undefined
> a;
1

此处,如果我们在前一个问题What state is kept between JavaScript lines?中讨论过的const{}中包含的两个node变量分配将会产生错误单独的翻译应该不是问题。)

但是,在代码块中使用时,不会生成错误。如上所示,第二项任务似乎根本没有效果。

> {const a = 1;}; {const a = 2;}; undefined > a; ReferenceError: a is not defined ... 中的行为也很有趣,

a

就好像两个代码块没有发生一样,babel-node没有定义。所以:

为什么在代码块中包含语句会导致上面的不同行为(即错误消失)?

代码块之间记住/忘记了什么?

node$ node --version v7.10.0 ~$ babel-node --version 6.24.1 中的哪种行为是正确的还是符合标准的?

仅供参考,版本为:

ui
 - app1
 - app2
 - components

2 个答案:

答案 0 :(得分:2)

“JavaScript,好的部分”是在const之前编写并发布的(2008),let是JavaScript中的东西(它们是在ES6中出现的)。这两个都允许您创建块范围的变量。同样var仍然完全相同(它不是块范围的,它的定义被提升到最近的(函数)范围的顶部)。

答案 1 :(得分:1)

constlet确实意味着是块范围的(请参阅MDN) - 但是,在您的第一个示例中,Babel将代码编译为可在其中工作的表单语法之前的黑暗日子里的浏览器存在 1

"use strict";

{
  var a = 1;
};{
  var _a = 2;
};

正如evolutionxbox在评论中指出的那样,var 不是块作用域,因此这会导致一些略微非标准的行为。请注意,第二个a会被重命名以避免名称冲突 - 这就是为什么a评估为区块外的1而不是2

Babel理论上可以将块包装在IIFE或其他东西中以正确模拟块范围,但我认为他们认为它不值得那么小的代码膨胀。

另一方面,

节点本地实现constlet,而不是将其转换为var语句,因此您可以在那里获得符合标准的行为。

1。您可以通过使用online REPL来轻松查看Babel生成的代码 - 如果我不确定为什么我的编译代码以某种方式运行,那么这往往是我的第一个停靠点。