惰性函数

惰性载入表示函数执行的分支只会在函数第一次掉用的时候执行,在第一次调用过程中,该函数会被覆盖为另一个按照合适方式执行的函数,这样任何对原函数的调用就不用再经过执行的分支了。

惰性函数相当于有记忆的功能一样,当它已经判断了一遍的话,第二遍就不会再判断了。

案例

  1. 现在要求写一个test函数,这个函数返回首次调用时的new Date().getTime(),注意是首次,而且不允许有全局变量的污染
  1. //一般会这样实现
  2. var test = (function () {
  3. var t = null;
  4. return function () {
  5. if (t) {
  6. return t;
  7. }
  8. t = new Date().getTime();
  9. return t;
  10. }
  11. })();
  12. console.log(test()); //1627462278021
  13. console.log(test()); //1627462278021
  14. setTimeout(function () {
  15. console.log(test()); //1627462278021
  16. }, 2000)

用惰性函数实现就是:

  1. var test = function () {
  2. var t = new Date().getTime();
  3. test = function () {
  4. return t;
  5. }
  6. return test();
  7. }
  8. console.log(test());
  9. console.log(test());
  10. console.log(test());
  11. console.log(test());
  1. 函数重构「闭包」判断环境只需要判断一次(函数库封装时判断环境)
  2. 分析怎么懒:每次都要判断是否兼容,实际上只要判断一次,后面都不用了
  3. 实现:函数重新赋值
  4. 原理:function 被全局作用域下的getCss占用,形成闭包
  1. // 惰性思想:懒,能够只执行一遍的,绝对不会执行第二遍「性能优化」
  2. // + getComputedStyle([Element])[ATTR] 获取当前元素所有经过浏览器计算的样式
  3. // + [Element].currentStyle[ATTR] IE6~8
  4. // 弊端:第一次执行,需要校验一下兼容性;但是后续每一次执行,都需要重新校验 “这个操作是多余的”...
  5. /* let getCss = function getCss(ele, attr) {
  6. if ('getComputedStyle' in window) {
  7. return window.getComputedStyle(ele)[attr];
  8. }
  9. return ele.currentStyle[attr];
  10. };
  11. console.log(getCss(box, 'width'));
  12. console.log(getCss(box, 'padding'));
  13. console.log(getCss(box, 'display')); */
  14. // 核心:函数重构「闭包」
  15. // 1. 不能用const, 因为后面要修改
  16. // 2. 匿名函数具名化这里不能用,因为不能修改
  17. let getCss = function (ele, attr) {
  18. // 根据是否兼容重新赋值,后面就不用判断了(懒)
  19. if ('getComputedStyle' in window) {
  20. getCss = function (ele, attr) {
  21. return window.getComputedStyle(ele)[attr];
  22. };
  23. } else {
  24. getCss = function (ele, attr) {
  25. return ele.currentStyle[attr];
  26. };
  27. }
  28. // 保证第一次也获取值
  29. return getCss(ele, attr);
  30. };
  31. console.log(getCss(box, 'width'));
  32. console.log(getCss(box, 'padding'));
  33. console.log(getCss(box, 'display'));