讲师中心 微信公众号
AI工具推荐 视频效率加速

深入理解JavaScript中的立即调用类表达式(IICE)及其执行机制

轻涛君_7355

轻涛君_7355

发布时间:2025-11-23 12:33:01

|

947人浏览过

|

来源于php中文网

原创

深入理解JavaScript中的立即调用类表达式(IICE)及其执行机制

本文深入探讨javascript中立即调用类表达式(iice)的执行机制,通过一个嵌套继承的示例,详细解析其声明、继承、实例化及构造函数调用顺序。我们将识别父子类关系,揭示属性初始化时序对结果的影响,并提供修正方案,旨在帮助开发者理解此类复杂结构的行为和潜在陷阱。

1. 立即调用类表达式(IICE)概览

在JavaScript中,立即调用函数表达式(IIFE)是一种常见的模式,用于创建私有作用域并立即执行。与此类似,立即调用类表达式(Immediately Invoked Class Expression, IICE)则是一种声明一个匿名类并立即实例化该类的模式。其基本形式为 new (class MyClass { /* ... */ })()。这种结构允许我们定义一个类,然后无需将其绑定到具名变量,直接创建一个实例。

考虑以下示例代码,它展示了一个嵌套的立即调用类表达式:

new (class C extends class B {
  constructor() {
    console.log(this.foo());
  }
} {
  num = 1;
  foo() {
    return this.num;
  }
})();

这段代码看似复杂,但通过逐步分解,我们可以清晰地理解其执行机制。

2. 代码结构解析与执行流程

为了更好地理解上述代码,我们将其从内到外进行分解。

立即学习“Java免费学习笔记(深入)”;

2.1 内部类声明:父类 B

首先,我们关注最内部的类声明:

class B {
  constructor() {
    console.log(this.foo());
  }
}

这是一个标准的类声明,定义了一个名为 B 的类。在JavaScript中,类声明的本质是创建一个构造函数。因此,class B { ... } 实际上生成了一个名为 B 的构造函数。这个构造函数在实例化时会执行 console.log(this.foo())。

2.2 外部类声明:子类 C

接下来,我们将内部的 class B 视为一个已定义的实体(即构造函数 B),那么整个表达式可以简化为:

new (class C extends B {
  num = 1;
  foo() {
    return this.num;
  }
})();

这里,我们声明了另一个匿名类,为了便于理解,我们称之为 C。这个类 C 通过 extends B 继承了类 B。因此,B 是父类,C 是子类。

类 C 包含一个实例属性 num,初始化为 1,以及一个方法 foo(),用于返回 this.num。

2.3 类的实例化

最后,整个表达式 new (C)() 或者简化为 new C(),表示立即实例化这个匿名子类 C。

js2java
js2java

JavaScript 到 Java 全栈翻译助手,专为前端开发者学习 Java 或快速实现后端业务逻辑而设计。当用户提到以下场景时必须使用此技能: - "帮我把这段 JS 代码转成 Java" - "用 Java 怎么写这个逻辑" - "我习惯用 JS 写,想翻译成 Java" - "教我 Java,我要写后端接...

下载

2.4 构造函数执行顺序与方法调用

当 new C() 被执行时,其内部的执行流程如下:

  1. 创建实例对象: JavaScript引擎首先创建一个新的空对象,并将其原型链指向 C.prototype。
  2. 调用父类构造函数: 接着,会自动调用父类 B 的构造函数。在 B 的 constructor 中,执行 console.log(this.foo())。
    • 此时,this 指向的是正在被创建的 C 的实例。
    • this.foo() 会被调用。由于 C 继承了 B,并且 C 自身定义了 foo() 方法,因此会调用 C 实例上的 foo() 方法。
  3. 初始化子类实例属性: 父类构造函数执行完毕后,才会初始化子类 C 中声明的实例属性 num = 1。
  4. 调用子类构造函数: 如果子类 C 有自己的 constructor(本例中没有显式定义,但会有一个隐式的 constructor),则会执行。

3. 深入分析:属性初始化与执行时序问题

根据上述执行顺序,我们可以发现一个关键问题:在父类 B 的 constructor 中调用 this.foo() 时,子类 C 的实例属性 num = 1 尚未被初始化。

在JavaScript类的继承中:

  • 父类的构造函数会首先执行。
  • 子类的实例属性(如 num = 1)是在父类构造函数执行完毕后,但在子类自身构造函数(如果存在且显式调用 super())执行之前进行初始化的。

因此,当 B 的 constructor 调用 this.foo() 时,this.num 实际上还未被赋值,其值为 undefined。所以,原始代码的输出结果是 undefined。

// 原始代码执行结果
undefined

4. 解决方案与最佳实践

要解决 undefined 的问题,我们需要确保在 B 的 constructor 调用 this.foo() 时,num 属性已经存在并被正确初始化。一种直接的方法是将 num 属性的声明移动到父类 B 中。

new (class C extends class B {
  num = 1; // 将 num 属性移动到父类 B 中
  constructor() {
    console.log(this.foo());
  }
} {
  // num = 1; // 此处不再需要
  foo() {
    return this.num;
  }
})();

在这个修正后的版本中:

  1. 当 new C() 实例化时,会先创建实例对象。
  2. 调用父类 B 的 constructor。
  3. 在 B 的 constructor 执行之前,B 中声明的实例属性 num = 1 会被初始化到实例上。
  4. 然后 B 的 constructor 执行 console.log(this.foo())。此时 this.num 已经为 1。
  5. this.foo() 返回 1。

因此,修正后的代码将输出 1。

// 修正后代码执行结果
1

注意事项:

  • 属性初始化时机: 在涉及类继承和构造函数调用的复杂场景中,务必清晰理解实例属性的初始化时机。ES6 类中的实例属性(Class Field)在父类构造函数执行后、子类构造函数执行前初始化。
  • 设计考量: 立即调用类表达式通常用于创建单例、封装私有逻辑或动态生成类等高级场景。在设计此类结构时,应仔细考虑其生命周期、继承关系和属性访问权限。
  • 避免副作用: 尽量避免在父类构造函数中调用子类中定义但依赖子类属性的方法,除非你明确知道这些属性在调用时已经初始化。如果必须如此,可以考虑将属性提升到父类,或者在子类构造函数中重写父类逻辑以确保属性的正确初始化。

5. 总结

立即调用类表达式是一种强大的JavaScript模式,它允许我们以简洁的方式定义并实例化类。然而,当与继承结合使用时,尤其是在父类构造函数中调用子类方法并依赖子类属性时,其执行时序可能导致意想不到的结果(如 undefined)。

理解JavaScript类的声明、继承链、构造函数调用顺序以及实例属性的初始化时机是避免此类问题的关键。通过将依赖的属性提升到父类,或者重新设计方法调用逻辑,可以确保代码的正确性和可预测性。在复杂的类结构中,清晰地规划属性和方法的声明位置,是编写健壮、可维护代码的重要一环。

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

相关专题

更多
es6新特性
es6新特性

es6新特性有:1、块级作用域变量;2、箭头函数;3、模板字符串;4、解构赋值;5、默认参数;6、 扩展运算符;7、 类和继承;8、Promise。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

265

2023.07.17

es6新特性有哪些
es6新特性有哪些

es6的新特性有:1、块级作用域;2、箭头函数;3、解构赋值;4、默认参数;5、扩展运算符;6、模板字符串;7、类和模块;8、迭代器和生成器;9、Promise对象;10、模块化导入和导出等等。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

406

2023.08.04

JavaScript ES6新特性
JavaScript ES6新特性

ES6是JavaScript的根本性升级,引入let/const实现块级作用域、箭头函数解决this绑定问题、解构赋值与模板字符串简化数据处理、对象简写与模块化提升代码可读性与组织性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

355

2025.12.24

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

3736

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

306

2025.12.06

console接口是干嘛的
console接口是干嘛的

console接口是一种用于在计算机命令行或浏览器开发工具中输出信息的工具,提供了一种简单的方式来记录和查看应用程序的输出结果和调试信息。本专题为大家提供console接口相关的各种文章、以及下载和课程。

836

2023.08.08

console.log是什么
console.log是什么

console.log 是 javascript 函数,用于在浏览器控制台中输出信息,便于调试和故障排除。想了解更多console.log的相关内容,可以阅读本专题下面的文章。

6023

2024.05.29

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

11705

2023.07.31

PixTV官网入口地址合集
PixTV官网入口地址合集

本专题汇总了 PixTV AI 一站式视频创作平台的官方入口与使用教程。无需下载软件,浏览器直接访问即可使用。平台将剧本、图像、视频、声音与剪辑整合在“无限画布”中,接入 GPT Image 2.5、Seedance 2.5 等头部模型。本专题整理了从新建画布、角色锚定、分镜拆分到视频生成与导出的完整操作指南,助你快速上手 AI 短剧与漫剧创作。

100

2026.10.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebStorm 官方调试文档
WebStorm 官方调试文档

共0课时 | 0人学习

React 教程
React 教程

共58课时 | 12.2万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 6.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn