我知道在JS中模仿私有变量是可能的:
function ConstructorPattern() {
var privateVar = 'hi there';
this.getVar = function() {
return privateVar;
};
};
但根据Learning JavaScript Design Patterns提及类Car
和方法toString
的类似代码时所述:
以上是构造函数模式的简单版本,但它确实遇到了一些问题。一个是它使继承变得困难,另一个是为使用Car构造函数创建的每个新对象重新定义了toString()等函数。这不是很理想,因为理想情况下,该函数应该在Car类型的所有实例之间共享。
因此,在我的案例中给出的解决方案是通过原型添加getVar函数:
ConstructorPattern.prototype.getVar = function() {
return privateVar;
};
但是当然这个函数不知道privateVar
是什么,所以它不起作用。我知道module pattern,但我特别希望能够实例化多个实例。
有没有办法在原型上“正确”使用构造函数模式,同时还能获得“私有”功能?
编辑:如果没有办法实现这一点,那么为每个类实例重新定义方法真的很糟糕吗?我最近开始研究采用这种方法的代码库。似乎我唯一遗漏的是继承?
EDIT2:根据接受的答案中的链接标记为重复。
答案 0 :(得分:3)
有没有办法在原型上“正确”使用构造函数模式,同时还能获得“私有”功能?
没有。具有特权函数的此模式基于闭包范围,不能与共享函数一起使用。所有特权方法必须是特定于实例的。
如果没有办法实现这一点,那么为每个类实例重新定义方法真的很糟糕吗?
没有。现代JavaScript引擎非常好地优化了这种模式。当然,有a little overhead,但在典型的设置中你不会注意到。
似乎我唯一遗漏的是继承?
仍然可以进行继承,请参阅Define Private field Members and Inheritance in JAVASCRIPT module pattern。当然,派生的子类不能直接访问在父构造函数中声明的私有变量,但通常它们通常不需要。
答案 1 :(得分:0)
当您在对象的原型上创建getVar时,在执行以下操作时不会调用它:
objectName.getVar();
因为原型的方法来自AFTER对象方法。下面的例子将告诉你我的意思:
function Car() {
var privy = "hidden";
this.getPrivy = function() {
return privy;
}
}
Car.prototype = {};
Car.prototype.getPrivy = function() {
return 'i came from prototype';
}
var obj = new Car;
obj.getPrivy();
JS遵循一个调用链,例如: 对象方法 - >原型方法 - >原型原型方法等....一直回到Object.prototype。它会在找到有效方法时停止并返回。在您的情况下,您的实例方法会在您的原型方法之前出现。