代理模式

2021-01-19  本文已影响0人  池鱼_故渊

代理模式

定义:为一个对象提供一个代用品和占位符,以便控制对它的访问

常用的虚拟代理模式:某个花销很大的操作,可以通过虚拟代理的方式延迟到需要创建的时候才去创建 (函数的节流防抖也是一种代理模式)
例如:使用虚拟代理实现图片的懒加载
图片的懒加载的方式:先通过一张 loading 图占位符,然后通过异步的方式加载图片,等待图片加载好,再把加载好的图片放到标签里面

var myImage = (function () {
  var imgNode = document.createElement("img");
  document.body.appendChild(imgNode);
  return {
    setSrc: function (src) {
      imgNode.src = src;
    },
  };
})();

var proxyImage = (function () {
  var img = new Image();
  img.onload = function () {
    myImage.setSrc(img.src);
  };
  return {
    setSrc: function (src) {
      img.src = src; // 当图片加载完成时会触发 上面的img.onload 然后替换掉图片
      myImage.setSrc("loading图片地址");
    },
  };
})();

proxyImage.setSrc("图片地址");

代理的意义是什么:单一职责原则(一个对象只有一个职责,如果一个对象担任过多的职责,那么这个对象将会不可控,代码就会变的很脆弱 )

再看一个例子:虚拟代理合并 HTTP(取自 js 设计模式与开发实践)


<body>
  <div id="wrapper">
    <input type="checkbox" id="1"></input>1
    <input type="checkbox" id="2"></input>2
    <input type="checkbox" id="3"></input>3
    <input type="checkbox" id="4"></input>4
    <input type="checkbox" id="5"></input>5
    <input type="checkbox" id="6"></input>6
    <input type="checkbox" id="7"></input>7
    <input type="checkbox" id="8"></input>8
    <input type="checkbox" id="9"></input>9
  </div>
</body>

<script type="text/javascript">
  // 模拟http请求
  var synchronousFile = function (id) {
    console.log('开始同步文件,id 为: ' + id);
  };

  var inputs = document.getElementsByTagName('input')
  var wrapper = document.getElementById('wrapper')
  wrapper.onclick = function (e) {
    if (e.target.tagName === 'INPUT' && e.target.checked) {
      proxySynchronousFile(e.target.id)
    }
  }
  var proxySynchronousFile = (function () {
    var cacheIds = [], // 缓存id
      timeId = 0 //定时器
    return function (id) {
      if (cacheIds.indexOf(id) < 0) {
        cacheIds.push(id)
      }
      clearTimeout(timeId)
      timeId = setTimeout(() => {
        synchronousFile(cacheIds.join(',')) //调用函数
        cacheIds = []
      }, 1000)
    }
  })()
</script>

通过代理缓存要发送的请求,最后统一发送请求
实际上上面的函数就是一个函数防抖(所以说防抖节流也是一种代理模式)
看过这几种模式是不是觉得设计模式也并不是很难懂的东西,但是如何使用设计模式,什么地方该用什么样的设计模式是需要一定的积累和应用的
一种大家几乎都使用过的代理模式:事件代理

<ul id="ul">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
</ul>
<script>
    let ul = document.querySelector('#ul')
    ul.addEventListener('click', (event) => {
        console.log(event.target);
    })
</script>

因为存在太多的 li,不可能每个都去绑定事件。这时候可以通过给父节点绑定一个事件,让父节点作为代理去拿到真实点击的节点。

上一篇下一篇

猜你喜欢

热点阅读