带有私有变量的JavaScript构造函数模式

时间:2014-09-16 18:15:58

标签: javascript

我知道在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:根据接受的答案中的链接标记为重复。

2 个答案:

答案 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。它会在找到有效方法时停止并返回。在您的情况下,您的实例方法会在您的原型方法之前出现。