说说分支技术的一种替代方案

大家应该都知道Javascript中分支技术的实现原理:是一种用来把浏览器间的差异封装到在运行期间进行设置的动态方法中的技术。没错,这个解释是出自《Javascript设计模式》。分支技术最大的特点是只在脚本加载是一次性的确定针对特定的浏览器的代码,这样一来,在初始化完成之后,每种浏览器都只会执行针对特定浏览器的代码,能够在运行时动态确定函数代码的能力。下面是分支技术的简单实现的一个例子:

//三个对象都声明相同的createXhr方法以示统一
var SimpleXhrFactory=(function(){
   var standard={
       createXhr:function(){
            return new XMLHttpRequest();
       }
   };
   var activeXNew={
       createXhr:function(){
            return new ActiveXObject("Msxml2.XMLHTTP");
       }
   };
   var activeXOld={
      createXhr:function(){
           return new ActiveXObject("Microsoft.XMLHTTP");
      }
   };

   var testObj;
   try{
       testObj=standard.createXhr();
       return standard;
   }catch(e){
        try{
              testObj=activeXNew.createXhr();
              return activeXNew;
        }catch(e){
              testObj=activeXOld.createXhr();
              return activeXNew;
        }
   }
}();

上面的例子就是分支技术的一个应用。我不知道大家对这段代码是否有什么意见或者异议,反正我是觉得冗长了,无端端的声明了三个对象不说,最后还是需要try…catch一套。下面是我所想到的一种解决方案来代替这个关于声明XMLHttpRequest实例对象的例子:

//在运行时就确定了特定的浏览器下将要执行哪个分支的函数
var XHR = {}
XHR.create = (function(){
    if (window.XMLHttpRequest) {
        return function(){
            return new XMLHttpRequest();
        }
    }
    else {
        try {
            //为了判断Msxml2和Microsoft版本的ActiveXObject,不得不实例化一个,不过也就是一次性过了而已
            return new ActiveXObject("Msxml2.XMLHTTP") && function(){
                return new ActiveXObject("Msxml2.XMLHTTP");
            }
        } catch (e) {
            return function(){
                return new ActiveXObject("Microsoft.XMLHTTP");
            }
        }
    }
})();

上面的代码简洁明了,有一个不好的缺点就是需要在IE6下需要实例化多一个ActiveXObject(“Msxml2.XMLHTTP”)作为判断条件,IE7以上以及FF等其他浏览器则不会有这个实例化的过程,不过还是那句话,也就是在初始化的时候有这个过程而已,之后浏览器会根据特定的函数来执行。测试页面

(全文…)