这个方法的主要用处是用来做数据劫持的,在vue2.x主要使用这个方法,在3.0中换成了proxy做数据劫持,数据劫持就是监听到数据的变化,然后可以做什么等
Object.defineProperty
/* 随便定义一个对象 */
let obj = {
name: 'hello',
age: 18,
child: {
sex: '女'
}
}
observer(obj)
function observer(obj) {
/* 判断传入进来的是否是对象 */
if (obj.constructor === Object) {
/* 循环对象 */
for (let key in obj) {
/* 如果值不是对象,则做劫持 */
if (obj[key].constructor !== Object) {
/* 定义一个临时变量,用于return出去 */
let _value = obj[key]
Object.defineProperty(obj, key, {
/* 设置属性可以被删除,可以被修改 */
configurable: true,
/* 设置属性可以被遍历 */
enumerable: true,
get() {
console.log('触发读取')
return _value
},
set(newVal) {
console.log('触发修改')
_value = newVal
}
})
} else {
/* 否则进行递归,再次判断 */
observer(obj[key])
}
}
}
}
Proxy
let obj = {
name: '小红',
age: 1
}
obj = new Proxy(obj, {
get(target, key) {
console.log(target)
console.log(key)
},
set(target, key, newVal) {
console.log(target)
console.log(key)
console.log(newVal)
}
})
console.log(obj)
`Object.defineProperty`在新增属性的时候没办法追踪吗?
这个我在vue里面测试了。vue里面也无法监听到新的属性值,但有个很巧妙的操作,如果读取了这个对象里的其他属性,再新增属性,就可以读取到。这是我写的demo
```html
obj固有的属性name:{{ obj.name }}obj新增的属性asd:{{ obj.asd }} new Vue({ el: "#app", data: { obj: { name: "哈哈" } }, mounted() { setTimeout(() => { this.obj.name = '哦121212' this.obj.asd = '哦' console.log(this.obj); }, 3000) } })
```