JS惰性载入函数

    函数的惰性载入,在Js中很常见的一种编码现象。由于各大浏览器的差异,我们在实现一项功能的时候需要考虑不同浏览器之间的兼容性问题,因此需要进行浏览器嗅探。最常用的嗅探方法就是通过if else的方式判断当前环境是否支持某一对象。例如,使用原生js创建XHR对象:

function createXHR(){
    if(typeof XMLHttpRequest != 'undefined'){
        return new XMLHttpRequest();
    }else if(typeof ActiveXObject != 'undefined'){
        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.')
    }

}

        每次调用createXHR()的时候,他都会对浏览器所支持的能力进行检测:首先检测内置的XHR,如果没有内置XHR,测试有没有基于ActiveX的XHR,最后如果都没有发现的话就抛出一个异常。每次调用该函数都会重复以上步骤,即使每次调用时分支结果都不变。如果浏览器支持内置的XHR,那么它就是一直支持了,那么这种重复的检测就变的没有必要了。在JS中,即使只有一个if语句的判断,也肯定要比没有if语句的慢,所以如果if语句不必内次都执行,那么代码就可以在一定程度上运行的更快。解决方案就是称之为惰性载入的技巧。

    惰性载入表示函数执行的分支仅会发生一次。有两种实现惰性载入的方式,第一种就是在函数被调用时在处理函数。在第一次调用的过程中,该函数会被覆盖为另外一个按合适的方式执行的函数,这样任何对原函数的调用都不会再经过执行的分支了。例如,可以用下面的方式使用惰性载入重写createXHR函数:

function createXHR(){
    if(typeof XMLHttpRequest != 'undefined'){
        createXHR = function(){
            return new XMLHttpRequest();
        };
    }else if(typeof ActiveObject !=  '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){
                        //skip
                    }
                }
            }
            return new ActiveXObject(arguments.callee.activeXString);            
        };
    }else{
        createXHR = function(){
            throw new Error('NO XHR object available.');
        }
    }

    return createXHR();
}

    在这个惰性载入的createXHR()中,if语句的每一个分支都会为creaeteXHR变量赋值,有效覆盖了原有的函数。最后一步便是调用新赋值的函数。下一次调用createXHR()的时候,就会直接调用被分配的函数。之后就不会再次执行if语句进行识别了。

    第二种实现惰性载入的方式是在声明函数时就指定适当的函数。这样,第一次调用函数就不会损失性能了,而在代码首次加载时会损失一点性能。例如,下面这个例子:

 var createXHR = (function(){
    if(typeof XMLHttpRequest != 'undefined'){
        return function(){
            return new XMLHttpRequest();
        }
    }else if(typeof ActiveObject != '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){
                        //skip
                    }
                }
            }
            return new ActiveXObject(arguments.callee.activeXString);
        };
    }else {
        return function(){
            throw new Error('NO XHR object available.');
        };
    }

})();

    这个例子中使用的技巧是创建一个匿名、自执行的函数,用以确定应该以哪一个函数实现。实际的逻辑都一样。不一样的地方就是第一行代码(使用var 定义函数)、新增了自执行的匿名函数,另外每个分支都返回正确的函数定义,以便立即将其赋值给createXHR()。

    惰性载入函数的有点是只在首次执行分支代码时牺牲一点性能,在以后再次调用时,可以避免执行不必要的分支检测。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值