惰性函数定义

惰性载入表示函数执行的分支只会在函数第一次掉用的时候执行,在第一次调用过程当中,该函数会被覆盖为另外一个按照合适方式执行的函数,这样任何对原函数的调用就不用再通过执行的分支了。javascript

下面咱们看几个典型的例子:前端

复制代码

function addEvent (type, element, fun) {
    if (element.addEventListener) {
        element.addEventListener(type, fun, false);
    }
    else if(element.attachEvent){
        element.attachEvent('on' + type, fun);
    }
    else{
        element['on' + type] = fun;
    }
}

复制代码

上面是注册函数监听的各浏览器兼容函数。因为,各浏览之间的差别,不得不在用的时候作能力检测。显然,单从功能上讲,已经作到了兼容浏览器。美中不足,每次绑定监听,都会对能力作一次检测。然而,真正的应用中,这显然是多余的,同一个应用环境中,其实只须要检测一次便可。java

下面咱们重写上面的addEvent:浏览器

复制代码

function addEvent (type, element, fun) {
    if (element.addEventListener) {
        addEvent = function (type, element, fun) {
            element.addEventListener(type, fun, false);
        }
    }
    else if(element.attachEvent){
        addEvent = function (type, element, fun) {
            element.attachEvent('on' + type, fun);
        }
    }
    else{
        addEvent = function (type, element, fun) {
            element['on' + type] = fun;
        }
    }
    return addEvent(type, element, fun);
}

复制代码

由上,第一次调用addEvent会对浏览器作能力检测,而后,重写了addEvent。下次再调用的时候,因为函数被重写,不会再作能力检测。缓存

一样的应用,javascript高级程序设计里的一例子:函数

复制代码

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"];
    
            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){
                    //skip
                }
            }
        }
    
        return new ActiveXObject(arguments.callee.activeXString);
    } else {
        throw new Error("No XHR object available.");
    }
}

复制代码

很显然,惰性函数在这里优点更加明显,由于这里有更多的分支。下面咱们看一下重写后台的函数:性能

复制代码

function createXHR() {
            if (typeof XMLHttpRequest != "undefined") {
                createXHR = function () {
                    return new XMLHttpRequest();
                }
                return new XMLHttpRequest();
            } else if (typeof ActiveXObject != "undefined") {
                var curxhr;
                var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
                    "MSXML2.XMLHttp"];

                for (var i = 0, len = versions.length; i < len; i++) {
                    try {
                        var xhr = new ActiveXObject(versions[i]);
                        curxhr = versions[i];
                        createXHR = function () {
                            return new ActiveXObject(curxhr);
                        }
                        return xhr;
                    } catch (ex) {
                        //skip
                    }
                }
            } else {
                throw new Error("No XHR object available.");
            }
        }

复制代码

 

浏览器之间最大的差别,莫过于Dom操做,Dom操做也是前端应用 中最频繁的操做,前端的大多性能提高,均体如今Dom操做方面。下面看一个Dom操做方面的惰性函数定义例子:this

复制代码

var getScrollY = function() {

    if (typeof window.pageYOffset == 'number') {

        getScrollY = function() {
            return window.pageYOffset;
        };

    } else if ((typeof document.compatMode == 'string') &&
               (document.compatMode.indexOf('CSS') >= 0) &&
               (document.documentElement) &&
               (typeof document.documentElement.scrollTop == 'number')) {

        getScrollY = function() {
            return document.documentElement.scrollTop;
        };

    } else if ((document.body) &&
               (typeof document.body.scrollTop == 'number')) {

      getScrollY = function() {
          return document.body.scrollTop;
      }

    } else {

      getScrollY = function() {
          return NaN;
      };

    }

    return getScrollY();
}

复制代码

 惰性函数定义应用还体如今建立单例上:设计

复制代码

unction Universe() {

    // 缓存的实例
    var instance = this;

    // 其它内容
    this.start_time = 0;
    this.bang = "Big";

    // 重写构造函数
    Universe = function () {
        return instance;
    };
}

复制代码

固然,像上面这种例子有不少。惰性函数定义,应用场景咱们能够总结一下:ip

1 应用频繁,若是只用一次,是体现不出它的优势出来的,用的次数越多,越能体现这种模式的优点所在;

2 固定不变,一次断定,在固定的应用环境中不会发生改变;

3 复杂的分支判断,没有差别性,不须要应用这种模式;

相关文章
相关标签/搜索