JavaScript代理模式之四大代理

简介: JavaScript代理模式之四大代理

在JavaScript设计模式中有一种模式为代理模式,但是在代理模式之下,还有我们一般不了解的四种模式。来一起温故而知新,看看有哪些是你不清楚的模式。


事件代理


事件代理是代理中最常见的一种,也是一道实打实的高频面试题,它的场景是一个父元素下有多个子元素。


<!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>

我们的需求是每点击一个a标签,都可以弹出”一句话“的提示,比如点击第一个a,我们弹出 链接 1号这样的操作。


老的做法,使用循环绑定事件

const aNodes = document.getElementById('father').getElementsByTagName('a')
const aLength = aNodes.length
aLength.forEach((ele,index) =>{
    // 添加监听事件
    aNodes[i].addEventListener('click', function (a) {
      e.preventDefault()
      alert(`我是${aNodes[i].innerText`)      
    })
}}

缺点:我们需要循环给安装六个监听函数,,如果a标签更多,那么性能消耗会更大。


新的做法,事件代理做法


考虑到事务具有冒泡性,当我们点击a标签的时候,会冒泡到父级。从而被监听。我们则只需要给父级绑定一个监听事件即可。

<div>
    <button id='open'>打开弹框</button>
    <button id='close'>关闭弹框</button>
</div>
document.getElementById('box').addEventListener('click', function (e) {
    e.preventDefault()
    console.log(e.target.tagName == 'BUTTON' && alert(e.target.inerHTML))
})

虚拟代理


懒加载:它是针对突破加载时机的优化,在一些图片量比较大的网站,如:电商网站首页,团购网站,小游戏首页等。如果我们尝试在用户打开页面的时候就把所有的图片资源加载完毕,那么很有可能会造成白屏、卡顿。


所以我们的做法一般是先占位,后加载。 在元素露出之前,我们先给他一个div占位,当它滚动到可视化区域的时候,再去加载真实的图片资源,这样既减轻了性能压力,又保住了用户体验。


除过懒加载外,还有一种操作叫做预加载。它主要是为了避免网络不好的时候,或者图片过大时,页面长时间给用户留白的尴尬,常见的操作是先让这个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)
    }
})()

2ad4330834ad46b6a0f132682780178f.png


结果如上,第二次速度比第一次更快。直接从缓存中取出。


保护代理


这个其实大家大多数都知道,就是使用proxy来进行代理,保护另一个对象的一部分东西。例如,一个19岁的小孩子要去相亲,这时候相亲网的系统中需要有保护,20岁以下的不允许相亲。所以,保护代理这不就出来了。

例如:


// 珍爱网
const 珍爱网 () {
    const BlindDate () { // 发起相亲请求
        return '你们开始相亲了'
    }
    return {join}
}
const 系统 (你的信息) {
    this.你的信息 = 你的信息
    const 判断资格 = function () {
        if( 你的信息.年龄  < 20){
            return "年龄不够资格,不允许相亲"        
        }else{
               珍爱网().BlindDate()     
        }
    }
    return 判断资格
}
console.log(系统({姓名:小孩子,年龄:19});



目录
相关文章
|
6月前
|
API
在vite.config.js 配置代理
在vite.config.js 配置代理
646 2
|
6月前
|
JavaScript 前端开发 定位技术
JavaScript 中如何代理 Set(集合) 和 Map(映射)
JavaScript 中如何代理 Set(集合) 和 Map(映射)
105 0
|
6月前
|
JSON JavaScript 前端开发
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)(下)
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
88 2
|
JavaScript 前端开发
JS 下载 URL 链接文件(点击按钮、点击a标签、支持代理与非代理下载)
JS 下载 URL 链接文件(点击按钮、点击a标签、支持代理与非代理下载)
559 0
|
缓存 JavaScript 应用服务中间件
Nginx+Tomcat代理环境下JS无法完全加载问题
Nginx+Tomcat代理环境下JS无法完全加载问题
181 0
|
3月前
|
编解码 JavaScript 前端开发
JS逆向浏览器脱环境专题:事件学习和编写、DOM和BOM结构、指纹验证排查、代理自吐环境通杀环境检测、脱环境框架、脱环境插件解决
JS逆向浏览器脱环境专题:事件学习和编写、DOM和BOM结构、指纹验证排查、代理自吐环境通杀环境检测、脱环境框架、脱环境插件解决
98 1
|
4月前
|
前端开发 JavaScript Linux
若依修改之后,无法访问前端项目如何解决,只能访问后端的接口,我的接口8083,端不显示咋解决?在vue.config.js文件中的映射路径要跟后端匹配,到软件商店里找到Ngnix配置代理,设80不用加
若依修改之后,无法访问前端项目如何解决,只能访问后端的接口,我的接口8083,端不显示咋解决?在vue.config.js文件中的映射路径要跟后端匹配,到软件商店里找到Ngnix配置代理,设80不用加
|
4月前
|
设计模式 JavaScript 前端开发
精读JavaScript中的代理(Proxy)与反射(Reflect)
精读JavaScript中的代理(Proxy)与反射(Reflect)
41 0
|
4月前
|
设计模式 缓存 JavaScript
js设计模式【详解】—— 代理模式
js设计模式【详解】—— 代理模式
31 0
|
6月前
|
JSON JavaScript 前端开发
vue2_vite.config.js的proxy跨域配置和nginx配置代理有啥区别?
vue2_vite.config.js的proxy跨域配置和nginx配置代理有啥区别?
199 1