惰性模式——减少重复性的浏览器特性/能力检测

惰性模式:减少每次代码执行时的重复性的分支判断,通过对对象重定义来屏蔽原对象中的分支判断。

问题代码:

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

每次为元素添加事件时,都会走一遍能力检测,这是多余的,因为在同一个浏览器中两次执行方法,能力检测是不可能走两个不同的分支的。

既然第一次执行时已经判断过了,而且以后再执行是不必要的,那么就可以在第一次执行后就重新定义它。这就是惰性模式的精髓。

工作中这种模式思想有两种实现方式,

  • 第一种就是在文件加载进来时通过闭包执行该方法对其重新定义。
    不过这样会使页面加载时占用一定的资源。
var on = function(dom, type, fn) {
    if (document.addEventListener) {
        return function(dom, type, fn) {
            dom.addEventListener(type, fn, false);
        }
    } else if (document.attachEvent) {
        return function(dom, type, fn) {
            dom.attachEvent('on' + type, fn);
        }
    } else {
        return function(dom, type, fn) {
            dom['on' + type'] = fn;
        }
    }
}();
  • 第二种方式是在第一种方式寄出上做一次延迟执行,在函数第一次调用的时候对其重定义。
    这么做的好处就是减少文件加载时的资源消耗,但是却在第一次执行时有一定的资源消耗。
function on(dom, type, fn) {
    if (dom.addEventListener) {
        on = function(dom, type, fn) {
            dom.addEventListener(type, fn, false);
        }
    } else if (dom.attachEvent) {
        on = function(dom, type, fn) {
            dom.attachEvent('on' + type, fn);
        }
    } else {
        on = function(dom, type, fn) {
            dom['on' + type] = fn;
        }
    }
    // 执行重定义on方法
    on(dom, type, fn);
}

第二种方式与第一种实现方式的不同之处在于,首先,内部对元素dom执行能力检测并显式重写,其次,原始函数在函数的最末尾重新执行一遍来绑定事件。不过在文件加载后on方法还没能重新被定义。所以我们还需等到某一元素绑定事件时(调用on方法时),on才能被重定义。

所以你可以看出这种方式实质上是对消耗的一种惰性推移,有时候是很有必要的,尤其在重定义时消耗资源比较大而且想尽量早地预览到页面时。

如今浏览器繁多,尤其在国内更是复杂,很多功能在不同浏览器中实现不以,所以很多代码为兼容各个浏览器写的分支特别臃肿,有了这种模式,就能使臃肿的代码执行效率得到提高了。比如创建XHR对象。

总结:
惰性模式是一种拖延模式,由于对象的创建或者数据的计算会花费高昂的代价(如页面刚加载时无法辨别是该浏览器支持某个功能,此时创建对象是不够安全的),因此页面之初会延迟对这一类对象的创建。惰性模式又分为两种:第一种是文件加载后立即执行对象方法来重定义对象。第二种是当第一次使用方法对象时重定义对象。

对于第一种方式,由于文件加载时执行,因此会占用一些资源。

对于第二种方式由于在第一次使用时重定义对象,以致第一次执行时间增加。

有时候两种方式对资源的开销都是可接受的,因此到底使用哪种方式,要看具体需求而定。

以上内容摘抄自《JavaScript设计模式》
阅读 90

推荐阅读