当前位置: 首页 > backend >正文

JavaScript 立即执行函数(IIFE)运行时行为分析笔记

一、代码示例

(function() {// IIFE 函数作用域console.log(typeof foo); // 第一次打印console.log(typeof bar); // 第二次打印function foo() {} // 函数声明var bar = 10;    // 变量声明console.log(typeof foo); // 第三次打印console.log(typeof bar); // 第四次打印
})();

二、作用域结构分析

IIFE 形成了嵌套的作用域结构,决定了变量的可见性:

  • 全局作用域:包含 IIFE 函数本身(IIFE 作为全局作用域的一个函数)。
  • IIFE 函数作用域:嵌套在全局作用域内,包含 foo(函数)和 bar(变量)的声明,是本次分析的核心作用域。

三、变量提升(Hoisting)机制

JavaScript 引擎在编译阶段会将声明(函数声明、变量声明)提升到当前作用域顶部,赋值操作保留在原地,代码实际执行顺序如下:

(function() {// 编译阶段提升的内容:function foo() {}  // 函数声明整体提升(含函数体)var bar;          // 变量声明提升(初始值为 undefined)// 执行阶段:按顺序执行console.log(typeof foo); // 第一次打印console.log(typeof bar); // 第二次打印bar = 10;         // 变量赋值(保留在原位置)console.log(typeof foo); // 第三次打印console.log(typeof bar); // 第四次打印
})();
  • 函数声明提升:函数声明(function foo() {})会被完整提升到作用域顶部,在声明前即可访问。
  • var 声明提升var 声明的变量(var bar = 10)仅提升声明部分,赋值操作留在原地,声明前访问时默认值为 undefined

四、执行上下文生命周期

执行上下文是函数运行时的环境,其生命周期分为创建阶段(编译时)和执行阶段(运行时)。

1. 创建阶段(编译时)

此阶段为执行做准备,确定变量存储、作用域链和 this 指向:

  • 变量对象(Variable Object,VO):存储当前作用域内的声明(函数/变量)
VO = {foo: function() {},  // 函数声明整体提升bar: undefined       // var 变量声明提升,初始值为 undefined
}
  • 作用域链:由内到外依次关联嵌套的作用域,此处为 [IIFE 函数作用域, 全局作用域]
  • this 指向:非严格模式下指向全局对象(浏览器中为 window

2. 执行阶段(运行时)

按代码顺序执行,修改变量对象中的值:

  • 执行赋值操作(bar = 10),变量对象更新为:
VO = {foo: function() {},  // 函数声明保持不变bar: 10              // 变量赋值后的值
}
  • 按顺序执行代码,完成打印等操作。

五、四次打印结果详解

打印位置变量输出结果原因解释
第一次typeof foo"function"函数声明被提升到作用域顶部,声明前可直接访问(函数类型)
第二次typeof bar"undefined"bar 仅提升声明,未执行赋值,默认值为 undefined(undefined 类型)
第三次typeof foo"function"函数声明未被修改,仍为函数类型
第四次typeof bar"number"bar 已执行赋值(bar = 10),类型为数字(number 类型)

六、编译阶段与运行阶段的核心差异

JavaScript 引擎对代码的处理分为两个明确阶段,是理解变量提升、作用域等机制的关键:

阶段时间点核心工作影响范围
编译阶段代码执行前1. 解析代码结构,确定作用域嵌套关系; 2. 处理声明提升(函数声明整体提升,var 声明仅提升名称)作用域结构、变量归属
运行阶段代码执行时1. 创建执行上下文(变量对象、作用域链、this 指向); 2. 逐行执行代码,修改变量值变量实际值、this 指向、运行状态

七、关键知识点补充

  1. 函数声明与变量声明的优先级
    同作用域内若存在同名函数声明和变量声明,函数声明会覆盖变量声明(但变量赋值会覆盖函数声明)。
    示例:
(function() {var foo = 'bar'; console.log(foo); // 输出 "bar"(变量赋值覆盖函数声明)function foo() {} 
})();
  1. var 与 let/const 的差异
    let/const 声明的变量存在“暂时性死区(TDZ)”,声明前访问会报错(ReferenceError),而 var 声明无此限制。
    示例:
(function() {console.log(bar); // 报错:ReferenceError(处于 TDZ)let bar = 10;
})();
  1. 作用域与执行上下文的关系
    作用域是静态结构(定义时确定),决定变量可见范围;执行上下文是动态状态(运行时创建),存储变量实际值,二者通过作用域链关联。

通过以上分析,可清晰理解 IIFE 运行时的变量提升、作用域交互及执行上下文变化,进而掌握 JavaScript 核心运行机制。

http://www.xdnf.cn/news/16300.html

相关文章:

  • 建筑施工场景下漏检率↓76%!陌讯多模态融合算法在工程安全监控的落地实践
  • 上证50指数分红和股指期货有什么关系?
  • Sklearn 机器学习 数值指标 entropy熵函数
  • Qt 与 WebService 交互开发
  • 配置nodejs
  • 【CTF-WEB-SQL】SQL注入基本流程-错误注入(sql-labs的Less5)(updatexml)
  • DOM元素添加技巧全解析
  • 如果在分支A上修改了内容,想要提交更新内容的话,如何与develop上的主分支的最新的代码拉齐
  • 面试问题总结——关于OpenCV(二)
  • GStreamer与OpenCV集成
  • 网络基础19--OSPF路由业务多区域
  • 解决VSCode中Github Copilot无法登陆的问题
  • HTTPS的基本理解以及加密流程
  • 掌握JavaScript函数封装与作用域
  • 学习随笔录
  • C#与C++交互开发系列(二十四):WinForms 应用中嵌入C++ 原生窗体
  • 达梦[-2894]:间隔表达式与分区列类型不匹配
  • [硬件电路-93]:模拟器件 - 晶体管的静态工作点,让晶体管工作在其放大电路舞台的中央!!!
  • MyBatis Plus 对数据表常用注解
  • ​机器学习从入门到实践:算法、特征工程与模型评估详解
  • 计算机中的单位(详细易懂)
  • 关于数据库表id自增问题
  • MySQL存储引擎深度解析与实战指南
  • 告别虚函数性能焦虑:深入剖析C++多态的现代设计模式
  • 数组相关学习
  • 基于深度学习的胸部 X 光图像肺炎分类系统(五)
  • 解决笔记本合盖开盖DPI缩放大小变 (异于网传方法,Win11 24H2)
  • 20分钟学会TypeScript
  • 若依框架 ---一套快速开发平台
  • 从零本地部署使用Qwen3-coder进行编程