动态数据绑定的三个难点:
对象深度问题
设置新对象是否能够继续响应getter 和 setter
考虑传递回调函数
本文的目的
在实践中使用递归思想
了解设计模式中的“发布-订阅模式”
三大难点
如果传入参数对象是一个“比较深”的对象(也就是其属性值也可能是对象),那该怎么办呢?举个例子。
// 一个“比较深”的对象:某些属性的值也是一个对象
let obj = {
a: 1,
b: 2,
c: {
d: 3,
e: 4
}
}
如果设置新的值是一个对象的话,新设置的对象的属性是否能能继续响应 getter 和 setter。举个例子。
// 一个“比较深”的对象:某些属性的值也是一个对象
let app1 = new Observer({
name: 'youngwind',
age: 25
});
app1.data.name = {
lastName: 'liang',
firstName: 'shaofeng'
};
app1.data.name.lastName;
// 这里还需要输出 '你访问了 lastName '
app1.data.name.firstName = 'lalala';
// 这里还需要输出 '你设置了firstName, 新的值为 lalala'
考虑传递回调函数。在实际应用中,当特定数据发生改变的时候,我们是希望做一些特定的事情的,而不是每一次都只能打印出一些信息。所以,我们需要支持传入回调函数的功能。举个例子。
let app1 = new Observer({
name: 'youngwind',
age: 25
});
// 你需要实现 $watch 这个 API
app1.$watch('age', function(age) {
console.log(`我的年纪变了,现在已经是:${age}岁了`)
});
app1.data.age = 100; // 输出:'我的年纪变了,现在已经是100岁了'
解决方法
对象深度问题解决方法
walk(obj){
let val;
for(let key in obj){
// 这里为什么要用hasOwnProperty进行过滤呢?
// 因为for...in 循环会把对象原型链上的所有可枚举属性都循环出来
// 而我们想要的仅仅是这个对象本身拥有的属性,所以要这么做。
if(obj.hasOwnProperty(key)){
val = obj[key];
//第一大难题:初始化深对象解决问题 这里进行判断,如果还没有遍历到最底层,继续new Observer
if(typeof val === 'object'){
new Observer(data)
}
this.convert(key,val);
}
}
}
使用递归的方式 . 利用 typeof 来检查 val 是否是 object 对象 ,如果是则进行递归,检查其子属性...递归..
设置新对象是否能够继续响应getter 和 setter
set: function (valnew) {
self.watch[key](valnew) // 回调监听 取代下面那条语句
//console.log(`你设置了 ${key}, 新的值为${valnew}`);
if (typeof newVal === 'object') {
new Observer(valnew);
}
if (valnew === val) return;
val = valnew
}
同第一个难点,在 setter 处,判断改变后的属性值是否是对象 如果是对象 则再重新new 一个Observer出来
考虑传递回调函数
$watch(key,callback){
this.watch[key] = callback;
}
仿照 JavaScript 设计模式 发布-订阅模式 来写一个进行 setter 时,触发函数
在线学习参考资料
更多设计模式相关的资料强烈推荐曾探所著《JavaScript设计模式与开发实践》
上篇文章Vue 动态数据绑定(一)
更多内容可以订阅本人微信公众号,一起开启前端小白进阶的世界!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。