监听对象变化,让对象中的数据变得可观测:
Object.defineProperty 劫持对象属性进行监听
let obj = {
name:'小明'
}
let val = 20
Object.defineProperty(obj,'age',{
get(){
console.log(`age属性被读取${val}`)
retrun val
}
set(newVal){
console.log(`age属性被修改了,新值${newVal}`)
val = newVal
}
})
但上述代码只能对某一个属性进行监听,若需对多个数据进行监听则需写多个,麻烦
解决:使用观测类
//./obser.js
export class Observer{
constructor(value){
this.value = value
if(Array.isArray(value)){
//数组逻辑
}else{
// 对象逻辑
this.walk(value)
};
}
walk(obj){
const keys = Object.keys(obj)
for(let i = 0; i < keys.length; i++){
defineReactive(obj,keys[i])
}
}
}
//循环 让对象的每一个属性都变成可观测的
function defineReactive(obj,key,val) {
if(arguments.length === 2){
val = obj[key]
}
if(typeof val === 'object'){
new Observer(val)
};
Object.defineProperty(obj,key,{
enumerable:true, //可枚举
configurable:true, //可改变
get(){
console.log(`${key}属性被读取了`)
return val
},
set(newVal){
console.log(`${key}属性被修改了,新值为${newVal}`)
val = newVal
}
})
}
//使用 ./obser.html
<script type="module">
// 使用类js必须声明类型为模块化
import {Observer} from './obser.js'
let obj = new Observer({
name:'小明',
age:18,
demo:{
a:'aaa',
b:12
}
})
console.log(obj.value.name)
obj.value.age = 25
console.log(obj.value.demo.a)
obj.value.demo.b = 11
</script>