[英]What state is kept between JavaScript code blocks?
我从“ JavaScript,优秀的部分”中了解到JavaScript没有块作用域,甚至建议在函数的最开始处声明变量,而不是在{ }
内部声明变量,以免造成混淆。
但是,我对我刚刚使用babel-node --presets es2015
进行测试的示例感到困惑(在此处简化):
> {const a = 1;}; {const a = 2;};
undefined
> a;
1
在这里,如果没有如我在上一个问题中所讨论的那样,如果一行中的两个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
“ JavaScript,优秀的部分”在const
和let
之前就被编写和发布(2008年),这是JavaScript中的一件事(它们到达了ES6)。 这两种方法都可以使您创建块作用域变量。 同样, var
仍然可以完全相同地工作(它不是块作用域的,其定义被提升到最近的(函数)作用域的顶部)。
const
和let
确实意味着是块作用域的(请参阅MDN )-但是,在您的第一个示例中,Babel将代码编译为一种形式,该形式可以从存在该语法的黑暗时期开始在浏览器中运行1 :
"use strict";
{
var a = 1;
};{
var _a = 2;
};
正如evolutionxbox在注释中指出的那样, var
不是块作用域的,因此这会导致一些稍微不标准的行为。 请注意,第二个a
被重命名以避免名称冲突-这就是为什么a
在块外求值为1
而不是2
。
Babel理论上可以将这些块包装在IIFE中,或者可以适当地模拟块作用域,但是我认为他们认为,对于这么小的事情,不值得让代码膨胀这么高的水平。
另一方面,Node实现const
并let
本地执行,而不是将其转换为var
语句,因此您可以在那里获得符合标准的行为。
1.您可以使用Babel的在线REPL轻松查看Babel生成的代码-如果不确定我的编译后代码为什么以某种方式运行,这通常是我的第一站电话。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.