编程语言
首页 > 编程语言> > javaScript惰性载入函数

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().

标签:activeXString,return,函数,javaScript,createXHR,载入,version,惰性,new
来源: https://blog.csdn.net/weixin_44283589/article/details/120889763