观察者模式: 观察者模式是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
这里我们使用vue中的观察者模式作为例子(为了简洁,省略部分代码)
其中的数据走向如下图所示。
/* observer.ts */
import { defineReactive } from ‘./define-reactive‘;
import Dep from ‘./dep‘;
function def(obj: Object, key: string, val: any) {
Object.defineProperty(obj, key, {
value: val,
enumerable: false,
writable: true,
configurable: true
})
}
/**
* 重写设置__ob__对象
* 增加观察者模式
*/
export default class Observer {
value: any;
dep: Dep;
// 这里只演示值为对象情况
constructor (value: Object) {
this.value = value;
this.dep = new Dep();
def(value, ‘__ob__‘, this);
this.walk(value)
}
walk (obj: Object) {
const keys = Object.keys(obj);
for (let i = 0; i < keys.length; i++) {
defineReactive(obj, keys[i])
}
}
}
/* define-reactive.ts */
import Dep from ‘./dep‘;
/**
* 将可配置的对象设置成__ob__对象
* get方法和set方法添加观察者模式
*/
export function defineReactive (obj: Object, key: string, val?: any,) {
const dep = new Dep();
// 只设置可配置的对象
const property = Object.getOwnPropertyDescriptor(obj, key);
if (property && property.configurable === false) {
return
}
const getter = property && property.get;
if (!getter && arguments.length === 2) {
val = obj[key]
}
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
const value = getter ? getter.call(obj) : val;
/**
* 如果在某一个watcher的上下文调用到了这个对象
* 那么这个watcher订阅这个对象改变的消息
* 这个对象改变的时候watcher执行更新函数
*/
if (Dep.target) {
dep.depend();
}
return value
},
set: function reactiveSetter (newVal) {
const value = getter ? getter.