繁体   English   中英

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

[英]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-nodenode之间的哪个行为正确或符合标准?

仅供参考,版本为:

$ node --version
v7.10.0
~$ babel-node --version
6.24.1

“ JavaScript,优秀的部分”在constlet之前就被编写和发布(2008年),这是JavaScript中的一件事(它们到达了ES6)。 这两种方法都可以使您创建块作用域变量。 同样, var仍然可以完全相同地工作(它不是块作用域的,其定义被提升到最近的(函数)作用域的顶部)。

constlet确实意味着是块作用域的(请参阅MDN )-但是,在您的第一个示例中,Babel将代码编译为一种形式,该形式可以从存在该语法的黑暗时期开始在浏览器中运行1

"use strict";

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

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

Babel理论上可以将这些块包装在IIFE中,或者可以适当地模拟块作用域,但是我认为他们认为,对于这么小的事情,不值得让代码膨胀这么高的水平。

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


1.您可以使用Babel的在线REPL轻松查看Babel生成的代码-如果不确定我的编译后代码为什么以某种方式运行,这通常是我的第一站电话。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM