You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何复用参数相同的JS Class实例,避免重复执行构造函数?

解决方案:基于参数的实例复用(享元模式)

你需要的是**享元模式(Flyweight Pattern)**的实现,核心是根据传入的参数缓存已创建的实例,避免重复执行构造逻辑。下面提供两种优雅的实现方式:

方式一:改造构造函数,保留new语法

通过类的私有静态属性存储已缓存的实例,在构造函数中先检查缓存,存在则直接返回已有实例,不存在则创建新实例并缓存:

class MyClass {
  // 私有静态属性:存储已创建的实例,key为参数url
  static #instances = new Map();

  constructor(url) {
    // 先检查缓存中是否存在对应url的实例
    if (MyClass.#instances.has(url)) {
      return MyClass.#instances.get(url);
    }

    // 不存在则执行构造逻辑
    this.url = url;
    console.log("Constructing MyClass with", url);
    
    // 将新实例存入缓存
    MyClass.#instances.set(url, this);
  }
}

// 测试代码
new MyClass("url1");
new MyClass("url1"); // 复用已有实例,不会执行构造逻辑
new MyClass("url22222");

说明:

  • 使用私有静态属性#instances(ES2022+支持)存储缓存,避免外部篡改,比外部数组更安全优雅
  • 构造函数中通过return已有实例,覆盖了默认返回新创建this的行为,实现复用
  • 完全保留new的调用语法,对原有代码侵入性低

方式二:静态工厂方法(语义更明确)

如果不想修改构造函数的默认行为,可以提供一个静态工厂方法,专门负责获取/创建实例:

class MyClass {
  static #instances = new Map();

  constructor(url) {
    this.url = url;
    console.log("Constructing MyClass with", url);
  }

  // 静态工厂方法:获取对应url的实例
  static getInstance(url) {
    if (!MyClass.#instances.has(url)) {
      MyClass.#instances.set(url, new MyClass(url));
    }
    return MyClass.#instances.get(url);
  }
}

// 测试代码
MyClass.getInstance("url1");
MyClass.getInstance("url1"); // 复用实例
MyClass.getInstance("url22222");

说明:

  • 构造函数保持原有逻辑,语义更清晰:new始终创建新实例,getInstance负责复用
  • 适合需要明确区分"创建新实例"和"获取复用实例"的场景
  • 同样使用私有静态属性保证缓存的安全性

输出结果验证

运行上述任意一种代码,都会得到你期望的输出:

Constructing MyClass with url1
Constructing MyClass with url22222

额外优化建议

  • 如果参数是复杂类型(而非简单字符串),可以将参数序列化为字符串作为Map的key,或使用WeakMap(若参数是对象且允许被垃圾回收)
  • 如需清理缓存,可添加静态方法(如clearInstance(url))移除指定缓存或清空所有缓存

内容的提问来源于stack exchange,提问作者greentea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 10:17:19