响应式处理的过程中会有两种 dep,大致如下
const dep = new Dep()
const val = obj[key]
let childOb = observe(val)
Object.defineProperty(obj, key, {
get() {
dep.depend()
childOb && childOb.dep.depend()
}
})
昨天晚上仔细思考了一下这里发现比自己想象中的绕。我先简单的把二者区分为闭包 dep(上面 new 出来的 dep) 和 ob 的 dep(通过 observe 生成的可以通过数据本身访问到的 dep)。
我理解 js 中对于对象的访问有两种情况:
因此对象内部的访问也必然触发对象本身的访问。
通过 Object.defineProperty 我们可以拦截到内部的值被访问(新添加的属性除外),但是无法获取到对象本身被访问的情况,假使
new Vue({
data() {
return {
me: {
person: {
age: 22
}
}
}
}
})
模板中访问了 me.person.name,由于 name 并无定义,因此 me.person 对象的闭包 dep (有一个,但属于 age 属性的)没有捕获到这个访问,只有对象 me 的 key 为 person 的闭包 dep 拦截到了这个访问,若后续新增了属性 name,除了 me 的闭包 dep 根本无处通知。
因此 childOb 的作用也就是当模板访问 me.person.name 的时候,在通知 me 的 key 为 person 的闭包 dep 的同时,通知到 person 对象(通过__ob__打在对象上让对象可以自由访问到): person 你在这里被访问了,至于有没有访问内部属性,访问的属性存不存在我不知道、我也不管。你自己记录一下,以备有用。
大部分情况下都是闭包 dep 在发挥作用,直到新增属性以及数组元素变更(数组并没有自己的闭包 dep),需要访问数据属性上的 dep 手动触发通知。
因此:
希望老师可以帮忙看看后面这三点理解有没有什么问题,先谢过老师!