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

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.dtcms.com/a/298919.html

相关文章:

  • 数控滑台的功能与应用
  • 生产环境使用云服务器(centOS)部署和使用MongoDB
  • MongoDB数据模型
  • Zookeeper的简单了解
  • 学习嵌入式的第三十三天-数据结构-(2025.7.25)服务器/多客户端模型
  • Typecho插件开发:自定义注册用户组与免审发布功能实现
  • OTG原理讲解
  • 非定长滑动窗口(持续更新)
  • 【GoLang#3】:数据结构(切片 | map 映射)
  • 新手向:Git下载全攻略
  • 用Java实现rpc的逻辑和流程图和核心技术与难点分析
  • 图论:Dijkstra算法
  • 【WPF】NumericUpDown的用法
  • 01 01 01 第一部分 C++编程知识 C++入门 第一个C++程序
  • Linux如何执行系统调用及高效执行系统调用:深入浅出的解析
  • HashMap(JDK1.7、JDK1.8)原理与结构分析与synchronizedMap()
  • Spring Boot SSE实战:SseEmitter实现多客户端事件广播与心跳保活
  • Spring Boot 实战:用 Apache Commons CSV 优雅解析 CSV 文件
  • x86汇编语言入门基础(三)汇编指令篇5 串操作
  • OpenCV学习探秘之一 :了解opencv技术及架构解析、数据结构与内存管理​等基础
  • 技术赋能与营销创新:开源链动2+1模式AI智能名片S2B2C商城小程序的流量转化路径研究
  • 嵌入式硬件篇---zigbee无线串口通信问题解决方法
  • Claude 4.0 终极编程指南:模型对比、API配置与IDE集成实战
  • CMakeLists.txt 怎么写
  • 39.Python 中 list.sort() 与 sorted() 的本质区别与最佳实践
  • 数据库索引详解:原理、设计原则与应用场景
  • NLua和C#交互
  • 6G通感算
  • Spring Boot DFS、HDFS、AI、PyOD、ECOD、Junit、嵌入式实战指南
  • 学习游戏制作记录(剑投掷技能)7.26