JavaScript对象属性
在JavaScript对象与原型体系中我们提到过, 对象具有状态和行为的特征。
在其他编程语言中,对象状态和行为分别被抽象成了属性和方法,而JavaScript
在自己的对象模型设计中将它们都抽象成了对象的属性
。
高度的抽象也使得关于对象的属性设计上明显比Java等其他语言更为复杂, 本文主要对JavaScript
的属性的特点以及操作他们的函数进行了梳理和总结。
JavaScript
对象的属性主要可以分为数据属性
和访问器属性
两类,同时,对象所具有的属性并非简单的K-V键值对, 每个属性都由一组特征(attribute)来描述。
数据属性
数据属性是我们通常使用的K-V键值对,它主要有四个特征来描述:
value
属性的数据值, 默认值为undefinedenumerable
表示该属性是否可枚举configurable
表示该属性是否能被删除,或特征值被修改writable
表示该属性值
是否能修改
访问器属性
访问器属性定义了在访问对象属性时的行为,它同样有四个特征来描述:
get
读取属性时调用的函数, 默认值为undefinedset
设置属性时访问的函数, 默认值为undefinedenumerable
表示该属性是否可枚举configurable
表示该属性是否能被删除,或特征值被修改
定义和修改属性的特征
在日常开发过程中,我们通常会直接为某个对象的属性赋值:
var obj={
aaa:"bbb"
get bbb(){
return "aaa"
}
}
通过这种方式所产生的数据属性特征{enumerable, configurable, writable} 都默认为true.
我们还可以使用Object.defineProperty函数定义或修改对象的数据属性或者访问器属性。
这里需要注意的一点是, 通过Object.defineProperty函数所定义的属性,如果没有显式指定相应的特征值, 则{enumerable, configurable, writable} 都默认取值为false.
通过Object.getOwnPropertyDescriptor函数, 可以读取指定对象上自身属性的属性特征(属性特征描述符), 改方法返回了一个关于属性特征的Descriptor
对象:
{
value,
enumerable,
configurable,
writable,
get,
set
}
通过Descriptor可以访问到指定属性的特征值。
属性的configurable
特征通常表示该属性本身是否能够被删除或被修改, 一旦设置为false则无法改为true。
同时,当configurable
为false的时候, 除了能修改writable
之外的特征值都会报错。
总结
通过上面的介绍,我们可以看到,JavaScript
对象模型其实是一个Map结构:<propName:Descriptor>
, key是属性名,而value则是该属性的Descriptor对象。
这样的设计让JavaScript
的对象属性具有了强大的动态性,可以在运行时灵活地修改一个对象的属性。