一、代理的作用
1. 拦截和监视外部对对象的访问
2. 降低函数或类的复杂度
3. 在复杂操作前对操作进行校验或对所需资源进行管理
二、 两种实现方法
Object.defineProperty数据劫持
let obj={
name: ''
}
Object.defineProperty(obj,'name',{
get(){
console.log('获取');
},
set(){
console.log('设置');
}
});
ES6中Proxy代理数据劫持
let obj={
a:1,
b:2
}
let p=new Proxy(obj,{
get(target, key, value){
if(key==="c") return "我是自定义的结果";
else return target[key];
},
set(target, key, value) {
if (value === 4) {
target[key] = '我是自定义的一个结果';
} else {
target[key] = value;
}
}
})
console.log(obj.a) // 1
console.log(obj.c) // undefined
console.log(p.a) // 1
console.log(p.c) // 我是自定义的一个结果
obj.name = '李白';
console.log(obj.name); // 李白
obj.age = 4;
console.log(obj.age); // 4
p.name = '李白';
console.log(p.name); // 李白
p.age = 4;
console.log(p.age); // 我是自定义的一个结果
三、Vue 2.0/3.0双向数据绑定实现方法
Object.defineProperty(2.0)
<body>
<lable>姓名:</lable> <span id="spanName"></span>
<br />
<input type="text" id="inpName">
<script>
let obj={
name:''
};
let newObj=JSON.parse(JSON.stringify(obj));
Object.defineProperty(obj,'name',{
get(){
return newObj.name;//准备新值来处理,深克隆来处理
},
set(val){
if(val==obj.name) return;
newObj.name=val;
observer();
}
});
function observer(){
spanName.innerHTML=obj.name;
inpName.value=obj.name;
};
observer();
setTimeout(()=>{
obj.name="hhhh";
},1000) ;
inpName.oninput=function(){
obj.name=this.value;
};
// 数据的更改影响视图
// 视图的更改如何影响数据呢?
</script>
</body>
- 存在的问题:
- 对原始数据需要进行克隆(深拷贝)
- 需要分别给对象中的每一个属性设置监听
Proxy(vue 3.0)
<body>
<lable>姓名:</lable> <span id="spanName"></span>
<br />
<input type="text" id="inpName">
<script>
let obj={ };
obj=new Proxy(obj,{
get(target,prop){ //obj==target prop==属性
return target[prop];
},
set(target,prop,value){
target[prop]=value;
observer();
}
});
function observer(){ //观察者(订阅者)
spanName.innerHTML=obj.name;
inpName.value=obj.name;
};
observer();
setTimeout(()=>{
obj.name="hhhh";
},1000) ;
inpName.oninput=function(){
obj.name=this.value;
};
</script>
</body>
</html>
from 珠峰培训