为什么这个 IIFE 的输出是 5?
(function() {
var a = b = 5;
})();
console.log(b);
我尝试了 console.log(a) 但它给出了预期的参考错误 为什么“b”在全球范围内还活着?
有趣的问题。尽管它与 IIFE 或提升根本无关。注意“a”没有被定义!
您的代码示例
function test() {
var a = b = 5;
}
在语义上等同于:
function test() {
var a = 5;
// this is essentially the same as `window.b = a`
b = a;
}
由于您没有声明“a”(又名
var a;
),它最终会进入全局范围。
在严格模式下,这是行不通的。
发生这种情况只是因为您将
b
声明为全局变量,而不是局部变量。
(function() {
var a = b = 5;
})();
它可能看起来就像是因为
var
而在本地定义的,但这仅适用于a
。
这是因为“泄漏”,这意味着无意中使本地声明的变量可用于全局范围。有关更多信息,请参阅此处。让我们拆分您的代码:
var a = b = 5;
这意味着:
a
采用b
的值,即5。在这种情况下,变量b
被隐式声明和初始化(使用b = 5
),并且由于您没有指定其块范围(这是因为 var
指的是 a
,而不是 b
)它仅限于全局范围。
该行为与非“严格模式”下的范围有关,
当函数尝试执行时,它会找到一个名为 a 的函数范围变量, 并且您无权从外部范围访问它,它将面临错误。
对于 b 变量,它找不到声明并向上一级询问有关变量 b 的全局范围,并且范围管理器找不到任何 var b,它会立即在全局范围内为您创建它,结果是您可以将其记录在全局范围内,这个东西调用(动态变量)。
来自文档。
用 var 声明的变量的作用域是其当前执行上下文及其闭包,即封闭函数和其中声明的函数