一、属性描述符
ECMAScript对象中目前存在的属性描述符
主要有两种,数据描述符
(数据属性)和存取描述符
(访问器属性)。
数据描述符
是一个拥有可写或不可写值的属性。存取描述符
是由一对 getter-setter 函数功能来描述的属性。
二、数据描述符属性
当修改或定义对象的某个属性的时候,给这个属性添加一些特性:
1 | Object.defineProperty(obj, "newKey", { |
- Value:属性对应的值,可以使任意类型的值,默认为undefined
- Writable:属性的值是否可以被重写,默认为false。
- Enumerable:此属性是否可以被枚举,默认为false。
- Configurable:设置为true可以被删除或可以重新设置特性,默认为false。
提示:一旦使用Object.defineProperty给对象添加属性,那么如果不设置属性的特性,那么configurable
、enumerable
、writable
这些值都为默认的false
1 | Object.defineProperty(person, 'name', { |
三、存取描述符属性
当使用存取器描述属性的特性的时候,允许设置以下特性属性:
1 | var obj = {}; |
注:
- 当使用了getter或setter方法,不允许使用writable和value这两个属性
- get或set不是必须成对出现,任写其一就可以。如果不设置方法,则get和set的默认值为undefined
1 | Object.defineProperty(obj, 'a', { |
四、Object.defineProperties
1 | var obj = new Object(); |
五、defineProperty的缺陷
Object.defineProperty
无法监听数组元素的变化
1 | var obj = { arr: [] }; |
注:对数组元素的监测,需要用一些奇技淫巧,把无法监听数组的情况hack掉。如vue提供的['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']
等方法。传送门
1 | 需要对每个对象的每个属性进行遍历,如果属性值也是对象那么需要深度遍历 |