【问题标题】:Why is one variable undefined outside of the IIFE while the other is not?为什么一个变量在 IIFE 之外未定义而另一个未定义?
【发布时间】:2019-03-09 15:30:22
【问题描述】:
我在玩 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
【问题讨论】:
标签:
javascript
scope
iife
【解决方案1】:
声明语法可能会令人困惑,因为它看起来类似于普通表达式的语法。然而,它是不同的。
var a = b = 3;
被解析为
var a = (something);
在这种情况下,something 是 b = 3,所以它就像你的函数看起来一样
b = 3;
var a = b;
没有var 或let 或const 的“裸”b = 3 创建一个隐式全局变量。因此b 在函数外部可见,而a 不可见。
【解决方案2】:
在 JavaScript 中有四种声明变量的方法:
-
var,它将将该变量的范围限定为声明函数。
-
let/const,它将将该变量的范围限定为声明块。
- 隐式声明,它将全局范围内该变量(除非先前在不同的范围内声明,在这种情况下它将重新分配该变量)。
var a = b = 3;
在这个语句中,我们在函数作用域中声明了a,其值为b = 3。表达式b = 3 的值为3,但同时隐式声明了变量b,这意味着b 将在全局范围内声明。
在函数之外,变量b 被声明(因为它是在全局范围内隐式声明的),而a 不是(因为它只在函数范围内声明)。
你应该避免隐式声明变量,但是(最好使用let和const而不是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;
})();