[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);
}
```