Open Twlig opened 2 years ago
Data通过Observer转换成getter/setter的形式来追踪变化(主要是Object.defineProperty)。
每个Observer中都有Dep实例,用于记录依赖(依赖就是Watcher)。
当外界通过Watcher读取数据时,会触发getter从而将Watcher添加到Observer的Dep实例中
当数据发生变化时,会触发setter,从而向Dep中的依赖(Watcher)发送通知
Watcher接受到通知后,会向外界发送通知,外界可能会触发试图更新或者执行某个回调函数
总结:在getter中收集依赖,在setter中触发依赖。
Object采用defineProperty通过getter/setter方法实现变化侦测。而Array没有,因此需要采用拦截器覆盖Array.prototype,在拦截器中定义push等方法新增变化侦测的代码。这样每次使用如push等数组操作时,执行的都是拦截器中定义的push方法,就可以实现变化侦测。
对于支持__proto__属性的浏览器采用拦截器方法覆盖原型
__proto__
arr.__proto__ = arrayMethods
对于不支持的浏览器,采用拦截器方法直接添加在数组实例上
arr.push = arrayMethods['push']
总结:在getter中收集依赖,在拦截器中触发依赖。
arr[0] = 1; arr.length = 0;
变化侦测
Object变化侦测
Data通过Observer转换成getter/setter的形式来追踪变化(主要是Object.defineProperty)。
每个Observer中都有Dep实例,用于记录依赖(依赖就是Watcher)。
当外界通过Watcher读取数据时,会触发getter从而将Watcher添加到Observer的Dep实例中
当数据发生变化时,会触发setter,从而向Dep中的依赖(Watcher)发送通知
Watcher接受到通知后,会向外界发送通知,外界可能会触发试图更新或者执行某个回调函数
总结:在getter中收集依赖,在setter中触发依赖。
Array变化侦测
Object采用defineProperty通过getter/setter方法实现变化侦测。而Array没有,因此需要采用拦截器覆盖Array.prototype,在拦截器中定义push等方法新增变化侦测的代码。这样每次使用如push等数组操作时,执行的都是拦截器中定义的push方法,就可以实现变化侦测。
对于支持
__proto__
属性的浏览器采用拦截器方法覆盖原型对于不支持的浏览器,采用拦截器方法直接添加在数组实例上
总结:在getter中收集依赖,在拦截器中触发依赖。