经过上一节(响应式的创建过程)分析,我们知道了data中数据的每一层都被我们通过Object.defineProperty架设了一层拦截,当我们去访问的时候会先执行了一些自己逻辑。那么现在有两个问题:什么时候会访问到data?拦截后做了什么?
访问data中数据的时机
-经过之前章节的分析,我们知道,每一个组件的加载过程都要经历一次mount,在mountComponent过程中定义了updateComponent函数并实例化一个渲染watcher,在其constructor中将updateComponent赋值给getter并调用了get方法

调用pushTarget

~dep是我们说的"发布者",它将在适当的时机去向订阅者进行广播,而watcher其实就是它的订阅者
~向targetStack中push,主要是因为组件的渲染是一次嵌套渲染的过程,它需要在每一次渲染完子组件后恢复到父组件
接着便调用getter即updateComponent方法

~执行组件的render,将调用render.call,render其实就是我们在组件内部手写的render函数

由于我们组件在init过程中已经为msg架设了拦截,故此时将进入msg的get方法
接着执行popTarget,将target恢复为父组件

最后执行cleanupDeps

~那么为什么说将这些deps 、 newDeps 、 depIds 、 newDepIds更新一遍后下次就不会再进行响应了呢?这是因为,每次get的时候都会调用dep.depend方法,dep.depend又会调用watcher的addDep方法,在该方法中对这些值进行了保存(即:完成了订阅),同时调用dep.addSub将本次的watcher保存到dep中(即:完成收集),那么不需要订阅的自然需要去除
拦截后做了什么
我们在分析cleanupDeps时实际上已经大致说了拦截后做的事情,那就是去完成watch的收集保存到dep的subs上,以便于在设置key的时候能向watcher进行广播,同时完成对dep的订阅保存到watcher的deps 、 newDeps 、 depIds 、 newDepIds 上,以便在适当的时机取消对dep的订阅
