初始化data流程如下
- 将data中的属性,挂载到实例
vm
下的_data
属性。如果data是函数,会首先对data函数求值 - 对
vm._data
做代理工作。遍历_data
中的每一个key执行proxy(vm, '_data', key)
核心proxy
的代码如下
function proxy(target, sourceKey, key) {
Object.defineProperty(target, key, {
get() {
return this[sourceKey][key];
},
set(val) {
this[sourceKey][key] = val;
}
})
}
这段代码比较简单,其目的就是当我们访问vm下面的key属性时,实际上访问的是vm._data.key
,这就实现了一层代理。那也许有人会问,为什么要做一层代理,我直接一开始就将data()
中的属性就挂载到vm上不行吗?这样的话我们就需要维护两份data数据了,一份是data中,一份在vm上,用于依赖收集和依赖更新(这种方式也存在一个问题,如下:)。
function proxy(target, key) {
Object.defineProperty(target, key, {
get() {
// 依赖收集
// 这里又访问了target.key, 形成了死循环
return target.key;
}
})
}