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

出于教学目的:如何在封装的ES5 Product对象创建时模拟自增ID?

嘿,这个问题我熟!要在这种闭包封装的"类"里实现自增的productId,关键是利用闭包来保存一个私有计数器,不让它暴露到全局作用域里。先帮你指出当前代码的问题:你写的getProductId方法里要返回的productId根本没定义,运行肯定会报错,得先把这个逻辑补全。

下面是修改后的完整实现,完美符合你的封装需求:

(function() {
  var Product = (function() {
    // 定义私有计数器,仅在这个IIFE作用域内可见,不会污染全局
    let productIdCounter = 0;

    function Product(name, description) {
      // 每次创建实例时,计数器自增,赋值给当前实例的私有ID
      const productId = ++productIdCounter;

      this.getName = function() {
        return name;
      };
      this.getDescription = function() {
        return description;
      };
      this.getProductId = function() {
        return productId;
      };
    }

    return Product;
  }());

  // 测试验证一下
  const p1 = new Product("无线耳机", "蓝牙连接,降噪功能");
  const p2 = new Product("机械键盘", "青轴,背光设计");
  console.log(p1.getProductId()); // 输出 1
  console.log(p2.getProductId()); // 输出 2
})();

为什么这么做可行?

  • 私有性保障:productIdCounter被放在包裹Product构造函数的IIFE内部,外部代码完全访问不到,既避免了全局变量污染,又保证了计数器不会被随意修改。
  • 唯一递增ID:每次调用new Product()时,构造函数会先将计数器自增,再把这个值绑定到当前实例的私有变量productId上——通过闭包,每个实例的getProductId方法都能精准返回自己的专属ID。
  • 兼容原有封装风格:延续了你用闭包隐藏属性、仅通过getter方法暴露数据的设计,完全符合封装的原则。

如果需要让ID从特定数值开始(比如从1000起步),只需要把productIdCounter的初始值改成999就行,第一个实例的ID就会是1000啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:02:13