Object.defineProperty
Object.defineProperty(obj, prop, descriptor)
descriptor的描述有两种:数据描述符和存取描述符。
数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。
存取描述符是有getter-setter函数描述的属性。
描述符必须是这两种形式之一,不能同时是两者。
可同时具 有的键值 |
configurable | enumerable | value | writable | get | set |
数据描述符 | yes | yes | yes | yes | no | no |
存取描述符 | yes | yes | no | no | yes | yes |
默认值 | false | false | undefined | false | undefined | undefined |
当writable属性设置为false时,该属性被称为“不可写”。它不能被重新分配。如果试图写入非可写属性,属性不会改变,也不会引发错误。
enumerable定义对象的属性是否可以在for...in循环和Object.keys()中被枚举。enumerable默认为false,如果直接赋值的方式(o.d=4)创建对象的属性,则这个属性的enumerable为true。
o.propertyIsEnumerable('a'); 获取对象的属性是否可枚举。
configurable特性表示对象的属性是否可以被删除,以及除value和writable特性外的其他特性是否可以被修改。
var o = {};
o.a = 1;
// 等同于 :
Object.defineProperty(o, "a", {
value : 1,
writable : true,
configurable : true,
enumerable : true
});
// 另一方面,
Object.defineProperty(o, "a", {
value : 1
});
// 等同于 :
Object.defineProperty(o, "a", {
value : 1,
writable : false,
configurable : false,
enumerable : false
});
记住,这些选项不一定是自身属性,如果是继承来的也要考虑。为了确认保留这些默认值,你可能要在这之前冻结 Object.prototype,明确指定所有的选项,或者通过 Object.create(null)将__proto__属性指向null。
注意:在对象上设置值属性时,如果原型上不存在这个属性,那么设置的值属性在对象上。然而,如果原型上一个不可写的属性被继承,那么它仍会防止修改对象上的属性。
function myclass() { }
myclass.prototype.x = 1;
Object.defineProperty(myclass.prototype, "y", {
writable: false,
value: 1
});
var a = new myclass();
a.x = 2;
console.log(a.x);// 2
console.log(myclass.prototype.x); // 1
a.y = 2; // Ignored, throws in strict mode
console.log(a.y); // 1
console.log(myclass.prototype.y); // 1
参考博客: