export class 导出唯一类定义,所有 import 获取同一构造函数;每次 new 创建独立实例,实例间属性隔离,仅原型和静态属性共享。

export class 本身不导出实例,只导出类定义;每次 new 都创建独立实例,无论 import 多少次、在多少文件中——这是 JavaScript 模块机制和类本质共同决定的。
模块加载与类定义共享
ES 模块是单例加载:同一路径的 export class Foo 在整个应用中只被解析执行一次,所有 import { Foo } 获取的是同一个类构造函数引用。
这意味着:
- 对 Foo.prototype 的修改(如动态加方法)会在所有 import 处生效
- Foo 自身的静态属性(Foo.count = 0)也是全局唯一一份,所有地方读写的是同一个值
- 但静态属性 ≠ 实例状态,它不随 new 而复制
实例对象天然隔离
每次调用 new Foo() 都会分配全新内存,生成彼此无关的对象:
- 不同文件里 import { Foo } 后各自 new Foo(),得到的实例拥有独立的 this.xxx 属性
- 即使两个实例调用同一原型方法,内部 this 指向各自数据,互不影响
- 不存在“多处 import 导致实例被共享”的情况——import 不触发实例化,只是拿到类
容易混淆的“伪共享”场景
看似“共享”的行为,往往源于外部状态或错误设计:
- 闭包捕获了外部变量:类方法内访问模块级 let/const 变量,多个实例共用该变量
- 静态属性被当实例状态用:Foo.id = Math.random() 写在类外,所有实例读到同一个值
- 传入了同一对象引用:多个实例接收同一个 config 对象,修改其属性时彼此可见
- 使用了单例模式封装:类内部用 static instance 控制仅返回一个实例,此时才是真共享——但这是主动设计,非 import 造成
验证方式很简单
在任意两处 import 同一类后打印实例标识:
console.log(new Foo() === new Foo()); // false<br>console.log(Object.getPrototypeOf(new Foo()) === Object.getPrototypeOf(new Foo())); // true
第一行必为 false(实例不同),第二行必为 true(原型相同),清晰体现“类共享、实例隔离”的本质。











