我假设 Node.js 或任何其他可以使用整个 EcmaScript 5 的环境。
如今,在 JavaScript 中拥有真正私有数据的唯一方法是在构造函数中保留一个变量,这就是您正在做的事情。但是,您return
对init
函数中的使用感到困惑。虽然该init
函数几乎是构造函数,但它并没有被完全调用,所以return
什么也不做。即使它做了什么,你想要的是将一个属性添加到this
,而不是返回一个新对象。所以基本上你必须将其更改return
为Object.defineProperty
:
init: function (name) {
// notice that the private variable has a different name
// than the parameter
var privateName = '~';
Object.defineProperty(this, 'myName', {
set: function (value) {
privateName = value + " +?";
},
get: function () {
return privateName + "^^^^^^^^^";
}
});
this.myName = name;
}
这仍然有继承的限制。如果您想从 Person 类继承并修改 getter 和 setter,您必须获取属性描述符,修改它并重新定义属性。那很痛苦。而且它不支持访问“超级getter/setter”。为了避免我们通常在 JavaScript 中所做的是忘记拥有真正的私有属性并按照约定使用私有属性,私有属性的名称以_
. 然后你可以像这样在原型中简单地定义你的getter和setter:
var Person = Class.extend({
init: function(name) {
// the private name property
this._name = '~';
this.myName = name;
},
set myName(value) {
this._name = value + " +?";
},
get myName() {
return this._name + "^^^^^^^^^";
}
});
这将让您在使用继承时访问超级 getter/setter。
有一个尖端功能可以让您拥有真正的私有并继承 getter 和 setter:WeakMap。WeakMap 基本上是一个对象,它在其他两个不计入垃圾收集的对象之间创建关系。最后一部分对于内存管理很重要,而第一部分是让你拥有真正私有的部分。您可以在 Firefox 的 Beta 版本和带有--harmony_collections
标志的 Node.js 中尝试 WeakMaps。以下是它的工作原理:
function privatize() {
var map = new WeakMap();
return function (obj) {
var data = map.get(obj);
if (!data) {
map.set(obj, data = {});
}
return data;
};
}
var Person = (function () {
var _private = privatize();
return Class.extend({
init: function(name) {
// the private name property
_private(this).name = '~';
this.myName = name;
},
set myName(value) {
_private(this).name = value + " +?";
},
get myName() {
return _private(this).name + "^^^^^^^^^";
}
});
}());