var obj = {
a: 1
}
// 获取属性描述符
var desc = Object.getOwnPropertyDescriptor('obj','a');
console.log(desc);
desc = {
value: 1,
writable: true,
enumerable: true,
configurable: true
}
// 设置属性描述符 - 其他属性
Object.defineProperty(obj,'a',{
get: function () {}, // 读取器getter
set: function () {}, // 设置器setter
})
- 通过
Object.getOwnPropertyDescriptor('obj','a')可以获得对象obj下a属性的描述符
Object.defineProperty(obj,'a',{ ...desc })重新定义属性描述符
value为值,writable是否可重写,enumerable是否可遍历,configurable表示属性描述符是否可再修改
Object.freeze冻结对象,使其里面的属性值全部不能修改
Object.seal方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。
完整代码如下:
var aGoods = {
pic: '.',
title: '..',
desc: `...`,
sellNumber: 1,
favorRate: 2,
price: 3,
};
class UIGoods {
get totalPrice() {
return this.choose * this.data.price;
}
get isChoose() {
return this.choose > 0;
}
constructor(g) {
g = { ...g };
Object.freeze(g);
Object.defineProperty(this, 'data', {
get: function () {
return g;
},
set: function () {
throw new Error('data 属性是只读的,不能重新赋值');
},
configurable: false,
});
var internalChooseValue = 0; // 中间变量,外部无法访问
Object.defineProperty(this, 'choose', {
configurable: false,
get: function () {
return internalChooseValue;
},
set: function (val) {
if (typeof val !== 'number') {
throw new Error('choose属性必须是数字');
}
var temp = parseInt(val);
if (temp !== val) {
throw new Error('choose属性必须是整数');
}
if (val < 0) {
throw new Error('choose属性必须大于等于 0');
}
internalChooseValue = val;
},
});
this.a = 1;
Object.seal(this); // 不让加新属性,原属性configurable设置为false,若原有属性可写则可修改
}
}
Object.freeze(UIGoods.prototype); // 不允许修改原型对象
var g = new UIGoods(aGoods);
UIGoods.prototype.haha = 'abc';
// g.data.price = 100;
console.log(g.haha);