为什么一个变量在 IIFE 之外是未定义的,而另一个不是?

Why is one variable undefined outside of the IIFE while the other is not?

我在玩 IIFE,我很困惑。 a 的值是 undefinedb 不是。为什么我可以在 IIFE 之外访问 b 的值?

(function(){
  var a = b = 3;
})();

console.log("a defined? " + (typeof a !== 'undefined')); // false
console.log("b defined? " + (typeof b !== 'undefined')); // true

在JavaScript中有四种声明变量的方法:

  • var,它将将该变量的范围限定为声明函数。
  • let/const,这会将变量的范围限定在声明块中。
  • 隐式声明,它将全局作用域该变量(除非之前在不同的作用域中声明,在这种情况下它将重新分配)。
var a = b = 3;

在这条语句中,我们在函数范围内声明了a,值为b = 3。表达式 b = 3 的值为 3,但也隐式声明了变量 b,这意味着 b 将在全局范围内声明。

在函数之外,变量 b 被声明(因为它是全局隐式声明的)而 a 不是(因为它仅在函数范围内声明)。


虽然你应该避免隐式声明变量(并且最好使用 letconst 而不是 var),所以上面的代码应该这样写:

(function() {
  let a = 3;
  let b = a;
});

或者,如果您真的想要在函数外部声明的变量:

let a, b;
(function() {
  // NOTE: not implicit declaration since a and b are both already declared
  a = 3;
  b = a;
})();

声明语法可能会令人困惑,因为它看起来类似于普通表达式的语法。然而,它是不同的。

var a = b = 3;

被解析为

var a = (something);

在这种情况下,somethingb = 3,因此您的函数看起来就像

b = 3;
var a = b;

没有varletconst的"naked"b = 3创建一个隐式全局变量。因此 b 在函数外可见,而 a 不可见。