处置惩罚深度对象
问题有个请求是假如传入的对象是比较深的对象,也就是 value 能够能是别的一个新的对象,也是要给谁人对象的属性加上 getter 和 setter 的,我的做法就是推断每个值是不是是对象,然后在做一次递归处置惩罚。
each(obj) {
Object.keys(obj).forEach(key => {
// 假如值是一个对象的话
if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
// 递归本身
this.each(obj[key])
} else {
this.convert(key, obj[key])
}
})
}
这里用了Object.prototype.toString.call()
来推断值是什么范例,由于运用typeof
的话,object、array 和 null 都邑返回 object,不是我想要的效果。
完成 $watch
问题另有别的一个请求就是完成$watch
的功用,用过 Vue 的同砚都晓得,我们能够用这个函数去监听一个值的变化,而且传入一个回调函数,假如值发生变话的话,就实行回调函数。
在constructor
中增加一个用来存储回调函数的变量:
...
this.watchProperties = {}
...
完成$watch
和emit
函数:
存储 watch 的回调函数做法我是用一个对象去处置惩罚的,key 为属性名,value 则是回调函数。
$watch(name, fn) {
this.watchProperties[name] = fn
}
emit(name, val) {
if (this.watchProperties[name] && typeof this.watchProperties[name] === 'function') {
this.watchProperties[name](val)
}
}
在convert
中增加:
convert(key, value) {
...
Object.defineProperty(this.setData || this.data, key, {
...
set: function (newValue) {
...
// 挪用 emit 实行 watchProperties 里的回调函数
// key 为属性名
// newValue 为新设置的值
that.emit(key, newValue)
...
}
})
}
末了一步,暴露$watch
要领:
constructor(json) {
...
return {
...
// 这里要注意,修正一下高低文的环境
$watch: this.$watch.bind(this)
}
}
这里须要运用bind
去修正实行的时刻高低的环境,不然无法访问watchProperties
。
还没完成的功用
$watch
函数不能够监听比较深的对象的属性。新建一个示例的时刻,假如传入一个深对象,会被打平:
let app = new Observer({ name: { a: 1, b: 2 } }) console.log(app.data) // 会输出 /* [object Object] { a: 1, b: 2 } */