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
  • 它们都有单独的值(1:string、2:integer、3:boolean),并且彼此不影响。这一点很明显,因为不会抛出语法错误,否则任何
    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问题的重点,那么我就没有抓住重点。进一步解释: