js系列之惰性载入函数

930 阅读2分钟

因为浏览器之间行为的差异,多数JavaScript代码包含了大量的if语句,将执行引导到正确的代码中,比如AJAX, 为了兼容ie7以下版本的浏览器和高版本ie的浏览器和其他浏览器,我们通常会这么写

function createXHR() {
    // IE7+和其他浏览器
    if(XMLHttpRequest !== undefined) {
        return new XMLHttpRequest();
    // IE5, IE6
    } else {
        retutrn new ActiveXObject("Microsoft.XMLHTTP")
    }
}

每次调用createXHR()的时候,它都要对浏览器所支持的能力仔细检查。如果浏览器支持内置XHR,那么它就一直支持了,那么这种测试就变得没必要了。即使只有一个if语句的代码,也肯定要比没有if语句的慢,所以如果if语句不必每次执行,那么代码可以运行地更快一些。解决方案就是称之为惰性载入的技巧

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

function createXHR() {
    if(XMLHttpRequest !== undefined) {
       createXHR = function () {
            return new XMLHttpRequest();
       }
    // IE5, IE6
    } else {
        createXHR = function () {
            return new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    return createXHR();
}

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

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

    var createXHR = (function() {
         if(XMLHttpRequest !== undefined) {
            return function () {
                return new XMLHttpRequest();
            }
       }
    // IE5, IE6
    } else {
        createXHR = function () {
            return function() {
                return new ActiveXObject("Microsoft.XMLHTTP");
            }
        }
    }
    })();

参考: 《javascript高级程序设计》