JavaScript代码块之间保持什么状态?
我从“JavaScript,好的部分”中读到JavaScript没有块作用域,甚至建议在函数一开始就在函数内部声明变量,而不是在JavaScript代码块之间保持什么状态?,javascript,node.js,ecmascript-6,babeljs,Javascript,Node.js,Ecmascript 6,Babeljs,我从“JavaScript,好的部分”中读到JavaScript没有块作用域,甚至建议在函数一开始就在函数内部声明变量,而不是在{}内部声明变量,以避免混淆 然而,我对刚才遇到的一个示例(此处简化)感到困惑,该示例使用babel node--presets es2015进行了测试: > {const a = 1;}; {const a = 2;}; undefined > a; 1 这里,在一行中进行的两个const变量赋值如果没有像我在上一个问题中讨论的那样被包含在块{}中,就会
{}
内部声明变量,以避免混淆
然而,我对刚才遇到的一个示例(此处简化)感到困惑,该示例使用babel node--presets es2015进行了测试:
> {const a = 1;}; {const a = 2;};
undefined
> a;
1
这里,在一行中进行的两个const
变量赋值如果没有像我在上一个问题中讨论的那样被包含在块{}
中,就会产生一个错误(因此单独的转换不应该是问题)
但是,在代码块中使用时,不会生成错误。如上所示,第二个任务似乎没有任何效果
节点中的行为也很有趣
> {const a = 1;}; {const a = 2;};
undefined
> a;
ReferenceError: a is not defined
...
就好像这两个代码块没有发生一样,a
没有定义。因此:
为什么在代码块中封装语句会导致上述不同行为(即错误消失)
代码块之间记住/忘记了什么
babel节点
和node
之间的哪种行为是正确的或符合标准的
供参考,版本为:
$ node --version
v7.10.0
~$ babel-node --version
6.24.1
《JavaScript,好的部分》是在const
和let
成为JavaScript的一部分之前(2008年)编写和出版的(它们出现在ES6)。这两种方法都允许创建块作用域变量。而且var
的工作原理仍然完全相同(它不是块作用域,它的定义被提升到最近的(函数)作用域的顶部)。在const
和let
成为JavaScript的一部分之前(2008年)就已经编写和发布了《JavaScript,好的部分》(它们在ES6中出现)。这两种方法都允许创建块作用域变量。另外,var
的工作原理仍然完全相同(它不是块作用域,它的定义被提升到最近的(函数)作用域的顶部)。const
和let
确实是块作用域(请参见)-但是,在第一个示例中,Babel将代码编译成一种形式,这种形式在语法出现之前的黑暗时代就可以在浏览器中使用1:
正如evolutionxbox在评论中指出的,var
不是块范围的,因此这会导致一些稍微不标准的行为。请注意,第二个a
被重命名以避免名称冲突-这就是a
在块外计算为1
而不是2
的原因
理论上,Babel可以用IILife或其他方法来包装这些块,以正确地模拟块的作用域,但我认为他们认为,对于如此微不足道的事情,不值得如此大量的代码
另一方面,节点以本机方式实现const
和let
,而不是将其转换为var
语句,因此您可以在那里获得符合标准的行为
一,。您可以使用它们轻松查看Babel生成的代码-如果我不确定编译后的代码为何以某种方式运行,那么这往往是我的第一个调用端口。const
和let
确实是块范围的(请参见)-但是,在您的第一个示例中,Babel将代码编译成一种形式,这种形式在语法出现之前的黑暗时代就可以在浏览器中使用1:
正如evolutionxbox在评论中指出的,var
不是块范围的,因此这会导致一些稍微不标准的行为。请注意,第二个a
被重命名以避免名称冲突-这就是a
在块外计算为1
而不是2
的原因
理论上,Babel可以用IILife或其他方法来包装这些块,以正确地模拟块的作用域,但我认为他们认为,对于如此微不足道的事情,不值得如此大量的代码
另一方面,节点以本机方式实现const
和let
,而不是将其转换为var
语句,因此您可以在那里获得符合标准的行为
一,。如果我不确定编译后的代码为何以某种方式运行,您可以使用它们的调用端口轻松查看Babel生成的代码。JavaScript变量(var
)没有块作用域。对于块作用域,您必须使用const
或let
。可能babel节点--预设es2015
不会将块作用域应用于const
?节点中显示的行为似乎与您预期的一致<代码>a
应该是未定义的
。在第一个示例中a
应该是未定义的
。如果不是,这是巴贝尔的错误。这是巴贝尔范围界定的错误。查看用babel翻译的js-它在块范围中使用var。这就是得到结果的原因我很好奇:你是如何知道const
而不知道它是块作用域的?JavaScript变量(var
)不是块作用域的。对于块作用域,您必须使用const
或let
。可能babel节点--预设es2015
不会将块作用域应用于const
?节点中显示的行为似乎与您预期的一致<代码>a
应该是未定义的
。在第一个示例中a
应该是未定义的
。如果不是,这是巴贝尔的错误。这是巴贝尔范围界定的错误。查看用babel翻译的js-它在块范围中使用var。这就是你得到结果的原因我很好奇:你是如何知道const
而不知道它是块作用域的?你能说说为什么第一个例子允许a
在块之外被记录吗?你能说说为什么第一个例子允许a
在块之外被记录吗阻塞?因此这会导致一些轻微的非标准行为。
感谢您的澄清和提示
"use strict";
{
var a = 1;
};{
var _a = 2;
};