JS 代理模式的一些应用

23 阅读2分钟

定义

代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。

代理模式的关键所在就是:当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对象,替身对象作出一些请求后再把请求转接给本体对象

作用:

  1. 保护代理: 在代理模式中,替身对象能做到过滤一些对本体不合理的请求时,这种代理就叫保护代理
  2. 虚拟代理:将一些代价昂贵的操作放置在代理对象中,待到机会合适时再进行,这种代理就叫虚拟代理

代理模式实现图片懒加载

不用代理实现

// 不用代理实现图片懒加载
var myImage = (function(){
  var imgNode = document.createElement('img');
  document.body.appendChild(imgNode);
  var img = new Image();
  img.onload = function() {
    imgNode.src = img.src;
  }
  return {
    setSrc: function(src) {
      imgNode.src = 'file:///C:/Users/admin/Desktop/mask/img/7.jpg'
      img.src = src;
    }
  }
})()
myImage.setSrc('https://img1.sycdn.imooc.com/5c09123400014ba418720632.jpg')

用代理实现图片懒加载

// 用代理实现图片懒加载
var myImage = (function(){
  var image = document.createElement('img');
  document.body.appendChild(image);
  return {
    setSrc: function(src) {
      image.src = src;
    }
  }
})();

var proxyImage = (function(){
  var img = new Image();
  img.onload = function() {
    myImage.setSrc(this.src);
  }
  return {
    setSrc: function(src) {
      myImage.setSrc('file:///C:/Users/admin/Desktop/mask/img/7.jpg');
      img.src = src;
    }
  }
})()
proxyImage.setSrc('https://img1.sycdn.imooc.com/5c09123400014ba418720632.jpg');

缓存代理

TIP

缓存代理可以为一些开销大的运算结果提供暂时的存储,在下次运算时,如果传递进来的参数跟之前一样,则可以直接返回前面存储的运算结果。

// 缓存代理:计算乘积
var mult = function() {
  console.log('开始计算乘积');
  var sum = 1;
  for(var i=0;i<arguments.length;i++) {
    sum = sum * arguments[i];
  }
  return sum;
}
var proxyMult = (function(){
  var cache = {};
  return function() {
    var args = Array.prototype.join.call(arguments,',');
    if(cache.hasOwnProperty(args)) {
      return cache[args];
    }
    return cache[args] = mult.apply(this,arguments)
  }
})()
console.log(proxyMult(1,2,3,4)); // 输出:开始计算乘积 24
console.log(proxyMult(1,2,3,4)); // 输出24

举一反三代理工厂

// 代理工厂(累加和乘积)
var mult = function() {
  console.log('开始计算乘积')
  var sum = 1;
  for (let index = 0; index < arguments.length; index++) {
    sum = sum * arguments[index]
  }
  return sum;
}
var plus = function() {
  console.log('开始计算累加')
  var sum = 0;
  for (let index = 0; index < arguments.length; index++) {
    sum = sum + arguments[index]
  }
  return sum;
}
var createProxyFactory = function(fn) {
  var cache = {};
  return function() {
    var args = Array.prototype.join.call(arguments,',');
    if(cache.hasOwnProperty(args)) {
      return cache[args]
    }
    return cache[args] = fn.apply(this,arguments);
  }
}
var proxyMult = createProxyFactory(mult);
var proxyPlus = createProxyFactory(plus);

console.log(proxyMult(1,2,3,4)); // 输出:开始计算乘积 24
console.log(proxyMult(1,2,3,4)); // 输出: 24
console.log(proxyPlus(3,4,5,6)); // 输出:开始计算累加 18
console.log(proxyPlus(3,4,5,6)); // 输出 18