数据响应原理
Object.defineProperty
Vue2数据响应核心是使用了Object.defineProperty
方法(IE9+)在对象中定义属性或者修改属性,其中存取描述符很关键的就是get和set,提供给属性getter和setter方法
可以看下面例子,我们拦截到了数据获取以及设置
let obj ={
_name:'zhangsan'
}
/* 不支持ie8以下 */
/* Object.defineProperty 可以对对象的属性进行劫持 */
/* configurable 属性是否能被删除 默认为true,可以被删除 */
/* value就是对象属性的默认值 优先级比定义的优先级大 为设置默认值为undefined */
// Object.defineProperty(obj,'name',{
// get (){
// console.log('我在获取值');
// return this._name
// },
// set (v){
// console.log('我设置的值是',v);
// this._name = v
// }
// })
/* defineProperties多个拦截 */
Object.defineProperties(obj,{
name:{
configurable:false,
writable:false,
value:'baobao',
// get (){
// console.log('我在获取值');
// return this._name
// },
// set (v){
// console.log('我设置的值是',v);
// this._name = v
// }
}
})
document.write(obj.name + '<br/>')
obj.name = 'waner'
document.write(obj.name)
vue3原理proxy
通过Proxy,我们可以对设置代理的对象
上的一些操作进行拦截,外界对这个对象的各种操作,都要先通过这层拦截。(和defineProperty差不多)
let p ={
name:'zhansan',
age:30
}
let p2 = {
get(obj,key){
/* obj是源对象 key是对象属性 */
return obj[key]
},
set(obj,key,val){
/* obj是源对象 key是对象属性 val是属性的值*/
if(val!=this.name){
console.log('我把:'+obj[key]+'改成了:'+val);
obj[key] = val;
}
}
}
/* p代表源对象 p2代表需要操作的对象 */
let proxy1 = new Proxy(p,p2)
proxy1.name = '李四'
document.write(proxy1.name+'<br>')
document.write(proxy1.age+'<br>')
//页面打印 李四\30