一共涉及两个对象内存空间
一个是原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
(另提一嘴,字符串的所有方法都不会改变原字符串)