属性特性
属性除了有名称和值之外,还有一些标注它们是否可写 可枚举和可配置的特性
这些特性给对象带来很大好处,比如:
- 把方法设置成不可枚举,看起来更像内置方法;
- 给对象定义不能修改或删除的属性,可以"锁定"这个对象.
数据属性有4个特性:值(value),可写性(writable),可枚举性(enumerable)和可配置性(configurable).
存取器属性不具有值特性和可写性,它的可写性是由是否存在setter决定的.因此存取器属性的4个特性是读取(get),写入(set),可枚举性和可配置性.
特性操作
通过属性描述符(property descriptor)对象可以对属性的特性进行查询和设置
读取属性特性
属性描述符与它描述属性的特性同名.所以数据属性描述符对象的属性有value,writable,enumerable和configurable,存取器属性描述符对象的属性有get,set,enumerable和configurable.其中writable,enumerable和configurable都是布尔值.get和set属性是函数值.
获取属性描述符:Object.getOwnPropertyDescriptor().
var o = { name:'Mike', sayHello:function(){console.log('hello')}}
Object.getOwnPropertyDescriptor(o,'name')
//{value: "Mike", writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o,'sayHello')
//{value: ƒ, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o,'age')
//undefined 获取不存在属性的描述符,返回undefined
getOwnPropertyDescriptor()只能获取自有属性的描述符.
设置属性特性
通过Object.defineProperty()可以修改属性特性,但只能修改自有属性或新建自有属性,不嫩修改继承属性.
var p={}
Object.defineProperty(p,'name',{value:'Mike',writable:true,enumerable:false,configurable:true}) //给p增加不可枚举属性
Object.keys(p) //[] name是不可枚举的
Object.defineProperty(p,'name',{writable:false}) //将name设为不可修改
p.name = 'Smith' //修改name,并不报错
console.log(p.name) //Mike 修改不成功
Object.defineProperty(p,'name',{value:'Smith'}) //通过配置方式修改name
p.name //Smith 修改成功
Object.defineProperty(p,'name',{get:function(){return 'Mike'},enumerable:true}) //将name转为存取器属性
Object.getOwnPropertyDescriptor(p,'name')
//{get: ƒ, set: undefined, enumerable: true, configurable: true}
如果需要一次新建或修改多个属性,使用Object.defineProperties().
var p = Object.defineProperties({},{
name:{value:'Mike',writable:false},
age:{value:18,enumerable:false}
})
Object.defineProperty()和Object.defineProperties()的使用规则(违反规则会抛出异常):
- 如果对象不可扩展,可以编辑已有自有属性,但不可添加属性
- 如果属性不可配置,不能修改它的可配置性和可枚举性
- 如果存取器属性不可配置,不能修改其setter和getter,不能转换为数据属性
- 如果数据属性不可配置,则不能转换为存取器属性
- 如果数据属性不可配置,则不能将可写性从false转为true,但可以从true修改为false
- 如果数据属性是不可配置且不可写的,则不能修改它的值
- 如果数据属性是可配置不可写的,可以先修改描述符为可写的,再修改其值
网友评论