为何IIFE外部一个变量未定义,另一个却可被访问?
为什么IIFE里的变量b能在外部访问,而a不行?
这问题问到点子上了!核心原因在于你写的var a = b = 3这行代码的执行逻辑,以及变量声明的作用域规则,咱们一步步拆解来看:
首先,赋值操作是从右往左执行的,所以这行代码其实等价于:
b = 3; var a = b;
你会发现,这里的b没有用var(或者let/const)声明——在非严格模式下,未声明直接赋值的变量会自动成为全局变量,不管它是在哪个作用域里被赋值的。
而var a是在IIFE的函数作用域里声明的,所以a的作用域被严格限制在这个自执行函数内部,外部自然访问不到它。
咱们把你的代码展开成更清晰的版本,你就能一眼看明白:
(function(){ // b未声明直接赋值,自动成为全局变量 b = 3; // a是当前函数作用域的局部变量 var a = b; })(); console.log("a defined? " + (typeof a !== 'undefined')); // false,a是局部变量,外部不可见 console.log("b defined? " + (typeof b !== 'undefined')); // true,b是全局变量,外部能访问
如何避免这种意外?
- 如果想让
b也成为IIFE内部的局部变量,必须给它加上声明:// 方式1:一次性声明多个变量 (function(){ var a = 3, b = 3; })(); // 方式2:分开声明赋值 (function(){ var b = 3; var a = b; })(); - 更推荐使用ES6的
let/const,它们有严格的块级作用域,而且未声明直接赋值会报错(严格模式下),能帮你更早发现这类问题:(function(){ const a = b = 3; })(); // 直接报错,因为b未声明
内容的提问来源于stack exchange,提问作者spratap124
相关产品推荐
相关产品推荐

