起源:在 Vue 的数据绑定中会对一个对象属性的变化进行监听,并且通过依赖收集做出相应的视图更新等等。
问题:一个对象所有类型的属性变化都能被监听到吗?
之前用 Object.defineProperty通过对象的 getter/setter简单的实现了对象属性变化的监听,并且去通过依赖关系去做相应的依赖处理。
但是,这是存在问题的,尤其是当对象中某个属性的值是数组的时候。正如 Vue 文档所说:由于 JavaScript 的限制,Vue 无法检测到以下数组变动:当你使用索引直接设置一项时,例如 vm.items[indexOfItem] = newValue
当你修改数组长度时,例如 vm.items.length = newLength
从 Vue 源码中也可以看到确实是对数组做了特殊处理的。原因就是 ES5 及以下的版本无法做到对数组的完美继承 。
实验一下?
用之前写好的 observe做了一个简单的实验,如下:
import { observe } from './mvvm'
const data = {
name: 'Jiang',
userInfo: {
gender: 0
},
list: []
}
// 此处直接使用了前面写好的 getter/setterobserve(data)
data.name = 'Solo'
data.userInfo.gender = 1
data.list.push(1)