JavaScript设计模式中有一种模式为代理模式
事件代理
事件代理是代理中最常见的一种,也是一道实打实的高频面试题,它的场景是一个父元素下有多个子元素。
考虑到事务具有冒泡性,当我们点击a标签的时候,会冒泡到父级。从而被监听。我们则只需要给父级绑定一个监听事件即可。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>事件代理</title>
</head>
<body>
<div id="father">
<a href="#">链接1号</a>
<a href="#">链接2号</a>
<a href="#">链接3号</a>
<a href="#">链接4号</a>
<a href="#">链接5号</a>
<a href="#">链接6号</a>
</div>
</body>
</html>
document.getElementById('father').addEventListener('click', function (e) {
e.preventDefault()
console.log(e.target.tagName == 'a' && alert(e.target.inerHTML))
})
虚拟代理
懒加载:它是针对突破加载时机的优化,在一些图片量比较大的网站,如:电商网站首页,团购网站,小游戏首页等。如果我们尝试在用户打开页面的时候就把所有的图片资源加载完毕,那么很有可能会造成白屏、卡顿。
预加载:它主要是为了避免网络不好的时候,或者图片过大时,页面长时间给用户留白的尴尬,常见的操作是先让这个img标签展示一个展位图,然后创建一个image实例,让这个image实例的src指向真实的目标图片地址。观察image实例的加载情况,当其对应的真实图片加载完毕后,就已经有了该图片的缓存内容,再将DOM上的img元素的src指向真实的目标图片地址,此时我们直接去取目标图片的缓存,所以会非常快。从展位图到目标图片的事件会非常小。
let myImage = function () {
let img = document.createElement('img');
document.body.appendChild(img);
return {
setSrc ( src ) {
img.src = src;
}
}
}();
proxyImage = function () {
let img = new Image;
img.onload = function () {
myImage.setSrc( this.src );
}
return {
setProxyImage( src ) {
myImage.setSrc("https://img.zcool.cn/community/01e2115d5d5c7da80120695c137bfb.jpg@1280w_1l_2o_100sh.jpg"); // 此处为加载 loading 图片,用来占位,本地图片(作者使用网络图片)
img.src = src;
}
}
}();
proxyImage.setProxyImage("https://img.zcool.cn/community/01a5d45543cd170000019ae94fc087.jpg")
缓存代理
在一些计算量较大的场景下,我们需要用空间换时间,例如:当我们需要用到某个已经计算过的值的时候,不想再耗时进行二次计算,而是希望能够从内存中去取现成的计算结果,这种场景下,就需要一个代理来帮我们进行计算的同时,缓存计算结果。
// addAll方法会对你传入的所有参数做求和操作
const addAll = function() {
console.log('进行了一次新计算')
let result = 0
const len = arguments.length
for(let i = 0; i < len; i++) {
result += arguments[i]
}
return result
}
// 为求和方法创建代理
const proxyAddAll = (function() {
// 求和结果的缓存池
const resultCache = {}
return function() {
// 将入参转化为一个唯一的入参字符串
const args = Array.prototype.join.call(arguments, ',')
// 检查本次入参是否有对应的计算结果
if(args in resultCache) {
// 如果有,则返回缓存池里现成的结果
return resultCache[args]
}
return resultCache[args] = addAll(...arguments)
}
})()
保护代理
就是使用proxy来进行代理,保护另一个对象的一部分东西。
// 珍爱网
const 珍爱网 () {
const BlindDate () { // 发起相亲请求
return '你们开始相亲了'
}
return {join}
}
const 系统 (你的信息) {
this.你的信息 = 你的信息
const 判断资格 = function () {
if( 你的信息.年龄 < 20){
return "年龄不够资格,不允许相亲"
}else{
珍爱网().BlindDate()
}
}
return 判断资格
}
console.log(系统({姓名:小孩子,年龄:19});