SOURCE

function proxys(data, observebal) {
	if (!data || typeof data !== 'object') {
		return;
	}
	Object.keys(data).forEach((key, index) => {
		let val = data[key];
		proxys(val, observebal);
		Object.defineProperty(data, key, {
			configurable: true,
			enumerable: true,

			get: function() {
				console.log('get~~~!');
				Observebal.observer && observebal.addObserver(Observebal.observer);
				return val;
			},
			set: function(newValue) {
				console.log('set~~~!');
				proxys(newValue, observebal);
				val = newValue;
				observebal.notify();
			},
		});
	});
}

class Observebal {
	constructor(data) {
		proxys(data, this);
		this.observerIds = {};
		this.observers = [];
	}

	addObserver(observer) {
    //保证不重复添加
		if (!this.observerIds.hasOwnProperty(observer.id)) {
			this.observers.push(observer);
			this.observerIds[observer.id] = observer;
		}
	}
	notify() {
		this.observers.forEach((observer, index) => {
			observer.update();
		});
	}
}
//全局方法
Observebal.observer = null;
var globalObserverId = 0;
/*
	可以把vm理解为一个特殊对象,它具有跟对象相同的行为,但是还有一些扩展
	this.$expr = expr; 
*/
class Observer {
	constructor(vm, expr, cb) {
		this.$vm = vm;
		this.$expr = expr;
		this.$cb = cb;
    //设置索引id,保证全局唯一
		this.id = globalObserverId++;
		//加入队列
		this.getter(this.$vm, this.$expr);
	}
	update() {
		
		this.$cb(this.getter(this.$vm, this.$expr));
	}
	getter(vm, expr) {
		var exps = expr.split('.');
		//只要不进行ob.xxx的修改就可以了,指针重新覆盖
		let obj = vm;
		for (var i = 0, len = exps.length; i < len; i++) {
			if (!obj) return;
			obj = obj[exps[i]];
		}
		return obj;
	}
}
let model = { a: 1, b: 2 };
let observal = new Observebal(model);
//监听a属性变化
Observebal.observer = new Observer(model, 'a', value => {
	console.log('observer1', value);
});
//监听b属性变化
Observebal.observer = new Observer(model, 'b', value => {
	console.log('observer2', value);
});
 
 
model.a = 22222;
console 命令行工具 X clear

                    
>
console