设计模式之代理模式

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

(0)
上一篇 2024年3月30日 上午10:38
下一篇 2024年3月30日 上午10:43

相关推荐

发表回复

登录后才能评论