设计模式之代理模式

haiweilian2021-01-17前端JavaScriptDesignPattern

定义

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

实现

当不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对象。

应用

虚拟代理

虚拟代理形式:某一个花销很大的操作,可以通过虚拟代理的方式延迟到这种需要它的时候才去创建执行。

函数防抖:如果短时间内大量触发同一事件,只会执行一次函数。

function debounce(fn, delay) {
  let timer = null;

  return function () {
    let arg = arguments;

    // 每次操作时,清除上传的定时器
    clearTimeout(timer);
    timer = null;

    // 定义新的定时器,一段时间后进行操作
    timer = setTimeout(function () {
      fn.apply(this, arg);
    }, delay);
  };
}

let count = 0;
let handerCount = function () {
  count++;
};

// 代理原始函数
let debounceCount = debounce(handerCount, 500);

// 开始频繁操作,数字不会变
let timer = setInterval(() => {
  debounceCount();
  console.log(count);
}, 100);

// 停止频繁操作,500ms 后数字变化
setTimeout(() => {
  clearInterval(timer);
  setTimeout(() => {
    console.log(count);
  }, 500);
}, 2000);

函数节流:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效

function throttle(fn, delay) {
  let timer = null;

  return function () {
    let arg = arguments;

    // 如果上次执行的时间间隔未到,不执行下一次。
    if (timer) {
      return;
    }

    timer = setTimeout(function () {
      fn.apply(this, arg);
      clearTimeout(timer);
      timer = null;
    }, delay);
  };
}

let count = 0;
let handerCount = function () {
  count++;
};

// 代理原始函数
let throttleCount = throttle(handerCount, 500);

// 开始频繁操作,间隔 500ms 数字才会变
let timer = setInterval(() => {
  throttleCount();
  console.log(count);
}, 100);

缓存代理

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

// 乘积:脑补是一个很复杂的预算
let mult = function () {
  console.log("mult...");
  let a = 1;
  for (let i = 0; i < arguments.length; i++) {
    a = a * arguments[i];
  }
  return a;
};

// 加和:脑补是一个很复杂的预算
let plus = function () {
  console.log("plus...");
  let a = 1;
  for (let i = 0; i < arguments.length; i++) {
    a = a + arguments[i];
  }
  return a;
};

// 创建缓存代理的工厂
let createProxyFactory = function (fn) {
  let cache = {};
  return function () {
    // 以参数为 key 把计算结果存起来,如果存在就直接返回
    let args = Array.from(arguments).join(",");
    if (args in cache) {
      return cache[args];
    }
    return (cache[args] = fn.apply(this, arguments));
  };
};

let proxyMult = createProxyFactory(mult);
let proxyPlus = createProxyFactory(plus);
console.log(proxyMult(1, 2, 3, 4, 5));
console.log(proxyMult(1, 2, 3, 4, 5));
console.log(proxyPlus(1, 2, 3, 4, 5));
console.log(proxyPlus(1, 2, 3, 4, 5));
// mult...
// 120
// 120
// plus...
// 16
// 16
最后更新时间 11/8/2023, 10:03:21 AM
ON THIS PAGE