使用let定义的变量未在同一范围IIFE中定义

时间:2018-05-28 16:22:49

标签: scope var let iife

我在下面有一些代码。我希望它可以正确记录ab,但结果是,它将a记录为1,b未定义错误:

  

未捕获的ReferenceError:b未定义



function foo(){
    var a = 1
    let b = 2
    (function bar() {
        console.log(a)
        console.log(b)
    }())
}
console.log(foo());




如果我更改代码以使bar作为函数声明,那么每件事情都很好



function foo(){
    var a = 1
    let b = 2
    function bar() {
        console.log(a)
        console.log(b)
    }
    bar()
}
console.log(foo());




我对功能范围,块范围,提升有所了解。但我真的不明白会发生什么事情导致b未被定义'

上面的所有代码都是在Chrome 66的devTools

中运行的

1 个答案:

答案 0 :(得分:1)

这是不依赖自动分号插入(ASI)的原因之一,除非您和每个可能在代码上工作的程序员非常明确ASI规则。

您的代码正在尝试将2作为函数调用,将调用bar函数的结果作为参数传递,因为以下IIFE周围的()可以合理地(通过ASI规则)被认为是let b =陈述的一部分。由于调用barb被声明之前发生(它在初始化程序运行之后才会被声明),因此会出现错误。

如果我们稍微更改换行符,您可以看到发生了什么:

function foo(){
    var a = 1
    let b = 2(function bar() {
        console.log(a)
        console.log(b)
    }());
}
console.log(foo());

添加;修复了它:

function foo(){
    var a = 1;
    let b = 2;
    (function bar() {
        console.log(a);
        console.log(b);
    }());
}
console.log(foo());