Javascript Babel重新声明函数参数if';让';使用相同的名称两次(在for循环中)
当我做这种(愚蠢的)事情时:Javascript Babel重新声明函数参数if';让';使用相同的名称两次(在for循环中),javascript,ecmascript-6,babeljs,variable-declaration,Javascript,Ecmascript 6,Babeljs,Variable Declaration,当我做这种(愚蠢的)事情时: function doBar(bar) { for (let bar = 0; bar < 10; bar++) { let bar = true; } } for (var _bar = 0; _bar < 10; _bar++) { var _bar = true; } function doBar(bar) { for (let bar = 0; bar < 10; bar++) { let bar = t
function doBar(bar) {
for (let bar = 0; bar < 10; bar++) {
let bar = true;
}
}
for (var _bar = 0; _bar < 10; _bar++) {
var _bar = true;
}
function doBar(bar) {
for (let bar = 0; bar < 10; bar++) {
let bar = true;
}
}
doBar("BAR");
或
for(var\u-bar=0;\u-bar<10;\u-bar++){
var _bar2=真;
}
编辑:向添加了一些控制台输出,以显示函数variabel是如何重新声明的。
let
和var
不一样
让
在块范围内定义变量,例如for循环。
var
在全局或函数范围内定义变量
因此,当您获得代码时:
function doBar(bar) {
for (let bar = 0; bar < 10; bar++) {
let bar = true;
}
}
首先,这在语义上是错误的。这包含一个重新声明。这两个bar
变量都在for块的范围内声明。但是,您不会抛出错误,没有babel也是如此。由于变量栏的重新声明发生在for的作用域块内,因此for的“参数”栏被覆盖,并且块本身无法访问,但是循环似乎仍然正常运行,次数正确
由于这个“无声错误”和块内重新声明的变量let bar
,巴贝尔认为这两个变量不一样,它们是不同的。出现错误的原因在于,通过在块内重新声明变量,可以有效地使块内或块外的任何对象都可以访问块本身的变量
现在从babel的角度来看,循环应该运行,循环的参数在for的括号内或括号外的任何地方都是不可访问的,因此这是for中条
的一个单独的“范围”
与let
不同,var
可以在不引发错误的情况下重新声明,但是这种无声的重新声明不会在两种情况下都引发错误,在这两种情况下都应该引发错误,而这正是问题的原因
解决方案是编写正确的代码,但你是100%正确的,这不是正确的行为,然而,非bable代码的常规javascript解释器也不是这样,因为它会抛出错误,并且你不能期望/责怪babel以错误的方式解释错误的代码。babel在这里只是部分正确 当我做这种(愚蠢的)事情时:
function doBar(bar) {
for (let bar = 0; bar < 10; bar++) {
let bar = true;
}
}
for (var _bar = 0; _bar < 10; _bar++) {
var _bar = true;
}
function doBar(bar) {
for (let bar = 0; bar < 10; bar++) {
let bar = true;
}
}
doBar("BAR");
功能多臂杆(杆){
用于(设bar=0;bar<10;bar++){
让bar=true;
}
}
多巴(“酒吧”);
…那么您可能没有想到在这里的三个不同范围内有三个名为bar
的不同变量
但这是真的:
var
-like)bar
条
,由foo
标题中的let
声明引入,其let
声明引入的块范围bar
let
重新定义函数作用域变量(参数,var
声明)或与自身作用域相同的let
都会抛出早期错误
巴贝尔产生了这个[…]。这样行吗
不。正如您在
doFoo
中所看到的,巴贝尔实际上认识到变量1和2是不同的。它也承认2和3是不同的。但一旦你介绍了这三个,它就会混淆1和2,将它们传输到同一个标识符。“当bable将其转换时,你会得到预期的行为”不,你没有。参数bar
必须保持不变。确实如此。但是您正在访问变量栏,而不是参数。我知道var
和let
的不同范围。事实上,这就是我问的原因。:)我认为(){}的中的所有内容都在那里。请查看babeljs.io示例(对不起,问题中有链接,请点击此处查看注释)。请参见右侧第18行。当我在这里访问变量bar
时,我希望得到函数的参数,就像第9行中的doFoo
示例一样。不同版本和不同范围的“规则”是什么?在for
循环之后插入console.log(bar)
。在完全符合ES2015标准的环境中,它打印参数值。传输的代码打印10
。不能在函数的作用域中使用let
声明名为bar
的变量。可以使用var
。那么,您是对的,参数被变量隐藏。尽管如此,传输的代码还是不正确的。毫无疑问,这是一个错误的代码,但其原因在于let到var的转换,而不管for()循环中发生了什么。如果这不是OP问题的重点,那么我就没有抓住重点。进一步解释: