使用者和目标类出现权限和安全问题,无法直接访问,可以使用代理
场景
网页事件代理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="div1" style="background-color: aqua;width: 200px;height: 200px;">
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<a href="#">a5</a>
</div>
<script src="https://cdn.bootcss.com/jquery/3.5.0/jquery.js"></script>
<script>
var div1 = document.getElementById('div1');
div1.addEventListener('click', function(e) {
var target = e.target;
if (target.nodeName === 'A') {
console.log(target.innerHTML);
}
})
</script>
</body>
</html>
jQuery $.proxy
$('div1').click(function() {
//this 符合期望
$(this).hide();
});
$('div1').click(function() {
setTimeout(function() {
//this不符合期望
$(this).hide();
}, 1000)
});
//可以用如下方式解决
$('div1').click(function() {
let _this = this
setTimeout(() => {
//_this不符合期望
$(_this).hide();
}, 1000);
});
//但推荐使用$.proxy解决,这样就少定义一个变量
$('#div1').click(function() {
setTimeout($.proxy(function() {
$(this).hide();
}, this), 1000)
})
es6 Proxy
//明星
let star = {
name: '郑爽',
age: '24',
phone: '18966881234'
};
//经纪人
let agent = new Proxy(star, {
get: function(target, key) {
if (key === 'phone') {
//返回经纪人自己的手机号
return '15612348899';
}
if (key === 'price') {
//明星不报价,经纪人报价
return 120000;
}
return target[key];
},
set: function(target, key, val) {
if (key === 'customPrice') {
if (val < 100000) {
throw new Error('价格过低')
} else {
target[key] = val
return true;
}
}
}
})
console.log(agent.name);
console.log(agent.phone);
console.log(agent.price);
agent.customPrice = 10; //报错价格过低
设计原则
- 代理类和目标类分离,隔离开目标类和使用者
- 符合开闭原则
代理模式 vs 适配器模式
- 适配器模式:提供一个不同的接口(如不同版本的插头)
- 代理模式:提供一模一样的接口
代理模式 vs 装饰器模式
- 装饰器模式: 扩展功能,原有功能不变且可直接使用,aop原理
- 代理模式:显示原有功能,但是经过限制之后的
网友评论