我假設的Node.js或任何其他環境中,整個EcmaScript 5可用。
如今在JavaScript中擁有真正的私有數據的唯一方法是在構造函數中保存一個變量,這就是你正在做的事情。但是,您在init
函數中使用return
會令人困惑。儘管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。
有一個先進的功能,可以讓你有真正的私人和繼承獲取和設置:WeakMap。 WeakMap基本上是一個對象,它創建了另外兩個對象之間的關係,這些對象不計入垃圾回收。最後一部分對於內存管理很重要,第一部分是讓你擁有真正私有化的部分。您可以使用--harmony_collections
標誌嘗試Firefox的Beta版本和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 + "^^^^^^^^^";
}
});
}());
你在哪裏執行此JavaScript? – 2013-04-06 15:28:40