什么是惰性函数

我的理解:一个函数无论执行多少次都会返回第一次执行的结果。

实现

例子:写一个 foo 函数,这个函数返回首次执行的结果

方法一

  1. let t;
  2. function foo() {
  3. if(t) return t;
  4. t = new Date();
  5. return t;
  6. }

问题:一是使用了全局变量,二是每次调用 foo 都需再判断一次。

方法二

闭包解决全局变量

  1. const foo = (function() {
  2. let t;
  3. return function() {
  4. if(t) return t;
  5. t = new Date();
  6. return t;
  7. }
  8. })();

还是每一次都执行都需要判断一次。

方法三

不使用闭包

  1. function foo() {
  2. if(foo.t) return foo.t;
  3. foo.t = new Date();
  4. return foo.t;
  5. }

方法四

惰性函数

  1. var foo = function() {
  2. var t = new Date();
  3. foo = function() {
  4. return t;
  5. };
  6. return foo();
  7. }

应用

为了兼容现代浏览器和 IE 浏览器,我们需要对浏览器进行一些兼容性判断。

常见的 dom 节点添加事件的函数。

  1. function addEvent (type, element, fun) {
  2. if (element.addEventListener) {
  3. element.addEventListener(type, fun, false);
  4. }
  5. else if(element.attachEvent){
  6. element.attachEvent('on' + type, fun);
  7. }
  8. else{
  9. element['on' + type] = fun;
  10. }
  11. }

每次判断的时候都需要执行一遍 if else 判断。

使用惰性求值

第一种实现是在事件函数第一次调用时,对函数本身进行二次处理,该函数会被覆盖为符合条件分支条件的函数,这样对原函数的调用就不用再经过 if else 分支了。

  1. function addEvent (type, element, fun) {
  2. if (element.addEventListener) {
  3. addEvent = function (type, element, fun) {
  4. element.addEventListener(type, fun, false);
  5. }
  6. }
  7. else if(element.attachEvent){
  8. addEvent = function (type, element, fun) {
  9. element.attachEvent('on' + type, fun);
  10. }
  11. }
  12. else{
  13. addEvent = function (type, element, fun) {
  14. element['on' + type] = fun;
  15. }
  16. }
  17. return addEvent(type, element, fun);
  18. }

第二种实现是在声明函数时就指定适当的函数。

  1. const addEvent = (function () {
  2. if (document.addEventListener) {
  3. return function (type, element, fun) {
  4. element.addEventListener(type, fun, false);
  5. }
  6. }
  7. else if (document.attachEvent) {
  8. return function (type, element, fun) {
  9. element.attachEvent('on' + type, fun);
  10. }
  11. }
  12. else {
  13. return function (type, element, fun) {
  14. element['on' + type] = fun;
  15. }
  16. }
  17. })();

参考:

[1] Javascript 专题之惰性函数
[2] 8.JavaScript函数惰性载入