出于教学目的:如何在封装的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
相关产品推荐
相关产品推荐

