为什么在IIFE之外未定义一个变量,而在另一个变量中则未定义呢?

时间:2019-03-09 15:30:23

标签: javascript scope iife

我在与IIFE玩耍时感到困惑。 a的值为undefined,但b不是。为什么我可以在IIFE之外访问b的值?

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

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

2 个答案:

答案 0 :(得分:10)

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

var a = b = 3;

解析为

var a = (something);

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

b = 3;
var a = b;

没有b = 3varlet的“裸” const创建一个隐式全局变量。因此,b在函数外部是可见的,而a在函数之外是可见的。

答案 1 :(得分:7)

有四种在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;
})();