Open liam61 opened 5 years ago
冒昧的说一句哈 ,看了下题目,如果按照原题目的话,感觉这个您这个有一点点小问题 就是
const data = new Observer({ a: 1, b: 2 });
这句之后,直接访问data.a
和data.b
应该是能够得到值的。
题目:
const data = new Observer({ a: 1 });
console.log(data.a); // 1 <---这里
但是您这个在构造函数中没有把{ a: 1, b: 2 }
的属性赋值给实例 直接访问data.a/b
就是undefined。
参照了您的思路,我自己也写了一个,感觉也有点问题。有什么不对的地方欢迎指出。
class Observer {
constructor(data){
this.data = data;
let keys = Object.keys(data);
this.observer = {};//调用了$on 的对象的属性
for(let key of keys){
Object.defineProperty(this,key,{
set(val){
this.$emit(key,this.data[key],val);
this.data[key] = val;
},
get(){
return this.data[key];
}
})
}
}
$on(name,callBack) {
if(!this.observer[name]){
this.observer[name] = callBack;
}
}
$emit(name,...args){
if(this.observer[name]){
this.observer[name](...args);
return;
}
return;
}
}
let data = new Observer({a:1,b:2});
console.log(data.a);//1
data.$on('a',(newVal,oldVal)=>{
console.log(`newValue:${newVal},oldValue:${oldVal}`);
});
data.a = 2;//newValue:1,oldValue2
data.b = 4;
console.log(data.b);//4
data.$on('b',(newVal,oldVal)=>{
console.log(`第一次:${newVal},第二次:${oldVal}`);
});
data.b = 5;//第一次:4,第二次:5
最后,非常感谢您的面经!
@anwenyao 你这样理解是对的,当时面试时我也是这个思路。写面经时想尽量简单些,就直接以 显示监听属性后才数据劫持 为基准,如 data.observe("a", callbackObj); data.b; // undefined
实现简易版 MVVM
关键词:Object.defineProperty