处置惩罚上个使命的题目
上个使命抛出了两个题目,一个是在初始化一个实例的时刻假如传一个比较深的对象会被打平。把each
和convert
做出了一些修正:
each()
:
each(obj, parents = []) {
Object.keys(obj).forEach(key => {
this.convert(key, obj[key], parents)
})
}
convert()
:
convert(key, value, parents) {
...
// 推断传入的 value 是不是一个对象
// 假如是一个对象的话,就在挪用 each 函数
if (Object.prototype.toString.call(value) === '[object Object]') {
that.setData = value
that.each(value, [...parents, key])
that.setData = null
}
...
}
上面代码多了一个parents
,这个是用来完成这个使命的功用,也就是事宜冒泡而用的。
完成深层次数据变化怎样逐层往上流传
进修过 dom 的同砚都晓得,给一个元素绑定一个事宜,这个元素的子元素触发这个事宜,也会一样会触发它的一切父元素一样的事宜。
上面用parents
来存储比较深的对象,每一个对象的父的 key 值,在 setter 函数内里一样做出一些修正:
...
Object.defineProperty(this.setData || this.data, key, {
set: function (newValue) {
...
// parents 存的是上一级 key
// 轮回 parents 完成逐层往上流传
parents.forEach(item => {
that.emit(item, that.data[item])
})
...
}
})
...
别的一个题目
完成了深层次数据变化怎样逐层往上流传的功用后,发明一个题目。假如失事传入一个如许的对象:
let app = new Observer({
name: {
a: 1,
b: {
c: 2
}
}
})
试着输出app.data
的值发明:
{
b: {
c: 2
},
name: {
a: 1,
b: {
c: 2
}
}
}
由于我们在convert()
函数内里完成深度对象处置惩罚有一些题目,只需要在增加一个推断就能够了:
convert(key, value, parents) {
...
// parents 里有上级的 key 值,然则 setData 为 null 则直接跳出函数
if (parents.length && !this.setData) {
return
}
...
}