1.如果设置新的值是一个对象的话,新设置的对象的属性是否能能继续响应 getter 和 setter
在上一步的基础上,我们直接设置data属性,是不会响应的,如:
app1.data.user = {a:1};
app1.data.user.a;
(function(){
window.Observer = function(data){
this.data=data;
this.makeObserver();
};
Observer.prototype.makeObserver = function(){
for(var key in this.data){
if(!this.data.hasOwnProperty(key))return;
var val = this.data[key];
if(typeof val === 'object'){
new Observer(val);
}
this.setObserver(val,key);
};
};
Observer.prototype.setObserver = function(val,key){
var that = this;
Object.defineProperty(that.data,key,{
enumerable: true,
configurable: true,
get:function(){
console.info("你访问了"+key);
return val;
},
set:function(newValue){
if(typeof newValue === 'object'){
new Observer(newValue);
};
console.info("你设置了"+key+",新的值为",newValue);
if(val === newValue)return;
val = newValue;
}
});
};
})()
//在set中,通过判断newValue是否是对象,来设置新对象的属性;
var app1 = new Observer({
user:{
ha:1
}
});
app1.data.user={
name:2
};
app1.data.user.name=3;
/*
输出:
你设置了user,新的值为 Object {}
你访问了user
你设置了name,新的值为 3
*/
2.数据改变时,需要回调函数
通过原型上建立一个watchArr对象,保存监听属性和回调函数,在set触发时执行
(function(){
window.Observer = function(data){
this.data=data;
this.makeObserver();
};
//监听对象
Observer.prototype.watchArr = {};
Observer.prototype.makeObserver = function(){
for(var key in this.data){
if(!this.data.hasOwnProperty(key))return;
var val = this.data[key];
if(typeof val === 'object'){
new Observer(val);
}
this.setObserver(val,key);
};
};
Observer.prototype.setObserver = function(val,key){
var that = this;
Object.defineProperty(that.data,key,{
enumerable: true,
configurable: true,
get:function(){
console.info("你访问了"+key);
return val;
},
set:function(newValue){
if(typeof newValue === 'object'){
new Observer(newValue);
};
console.info("你设置了"+key+",新的值为",newValue);
if(val === newValue)return;
if(that.watchArr[key]){
//如果监听对象对应key存在,则执行回调
for(var i = 0;i<that.watchArr[key].length;i++){
that.watchArr[key][i](newValue,val);
}
}
val = newValue;
}
});
};
//监听函数
Observer.prototype.$watch = function(key,fn){
if(!this.watchArr[key]){
this.watchArr[key]=[];
};
this.watchArr[key].push(fn);
};
return this;
})()
var app1 = new Observer({
user:{
info:1
},
age:10
});
app1.data.user={
name:2
};
app1.$watch('name', function(name,oldname) {
console.log(`我的名字${oldname}变了,现在已经是:${name}`)
}).$watch('age', function(age,oldage) {
console.log(`我的年龄${oldage}变了,现在已经是:${age}`)
});
app1.data.user.name=3;
app1.data.age=33;
/*
输出为:
你设置了user,新的值为 Object {}
你访问了user
你设置了name,新的值为 3
我的名字2变了,现在已经是:3
你设置了age,新的值为 33
我的年龄10变了,现在已经是:33
*/