javaScript惰性载入函数实现的两种方式

由于浏览器的差异,多数js代码包含大量if语句用来引导程序正确执行.
例子如下:

   function createXHR() {
        if (typeof XMLHttpRequest != "undefined") {
            return new XMLHttpRequest(); //XMLHttpRequest类型不为undefined时返回XMLHttpRequest实例
        } else if (typeof ActiveXObject != "undefined") {
            if (typeof arguments.callee.activeXString != "string") {
                var version = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp", ],
                    i;
                for (i = 0, i < version.length; i++) {
                    try {
                        new ActiveXObject(version[i]);
                        arguments.callee.activeXString = version[i];
                        break;
                    } catch (ex) {
                        // 跳过
                    }
                }
            }
            return new ActiveXObject(arguments.callee.activeXString);
        } else {
            throw new Error("NO XHR object available")
        }
    }

每次调用createXHR()时,它都会对浏览器支持的能力做检查;
首先检查内置的XHR,然后测试有没有基于ActiveX的XHR,两者都没有就抛出错误;
每次调用此函数都会这样,即使每次调用时分支的结果都不变,也都会执行if语句;
那如果浏览器支持内置XHR,也就意味着会一直支持,那么这个测试就没必要了,因为有if语句的函数要比没有if语句的慢;
所以,如果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") {
                    var version = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp", ],
                        i;
                    for (i = 0; i < version.length; i++) {
                        try {
                            new ActiveXObject(version[i]);
                            arguments.callee.activeXString = version[i];
                            break;
                        } catch (ex) {

                        }
                    }
                }
                return new ActiveXObject(arguments.callee.activeXString);
            }
        } else {
            createXHR = function () {
                throw new Error("NO XHL object available")
            };
        }
        return createXHR();
    }

在这个惰性载入的createXHR()中,if语句的每一个分支都会为createXHR变量赋值,从而覆盖了原有的函数,最后一句就是调用新赋的函数.下一次调用时,就会直接调用被分配的函数,这样就不用再次执行if语句了

方式二:在声明函数时就指定适当的函数.

这样在第一次调用函数时就不会损失性能了,而是在代码首次加载时会损失一点性能
例子重写如下:

var createXHR = (function () {
        if (typeof XMLHttpRequest != "undefined") {
            return function () {
                return new XMLHttpRequest()
            };
        } else if (typeof ActiveXObject != "undefined") {
            return function () {
                if (typeof arguments.callee.activeXString != "string") {
                    var version = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp", ],
                        i;
                    for (i = 0; i < version.length; i++) {
                        try {
                            new ActiveXObject(version[i]);
                            arguments.callee.activeXString = version[i];
                            break;
                        } catch (e) {
                            // 
                        }
                    }
                }
                return new ActiveXObject(arguments.callee.activeXString);
            };
        } else {
            return function () {
                throw new Error("NO XHR object available")
            };
        }
    })();

这个重写的例子中创建了一个匿名、自执行的函数,根据返回的结果来确定使用哪一个函数实现.实际逻辑是一样的,不一样的地方是第一行代码是使用var定义的函数,并且新增了自执行的匿名函数,每个分支都会返回正确的函数定义,以便将其赋值给createXHR().

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值