我在下面有一些代码。我希望它可以正确记录a
和b
,但结果是,它将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
中运行的答案 0 :(得分:1)
这是不依赖自动分号插入(ASI)的原因之一,除非您和每个可能在代码上工作的程序员非常明确ASI规则。
您的代码正在尝试将2
作为函数调用,将调用bar函数的结果作为参数传递,因为以下IIFE周围的()
可以合理地(通过ASI规则)被认为是let b =
陈述的一部分。由于调用bar
在b
被声明之前发生(它在初始化程序运行之后才会被声明),因此会出现错误。
如果我们稍微更改换行符,您可以看到发生了什么:
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());