JS编程建议——72:惰性载入函数

建议72:惰性载入函数
惰性载入函数主要解决的问题也是兼容性,原理跟分支函数类似,下面是简单的示例。
var addEvent = function(el, type, handle) {

addEvent = el.addEventListener ? function(el, type, handle) {
    el.addEventListener(type, handle, false);
} : function(el, type, handle) {
    el.attachEvent("on" + type, handle);
};
//在第一次执行addEvent函数时,修改了addEvent函数之后,必须执行一次
addEvent(el, type, handle);

}
从代码上看,惰性载入函数也是在函数内部改变自身的一种方式,这样在重复执行的时候就不会再进行兼容性方面的检测了。
惰性载入表示函数执行的分支仅会发生一次,即第一次调用的时候。在第一次调用的过程中,该函数会被覆盖为另一个按合适方式执行的函数,这样任何对原函数的调用都不用再经过执行的分支了。其优点如下:
要执行的适当代码只有在实际调用函数时才执行。
尽管第一次调用该函数会因额外的第二个函数调用而稍微慢点,但后续的调用都会很快,因为避免了多重条件。
由于浏览器之间的行为差异,多数JavaScript代码包含了大量的if语句,将执行引导到正确的代码中。
在下面惰性载入的createXHR()中,if语句的每个分支都会为createXHR()变量赋值,有效覆盖了原有的函数,最后一步便是调用新赋函数。下次调用createXHR()的时候,就会直接调用被分配的函数,这样就不用再次执行if语句。
function createXHR() {

if( typeof XMLHttpRequest != 'undefined') {
    return new XMLHttpRequest();
} else if( typeof ActiveXObject != 'undefined') {
    if( typeof arguments.callee.activeXString != 'string') { ver
        versions = ["MSXML2.XMLHttp", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp.6.0"];
        for(var i = 0, len = versions.length; i < len; i++) {
            try {
                var xhr = new ActiveXObject(versions[i]);
                arguments.callee.activeXString = versions[i];
                return xhr;
            } catch(ex) {
                //跳过
            }
        }
    }
    return new ActiveXObject(arguments.callee.activeXString);
} else {
    throw new Error("No XHR object available.");
}

}
每一次调用createXHR()时都要对浏览器所支持的功能仔细检查,这样每次调用createXHR()时都要进行相同的测试就变得没有必要了。减少if语句使其不必每一次都执行,代码就会执行得快些。解决方案就是惰性载入的技巧。
function createXHR() {

if( typeof XMLHttpRequest != 'undefined') {
    createXHR = function() {
        return new XMLHttpRequest();
    };
} else if( typeof ActiveXObject != 'undefined') {
    createXHR = function() {
        if( typeof arguments.callee.activeXString != 'string') { ver
            versions=["MSXML2.XMLHttp","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp.6.0"];
            for(var i = 0, len = versions.length; i < len; i++) {
                try {
                    var xhr = new ActiveXObject(versions[i]);
                    arguments.callee.activeXString = versions[i];
                    return xhr;
                } catch(ex) {
                    //跳过
                }
            }
        }
        return new ActiveXObject(arguments.callee.activeXString);
    };
} else {
    createXHR = function() {
        throw new Error("No XHR object available.");
    };
}
return createXHR();

}
如前面所述,if语句的每一个分支都会为createXHR变量赋值,有效覆盖了原有函数。最后一步便是调用新赋函数,下次调用creatXHR()的时候就会直接调用被分配的函数,这样就不用再次执行if语句。

时间: 2024-10-09 22:48:56

JS编程建议——72:惰性载入函数的相关文章

JS编程建议——67:套用函数

建议67:套用函数套用是JavaScript函数一个很有趣的应用.所谓套用就是将函数与传递给它的参数相结合,产生一个新的函数.在函数式编程中,函数本身也是一个值,这种特性允许用户以有趣的方式去操作函数值.例如,在下面代码中定义一个add()函数,该函数能够返回一个新的函数,并把参数值传递给这个新函数,从而实现连加操作.var add = function(n){ return function(m){ return n+m; } }document.writeln(add(2)(3)); //5

JS编程建议——66:使用函数实现历史记录

建议66:使用函数实现历史记录函数可以利用对象去记住先前操作的结果,从而能避免无谓的运算,这种优化称为记忆.JavaScript的对象和数组要实现这种优化是非常方便的.例如,使用递归函数计算fibonacci数列.一个fibonacci数字是之前两个fibonacci数字之和.最前面的两个数字是0和1.var fibonacci = function(n) { return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); };for(var i

JS编程建议——71:推荐分支函数

建议71:推荐分支函数分支函数解决的一个问题是浏览器之间兼容性的重复判断.解决浏览器之间的兼容性的一般方式是使用if逻辑来进行特性检测或能力检测,根据浏览器不同的实现来实现功能上的兼容,这样做的问题是,每执行一次代码,可能都需要进行一次浏览器兼容性方面的检测,这是没有必要的.能否在代码初始化执行的时候就检测浏览器的兼容性,在之后的代码执行过程中,就无须再进行检测了呢?答案是:能.分支技术就可以解决这个问题,下面以声明一个XMLHttpRequest实例对象为例进行介绍.var XHR = fun

JavaScript代码教程:惰性载入函数

文章简介:因为浏览器之间行为的差异,多数JavaScript代码包含了大量的if语句,将执行引导到正确的代码中.看看XMLHttpRequest(XHR)对象中的createXHR()函数. 因为浏览器之间行为的差异,多数JavaScript代码包含了大量的if语句,将执行引导到正确的代码中.看看XMLHttpRequest(XHR)对象中的createXHR()函数: function createXHR() { if (typeof XMLHttpRequest != "undefined&

JS编程建议——65:比较函数的惰性求值与非惰性求值

建议65:比较函数的惰性求值与非惰性求值在JavaScript中,使用函数式风格编程时,应该对于表达式有着深刻的理解,并能够主动使用表达式的连续运算来组织代码.1)在运算元中,除了JavaScript默认的数据类型外,函数也作为一个重要的运算元参与运算.2)在运算符中,除了JavaScript的大量预定义运算符外,函数还作为一个重要的运算符进行计算和组织代码.函数作为运算符参与运算,具有非惰性求值特性.非惰性求值行为自然会对整个程序产生一定的负面影响.先看下面这个示例:var a = 2;fun

JS编程建议——59:推荐动态调用函数

建议59:推荐动态调用函数调用函数更便捷的方式是使用Function对象的call和apply方法.apply与call方法在本质上没有太大区别,只不过它们传递给函数的参数方式不同, apply是以数组形式进行参数传递,而call方法可以同时传递多个值.如果某个函数仅能够接收多个参数列表,而现在希望把一个数组的所有元素作为参数进行传递,那么使用apply方法就显得非常便利.function max(){ var m = Number.NEGATIVE_INFINITY; // 声明一个负无穷大的

JS编程建议——74:使用高阶函数

建议74:使用高阶函数高阶函数作为函数式编程众多风格中的一项显著特征,经常被使用.实际上,高阶函数即对函数的进一步抽象.高阶函数至少满足下列条件之一:接受函数作为输入.输出一个函数. 在函数式语言中,函数不但是一种特殊的对象,还是一种类型,因此函数本身是一个可以传来传去的值.也就是说,某个函数在刚开始执行的时候,总可以送入一个函数的参数.传入的参数本身就是一个函数.当然,这个输入的函数相当于某个函数的另外一个函数.当函数执行完毕之后,又可以返回另外一个新的函数,这个返回函数取决于return f

JS编程建议——70:惰性实例化

建议70:惰性实例化惰性实例化要解决的问题是:避免了在页面中JavaScript初始化执行的时候就实例化类,如果在页面中没有使用这个实例化的对象,就会造成一定的内存浪费和性能消耗.如果将一些类的实例化推迟到需要使用它的时候才去做,就可以避免资源过早损耗,做到"按需供应".var myNamespace = function() { var Configure = function() { var privateName = "someone's name"; var

JS编程建议——22:少用函数迭代

建议22:少用函数迭代ECMA-262v4为本地数组对象新增加了一个forEach方法.此方法遍历一个数组的所有成员,并且在每个成员上执行一个函数.在每个元素上执行的函数作为forEach()的参数传进去,并在调用函数时接收3个参数:数组项的值.数组项的索引.数组自身.例如: items.forEach(function(value, index, array){ process(value); }); forEach在Firefox.Chrome和Safari等浏览器中为原生函数.另外,for