一共涉及两个对象内存空间
一个是原data、一个是Vue加工(劫持)后的data
首先Vue拿到原data后作为参数传入一个构造函数中
然后以difineProperty代理原data到自身实例obs中,即this
然后将_data = data = obs
此时原data对象已经成为了一个匿名对象
但地址已经传递到obs内部了所以并不影响引用
所以最后读取data实际上是在读取obs,而obs代理的是原data
(Vue还有很多例如深度监视的代码、在set调用更新DOM的代码、将data属性直接放到vm实例上等)
let data = {name:'王强',age:18
}const obs = new Observer(data);
let vm = {}vm._data = data = obs;function Observer(obj) {const keys = Object.keys(obj);keys.forEach((k)=>{Object.defineProperty(this,k,{get(){return obj[k];},set(val){obj[k] = val;}})})
}
对象添加属性用Vue.set()
数组用会修改原数组的7个方法(Vue已重新包装,添加了更新DOM的代码):push、unShilft、pop、shilft、splice、reverse、sort
(另提一嘴,字符串的所有方法都不会改变原字符串)