为什么IIFE中可访问let声明的变量,var声明的却出现undefined?
二者表现差异的核心原因
是var和let的作用域规则、变量提升行为不同,具体执行逻辑如下:
第二段使用var的代码逻辑(输出undefined)
var声明的变量是函数级作用域,且声明会被提升到所属函数的最顶部,赋值操作留在原位置。- 这段代码中IIFE内部的
var count = 1,其声明会被提升到整个immediate函数的最顶部,相当于IIFE内部预先创建了一个局部的count变量,初始值为undefined,直接覆盖了外层的全局count变量。 - 执行
if (count === 0)判断时,访问的是IIFE内部提升后的局部count,值为undefined,不满足等于0的条件,if代码块不会执行。 - 最终打印的就是IIFE内部未被赋值的局部
count,值为undefined。
你可以理解为这段var代码实际执行时等价于:
var count = 0; (function immediate() { // 变量提升,隐式声明局部count var count; if (count === 0) { // undefined === 0 为false,不进入 count = 1; console.log(count); } console.log(count); // 输出undefined })();
第一段使用let的代码逻辑(可正常访问外部count)
let声明的变量是块级作用域,仅在其所在的{}代码块内生效,不会将声明提升到上层的函数作用域,同时存在暂时性死区限制。- 这段代码中if块内部的
let count = 1仅作用于if块内部,不会影响if块外的IIFE作用域。 - 执行
if (count === 0)判断时,IIFE作用域内没有声明自己的count变量,会向上查找外层全局的count,值为0,满足条件进入if块。 - if块内部的局部
count赋值为1,打印输出1;离开if块后这个局部count失效,后续打印count会继续访问外层全局的count,值为0。
内容的提问来源于stack exchange,提问作者Shivangam Soni
相关产品推荐
相关产品推荐

