Skip to content
文档章节

懒加载函数

背景

在 Vue 中的 lazy 属性,返回一个方法,需要再次调用才能得到。

js
const effectFn = effect(() => obj.a + obj.b, { lazy: true });
const value = effectFn();

一个简单实现 lazy 如下

js
function lazy(fn) {
  return function lazyedFn(...args) {
    return fn.apply(this, args);
  };
}

function sum(a, b) {
  return a + b;
}

const lazySum = lazy(sum);
console.log(lazySum(1, 2));
console.log(lazySum(3, 4));

假如我们需要将页面中一个元素绑定 事件,不同浏览器不同方法,我们写一个通用的 addEvent 函数,来提供绑定方法。

  • elem 待绑定监听方法的对象
  • 监听方法,比如 click, holver 等
  • handler, 监听回调方法
html
<div id="app"></div>
<script>
  const elem = document.getElementById('app');

  addEvent(elem, type, handler);
</script>

代码

方法一: 正常的监听函数

缺点是: 每次执行 addEvent 都需要执行内部的 if 条件判断

js
var addEvent = function (elem, type, handler) {
  if (window.addEventListener) {
    return elem.addEventListener(type, handler);
  }

  if (window.attachEvent) {
    return elem.attachEvent('on' + type, handler);
  }
};

方法二: 提前判断浏览器类型,在代码加载判断

优点: 将判断类型提前到代码加载阶段执行,后续不需要再次执行 if 条件判断

缺点:如果没有调用 addEvent 方法,则该方法内部已经执行过一次了。

js
var addEvent = (function () {
  if (window.addEventListener) {
    return function (elem, type, handler) {
      elem.addEventListener(type, handler);
    };
  }

  if (window.attachEvent) {
    return function (elem, type, handler) {
      return elem.attachEvent('on' + type, handler);
    };
  }
})();

方法三: 惰性载入,在 addEvent 判断逻辑中重写 addEvent

优点: 第一次执行 addEvent 时指定了 addEvent 正确方法,后续不需要再次执行 if 判断了

js
var addEvent = function (elem, type, handler) {
  if (window.addEventListener) {
    addEvent = function (elem, type, handler) {
      elem.addEventListener(type, handler);
    };
  }

  if (window.attachEvent) {
    addEvent = function (elem, type, handler) {
      return elem.attachEvent('on' + type, handler);
    };
  }
};

参考

  1. JavaScript 设计模式与开发实践