熟悉vue和react的大家应该都知道,当数据变化的时候,我们会触发相应的DOM更新,那有没有思考过,怎么样监听到一个对象属性的变化呢?
答案是,ES5中提供了一个函数,Object.defineProperty(obj, key, {属性})
let obj = {name: 'hello'} Object.defineProperty(obj, 'name', { configurable: true, // 表示能否通过delete删除属性默认为true enumerable: true, // 表示能否通过for-in返回属性默认为true get () { console.log(obj['name']) }, set (newValue) { console.log('您设置了新的值' + newValue) } })
1、数据属性:
configurable: 表示能否通过delete删除属性默认为true
enumerable:表示能否通过for-in返回属性默认为true
writable: 是否可写
value: 值
2、访问器属性:
configurable: 表示能否通过delete删除属性默认为true
enumerable:表示能否通过for-in返回属性默认为true
get:callback
set:callback
这两组属性默认不能一起写,否则会报错,比如下面这段代码将会报错
Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #<Object>
at Function.defineProperty (<anonymous>)
let person = { name: 'qihr' } Object.defineProperty(person, 'age', { enumerable: true, configurable: true, value: '10', get: function () {} })
将configurable设置为false,表示不能从对象中通过delete删除掉属性。如果调用delete属性,非严格模式下没什么作用,但是在严格模式下则会报错。而且,如果一旦把属性定义为不可配置的,就不能把他变为可配置的了。这时,再调用Object.defineProperty()方法修改除writable之外的特性,都会导致错误:
let person = { name: 'qihr' } Object.defineProperty(person, 'age', { value: 20, configurable: false }) // 下面的代码将会抛出错误 Object.defineProperty(person, 'age', { value: 20, configurable: true })