晴明的博客园 GitHub      CodePen      CodeWars     

[js] 惰性加载

#原始

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

#plan A  覆盖原始函数

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

#plan B  

        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 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.");
                };
            }
        })();

#

 

 

通用的事件绑定函数addEvent,常见写法:

```

var addEvent = function(ele, type, handler){
    if(window.addEventListener){
        return ele.addEventListener(type, handler, false);
    }else if(ele.attachEvent){
        return ele.attachEvent('on'+type, handler);
    }
}

缺点是每调用一次都会执行里面的if条件分支
```


第二种方案是把嗅探浏览器的操作提前到代码加载的时候,
在代码加载的时候就立刻执行一次判断,
以便让addEvent返回一个包裹了正确逻辑的函数。

```
var addEvent = (function(){
    if(window.addEventListener){
        return function(ele, type, handler){
            ele.addEventListener(type, handler, false);
        }
    }
    if(window.attachEvent){
        return function(els, type, handler){
            ele.attachEvent('on'+type, handler);
        }
    }
})()

目前的addEvent函数依然有一个缺点,
也许我们从头到尾都没有使用过addEvent函数,这样看来,
前一次的浏览器嗅探就是完全的多余操作,而且也会稍稍延长页面ready的时间。
```


#惰性加载函数

此时addEvent被声明为一个普通函数,在函数里依然有一些分支判断。
但是,在第一次进入条件分支之后,函数内部就会重写这个函数,
重写后的函数就是我们期望的addEvent函数,在下一次进入addEvent函数的时候,
addEvent函数里不再存在分支条件。

```
var addEvent = function(ele, type, handler){
        if(window.addEventListener){
            addEvent = function(ele, type, handler){
                ele.addEventListener(type, handler, false);
            }
        }else if(window.attachEventListener){
            addEvent = function(ele, type, handler){
                ele.attachEvent('on'+type, handler);
            }
        }
        addEvent(ele, type, handler);
}
```

posted @ 2016-04-04 23:12  晴明桑  阅读(172)  评论(0编辑  收藏  举报