ES6 Proxy对象
使用ES6的Proxy对象实现一个简单的双向数据绑定
Proxy可以对一个对象的属性访问和设置进行拦截,并增加一些操作。
在设置对象的一个属性时,会自动设置元素的innerText,
当输入框按键抬起的时候,会触发事件,更改对象的属性,同时会触发Proxy的拦截,自动设置HTML元素的innerText属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="btn"></div>
<input id='input' />
</body>
<script>
const btn = document.querySelector('#btn');
const input = document.querySelector('#input');
let user = {
name:'Jack',
id:'1001',
}
user = new Proxy(user,{
set(obj,key,val){
console.log('obj:',obj);
console.log('key:',key);
console.log('val',val);
obj[key] = val;
if(key === 'name'){
btn.innerText = val;
input.value = val;
}
}
});
user.name = 'Tom';
console.log('user:',user);
btn.innerText = user.name;
let count = 1;
const timer = setInterval(() => {
user.name = user.name + '' + count++;
},1000);
setTimeout(() => {
// clearInterval(timer);
},5000);
input.addEventListener('keyup',(e) => {
user.name = input.value;
console.log(user);
})
</script>
</html>
对get(获取对象属性值)进行拦截
let user = {
name:"Jack",
id:"1001"
}
user = new Proxy(user,{
get(obj,key){
if(!(key in obj)){
return '出错了,对象上没有'+key+'这个属性';
}
if(key === 'id'){
return '不行,你不能访问'+key+'这个属性';
}
return '你可以访问'+key+'这个属性,属性值为:' + obj[key];
}
});
console.log(user.idd);
console.log(user.id);
console.log(user.name);
输出:
出错了,对象上没有idd这个属性
不行,你不能访问id这个属性
你可以访问name这个属性,属性值为:Jack
对set(设置对象属性值)进行拦截
let arr = [1,2,3];
arr = new Proxy(arr,{
set(obj,key,val){
console.log('obj:',obj);
console.log('key:',key);
console.log('val:',val);
if(typeof val === 'number'){
obj[key] = val;
return true;
}else{
throw new Error('错误,必须设置为number类型的值!!!');
return false;
}
}
});
arr.push(8888);
console.log('arr:',arr);
arr.push('1000');
console.log('arr:',arr);
输出:
obj: (3) [1, 2, 3]
key: 3
val: 8888
obj: (4) [1, 2, 3, 8888]
key: length
val: 4
arr: Proxy(Array) {0: 1, 1: 2, 2: 3, 3: 8888}
obj: (4) [1, 2, 3, 8888]
key: 4
val: 1000
Uncaught Error: 错误,必须设置为number类型的值!!!
at Object.set (Proxy.vue:17:19)
at Proxy.push ()
at setup (Proxy.vue:25:5)
at callWithErrorHandling (vue.js?v=2416ef04:1660:19)
at setupStatefulComponent (vue.js?v=2416ef04:9060:25)
at setupComponent (vue.js?v=2416ef04:9021:36)
at mountComponent (vue.js?v=2416ef04:7352:7)
at processComponent (vue.js?v=2416ef04:7318:9)
at patch (vue.js?v=2416ef04:6784:11)
at mountChildren (vue.js?v=2416ef04:7032:7)
对has(包含)进行拦截
let range = {
min:3,
max:10
}
range = new Proxy(range,{
has(obj,key){
return key >= 3 && key <= 10 ? true : false;
}
});
console.log(5 in range);
对ownKeys(遍历)进行访问
let user = {
name:'Jack',
id:'1001002',
_password:'ppppppp'
}
user = new Proxy(user,{
ownKeys(obj){
return Object.keys(obj).filter(key => !key.startsWith('_'));
}
});
console.log('Object.keys(user):',Object.keys(user));
for(let key in user){
console.log(key);
}
console.log('name' in user);
console.log('_password' in user);
原文链接:https://juejin.cn/post/7351624415317344271 作者:wangchongfire