在 JavaScript 中拥有“私有”成员的标准方法是在构造函数中使用局部变量,并在调用构造函数的上下文中将需要访问它们的任何内容定义为闭包,如下所示:
function Class() {
var privateValue = 0;
this.getPrivateValue = function() {
return privateValue;
};
}
Class.prototype.doSomething = function() {
// This function doesn't have access to `privateValue`
// except through `getPrivateValue`, even though
// it's accessible as a member of the instance
};
许多人已经描述了这一点,其中最著名的可能是道格拉斯·克罗克福德( Douglas Crockford ) 。
请注意,这会产生影响,即每个实例Class
都有自己的函数副本,因为每个实例都是getPrivateValue
对构造函数的不同调用的闭包(这就是它起作用的原因)。(但这并不意味着函数的所有代码都是重复的;至少一些引擎——例如谷歌的 V8 引擎,用于 Chrome 和其他地方——允许相同的代码被具有不同关联上下文的多个函数对象共享.)
(旁注:我没有使用这个名字private
,因为它是一个保留字。在 ES3 中,它是一个“未来的保留字”;在 ES5 中,它只是严格模式下的一个;详情。)
我在上面使用了一个简单的变量而不是一个对象,以避免使事情看起来比实际更复杂。这是适用于您的示例的方式:
function Class() {
var privateData = {};
this.get = function(name) {
return privateData[name];
};
this.set = function(name, value) {
privateData[name] = value;
};
}
或者,如果您仍然希望跨实例共享类范围的私有数据:
var Class = function() {
var dataSharedAmongstInstances;
function Class() {
var privateDataForEachInstance = {};
this.get = function(name) {
return privateDataForEachInstance[name];
};
this.set = function(name, value) {
privateDataForEachInstance[name] = value;
};
}
return Class;
})();