在定义对象、定义属性时,我们曾经介绍过属性描述符,属性描述符实际上就是一个对象。属性描述对象包含6个属性,可以选择使用。
- value:设置属性值,默认值为undefined。
- writable:设置属性值是否可写,默认值为true。
- enumerable:设置属性是否可枚举,即是否允许使用for/in语句或Object.keys()函数遍历访问,默认为true。
- configurable:设置是否可设置属性特性,默认为true。如果为false,将无法删除该属性,除了value特性外,也不能修改属性的属性描述对象。
- get:取值函数,默认为undefined。
- set:存值函数,默认为undefined。
【示例1】下面示例演示了使用value读写属性值的基本用法。
var obj = {}; //定义空对象
Object.defineProperty(obj, 'x', { value: 100 }); //添加属性x,值为100
console.log( Object.getOwnPropertyDescriptor(obj, 'x').value ); //返回100
【示例2】下面示例演示了使用writable属性禁止修改属性x。
var obj = {};
Object.defineProperty(obj, 'x', {
value: 1, //设置属性默认值为1
writable: false //禁止修改属性值
});
obj.x = 2; //修改属性x的值
console.log( obj.x ) //1,说明修改失败
提示,在正常模式下,如果writable为false,重写属性值不会报错,但是操作失败,而在严格模式下会抛出异常。
【示例3】enumerable可以禁止for/in语句、Object.keys()函数、JSON.stringify()方法遍历访问指定属性,这样可以设置隐藏属性。
var obj = {};
Object.defineProperty(obj, 'x', { //定义属性
value: 1, //定义属性值
enumerable: false //禁止遍历
});
console.log( obj.x ); //1,直接读取
for (var key in obj) { //遍历
console.log(key);
} //空,没有找到属性
console.log( Object.keys(obj) ); //[]
console.log( JSON.stringify(obj) ); //"{}"
【示例4】configurable可以禁止修改属性描述对象,当其值为false时,value、writable、enumerable和configurable禁止修改,同时禁止删除属性。在下面示例中,当设置属性x禁止修改配置后,下面操作都是不允许的,其中obj.x =5;操作失败,而后面4个操作方法都将抛出异常。
var obj = Object.defineProperty({}, 'x', {
configurable: false //禁止配置
});
obj.x =5; //试图修改其值
console.log( obj.x ); //修改失败,返回undefined
Object.defineProperty(obj, 'x', {value: 2}); //抛出异常
Object.defineProperty(obj, 'x', {writable: true}); //抛出异常
Object.defineProperty(obj, 'x', {enumerable: true}); //抛出异常
Object.defineProperty(obj, 'x', {configurable: true}); //抛出异常
【注意】
当configurable为false时,如果把writable=true改为false是允许的。只要writable或configurable有一个为true,value也允许修改。