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);
}