带有私有变量的JavaScript构造函数模式[重复]
Posted
技术标签:
【中文标题】带有私有变量的JavaScript构造函数模式[重复]【英文标题】:JavaScript constructor pattern with private variables [duplicate] 【发布时间】:2014-11-10 14:49:12 【问题描述】:我知道在 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:根据已接受答案中的链接标记为重复项。
【问题讨论】:
不使用构造函数模式(没有一些技巧,我不鼓励)。但是,您可以通过使用 Object.defineProperty(); 来实现隐私的“形式”;使您的属性不可枚举,不可写,不可配置。否则模块模式是要走的路。 回答您的编辑,如果您要在每个实例上重新定义您的方法,为什么要使用构造函数? 它们使用相同的方法,但是为每个实例化的对象创建一个新的方法实例。上面的构造函数模式链接中对此进行了解释。 实际上,为了清楚起见,您不是在创建方法的新实例,而是在对象的原型链中添加方法。我添加了一个带有解释的答案 嗯,不。 “私有”属性是通过使用局部变量来模拟的。变量受词法范围的约束。并且原型函数是在这些私有变量的词法范围之外定义的。 【参考方案1】:当您在对象的原型上创建 getVar 时,当您执行以下操作时不会调用它:
objectName.getVar();
因为原型的方法出现在对象方法之后。下面的示例将向您展示我的意思:
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。当找到有效方法时,它会停止并返回。在您的情况下,您的实例方法位于原型方法之前。
【讨论】:
这似乎根本无法回答问题。 这不是对最初问题的回答,而是对主要问题中的一个 cmets 的回答。 ;) 唯一不属于你(或我)的评论是 “他们使用相同的方法,但是为每个实例化的对象创建一个新的方法实例。在上面的构造函数模式链接。”。而且我看不出这与您发布的内容有何关系。您发布的内容似乎更像是评论而不是答案。 是的,但这种说法显然是一种误解,所以我选择阐明一些观点。 (你说得对,这不是一个明确的问题)。 我不认为 OP 在这里误解了什么,但我可能是错的。【参考方案2】:有什么方法可以“正确”地使用原型的构造函数模式,同时仍然获得“私有”功能?
没有。这种具有特权函数的模式基于闭包范围,不能与共享函数一起使用。所有特权方法必须是特定于实例的。
如果没有办法做到这一点,为每个类实例重新定义方法真的那么糟糕吗?
没有。现代 JavaScript 引擎很好地优化了这种模式。当然,有 a little overhead,但在典型设置中您不会注意到。
似乎我唯一错过的就是继承?
仍然可以继承,请参阅Define Private field Members and Inheritance in JAVASCRIPT module pattern。当然,派生子类不能直接访问在父构造函数中声明的私有变量,但通常它们也不需要。
【讨论】:
以上是关于带有私有变量的JavaScript构造函数模式[重复]的主要内容,如果未能解决你的问题,请参考以下文章