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

spr*_*124 4 javascript scope iife

我在与IIFE玩耍时感到困惑。的价值a就是undefined,但b并非如此。为什么我能够获得bIIFE之外的价值?

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

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

Poi*_*nty 10

声明语法可能会造成混淆,因为它看起来像普通表达式的语法。但是,这是不同的。

var a = b = 3;
Run Code Online (Sandbox Code Playgroud)

被解析为

var a = (something);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,somethingis b = 3,所以就好像您的函数看起来像

b = 3;
var a = b;
Run Code Online (Sandbox Code Playgroud)

“裸” b = 3varletconst创建一个隐含的全局变量。因此b在函数外部可见,而在函数外部a则不可见。


Frx*_*rem 7

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

  • var,它将把该变量作用于声明函数。
  • let/ const,它将把该变量作用于声明块。
  • 隐式声明,它将在全局范围内定义该变量(除非以前在不同的范围中声明过,否则将重新分配该变量)。
var a = b = 3;
Run Code Online (Sandbox Code Playgroud)

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

在函数之外,b声明变量(因为已在全局范围内隐式声明),a而未声明(因为仅在函数范围内声明)。


不过,您应该避免隐式声明的变量(最好使用letconst代替var),因此上面的代码应该这样写:

(function() {
  let a = 3;
  let b = a;
});
Run Code Online (Sandbox Code Playgroud)

或者,如果您实际上还希望在函数外部声明变量:

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