理解惰性函数

先列个通过if判断执行的代码块:

creatXHR()

function createXHR(){
  if (typeof XMLHttpRequest != "undefined"){ // 首先检查内置的XHR
    return new XMLHttpRequest();
  } else if (typeof ActiveXObject != "undefined"){
    // 没有内置XHR就再测试有没有基于ActiveX的XHR
    if (typeof arguments.callee.activeXString != "string"){
      var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
                      "MSXML2.XMLHttp"],
          i,len;

      for (i=0,len=versions.length; i < len; i++){
        try {
          new ActiveXObject(versions[i]);
          arguments.callee.activeXString = versions[i];
          break
        } catch (ex){
          // 跳过
        }
      }
    }

    return new ActiveXObject(arguments.callee.activeXString);
  } else { // 都没有发现抛错
    throw new Error("No XHR object available.");
  }
}

这样通过大量if语句将执行引导到正确代码中,但如果浏览器支持内置XHR,它就是一直支持的,这种测试就变的没有必要。

即使只有一个if语句的代码也肯定比没有if语句的慢,所以如果if语句不必每次执行,代码可以运行的更快一些。

可以通过惰性载入来解决:惰性载入表示函数执行的分支仅会发生一次。

有两种实现惰性载入的方式:

1.在函数被调用时再处理函数

在第一次调用的过程中该函数会被覆盖为另外一个按合适方式执行的函数,这样任何对原函数的调用都不必再经过执行的分支了:

// 使用惰性载入重写
function createXHR(){
  if (typeof XMLHttpRequest != "undefined"){ // 首先检查内置的XHR
    createXHR = function(){
      return new XMLHttpRequest();
    };
  } else if (typeof ActiveXObject != "undefined"){
    createXHR = function(){
      if (typeof arguments.callee.activeXString != "string"){
        var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
                        "MSXML2.XMLHttp"],
            i,len;

        for (i=0,len=versions.length; i < len; i++){
          try {
            new ActiveXObject(versions[i]);
            arguments.callee.activeXString = versions[i];
            break
          } catch (ex){
            // 跳过
          }
        }
      }
    };

    return new ActiveXObject(arguments.callee.activeXString);
  } else { // 都没有发现抛错
    createXHR = function(){
      throw new Error("No XHR object available.");
    };
  }

  return createXHR(); // 再调用一下新赋的函数
}

2.在声明函数时就指定适当的函数

这样做在第一次调用函数时就不会损失性能了,但在代码首次加载时会损失一点性能:

// 创建一个匿名、自执行函数来确定应该使用哪一个函数实现。
var createXHR = (function(){
  if (typeof XMLHttpRequest != "undefined"){ // 首先检查内置的XHR
    return function(){
      return new XMLHttpRequest();
    };
  } else if (typeof ActiveXObject != "undefined"){
    return function(){
      if (typeof arguments.callee.activeXString != "string"){
        var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
                        "MSXML2.XMLHttp"],
            i,len;

        for (i=0,len=versions.length; i < len; i++){
          try {
            new ActiveXObject(versions[i]);
            arguments.callee.activeXString = versions[i];
            break
          } catch (ex){
            // 跳过
          }
        }
      }
    };

    return new ActiveXObject(arguments.callee.activeXString);
  } else { // 都没有发现抛错
    return function(){
      throw new Error("No XHR object available.");
    };
  }
})();

总结

惰性载入函数优点:只在执行分支代码时牺牲一点儿性能,避免重复执行不必要代码。

原文地址:https://www.cnblogs.com/hencins/p/10050558.html

时间: 2024-08-02 22:21:59

理解惰性函数的相关文章

JS 惰性函数 的简单案例

今天了解到一个新的名词叫惰性函数,在js中的重复计算可以省事很多 var add = function(a) { var e = a+a ; console.log("通道 1"); add = function(a) { console.log("通道 2") return e; }; return e; } alert(add(3)); // 通道1 弹出6 alert(add(5)); // 通道2 弹出6 alert(add(9)); // 通道2 弹出6

正确理解Python函数是第一类对象

正确理解 Python函数,能够帮助我们更好地理解 Python 装饰器.匿名函数(lambda).函数式编程等高阶技术. 函数(Function)作为程序语言中不可或缺的一部分,太稀松平常了.但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性.那到底什么是第一类对象呢? 函数是对象 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性

惰性函数——JS高级

原文地址:http://www.cnblogs.com/galenyip/p/4613430.html 我们先来看一下js的异步提交. XHR我们在原生的时候常常用到,因为常用到,我们更多把封装到了工具库中 先看下他最常用的实现 1 // 旧方法 2 3 function createXHR() { 4 var xhr; 5 try{ 6 xhr = new XMLHttpRequest(); 7 }catch(e) { 8 handleErr(e); 9 10 try { 11 xhr = n

惰性函数

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script> //惰性函数,即对function对象进行更改,但第二次才会执行该函数. function createXML(){ var xmlHttp; try{ //-------开始更改---- createXML = function(){ return

JavaScript惰性函数定义

函数是js世界的一等公民,js的动态性.易变性在函数的应用上,体现的淋漓尽致.做为参数,做为返回值等,正是函数这些特性,使得js开发变的有趣. 下面就阐述一下,js一个有趣的应用--惰性函数定义(Lazy Function Definition). 惰性载入表示函数执行的分支只会在函数第一次掉用的时候执行,在第一次调用过程中,该函数会被覆盖为另一个按照合适方式执行的函数,这样任何对原函数的调用就不用再经过执行的分支了. 下面我们看几个典型的例子: 1 function addEvent (typ

深入理解javascript函数系列第三篇

前面的话 函数是javascript中特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本文是深入理解javascript函数系列第三篇--属性和方法 属性 [length属性] 函数系列第二篇中介绍过,arguments对象的length属性表示实参个数,而函数的length属性则表示形参个数 function add(x,y){ console.log(arguments.length)//3 console.log(

理解fork()函数

学习 C 语言的进程概念时,会遇到 fork()函数.而遇到时要是有例子,会像下边的样子.执行后双输出.起初见到时,甚为难以理解. 我把见到的例子略作修改,以便于我理解这个函数涉及的进程概念. vim child_process.c    gcc child_process.c ./a.out 这里的显示表示运行在父进程中.[[email protected] chapter 7 进程控制]# 这个显示内容是在子进程中输出的. echo $? 3 ------------------------

More Effective C++----(24)理解虚拟函数、多继承、虚继承和RTTI所需的代价

Item M24:理解虚拟函数.多继承.虚继承和RTTI所需的代价 C++编译器们必须实现语言的每一个特性.这些实现的细节当然是由编译器来决定的,并且不同的编译器有不同的方法实现语言的特性.在多数情况下,你不用关心这些事情.然而有些特性的实现对对象大小和其成员函数执行速度有很大的影响,所以对于这些特性有一个基本的了解,知道编译器可能在背后做了些什么,就显得很重要.这种特性中最重要的例子是虚拟函数. 当调用一个虚拟函数时,被执行的代码必须与调用函数的对象的动态类型相一致:指向对象的指针或引用的类型

理解JavaScript函数参数

前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数. arguments javascript中的函数定义并未指定函数形参的类型,函数调用也未对传入的实参值做任何类型检查.实际上,javascript函数调用甚至不检查传入形参的个数 ? 1 2 3 4 5 6 7 function add(x){ return x+1; } console.log(add(1));//2 console