1.讓屬性不可枚舉:
(function () {
Object.defineProperty(ClassA.prototype, "propA", {
get: propAGetter,
set: propASetter,
enumerable: false,
configurable: false
});
function checkPropA(self) {
if (!(_propAName in self)) {
if (!Object.isExtensible(self)) {
throw new Error("can't define propA for nonextensible obj");
}
Object.defineProperty(self, _propAName, {
writable: true,
value: _propA,
enumerable: false,
configurable: false
});
}
}
function propASetter(v) {
checkPropA(this);
this[_propAName] += v;
};
function propAGetter() {
checkPropA(this);
return this[_propAName];
};
var _propAName = "_propA";
var _propA = 1;
})();
var b = new ClassB(1, 2, 3);
for (var prop in b) {
console.log(prop);
}
b.propA = 4;
console.log(b.propA);
打印結果:getParamB, setParamB, porpC, constructor, funcA, funcB, 6
注意不是5,因爲在B的構造函數中繼承了ClassA的代碼this.propA = paramA;
2.定義不可變的類:
定義一些工具函數:e.g.
//將制定名字或者所有的屬性設置爲不可寫以及不可配置的
function freezeProps(o) {
var props = (arquments.length == 1) ?
Object.getOwnPropertyNames(o) :
Array.prototype.splice.call(arguments,1);
props.forEach(function(n) {
if (!Object.getOwnPropertyDescriptor(o, n).configurable) return;
Object.defineProperty(o, n, {writable: false, configurable: false});
});
return o;
}
3.封裝對象的狀態:
將setter,getter函數更爲嚴格地進行封裝:
function setAndGetProp(o, p, g, s) {
var obj = {enumerable: true, configurable: false};
if (g) obj.get = g;
if (s) obj.set = s;
Object.defineProperty(o, p, obj);
}
//定義構造函數
function ClassA(paramA, paramB) {
//定義實例字段
this.propA = paramA;
function getParamB() {
return paramB;
};
function setParamB(value) {
paramB = value;
};
setAndGetProp(this, "paramB", getParamB, setParamB);
}