构建一个动态的可监听树
迄今为止,我们的模型在单层数据结构运行得很好,但是要求我们手工把每个新对象-值属性封装为可监听。例如,如下代码将不能按预期运行。
const person = observable({data: {name: 'John'}})
function print () {
console.log(person.data.name)
}
// outputs 'John' to the console
observe(print)
// does nothing
setTimeout(() => person.data.name = 'Dave', 100)
为了让代码运行,我们不得不把 observable({data: {name: 'John'}})
替换为 observable({data: observable({name: 'John'})})
。幸运的是,我们可以通过稍微修改 get
陷阱函数来去除这种不便。
function get (target, key, receiver) {
const result = Reflect.get(target, key, receiver)
if (currentObserver) {
registerObserver(target, key, currentObserver)
if (typeof result === 'object') {
const observableResult = observable(result)
Reflect.set(target, key, observableResult, receiver)
return observableResult
}
}
return result
}
如果返回值是一个对象的时候,上面的 get
陷阱函数会在返回之前把返回值设置为一个可监听的代理对象。从性能的角度来看,这也是相当完美的方案,因为可监听对象仅当监听函数需要的时候才创建。