在web开发中,因为浏览器之间的差异,往往会进行一些兼容性的浏览器嗅探,针对不同浏览器,走适合该浏览器的逻辑。
比如,事件绑定,W3C事件处理函数 addEventListener 在 IE 下不支持,IE 有自己的事件处理函数:attachEvent。针对这个情况,我们封装一个绑定事件的函数,可能大部分人学习的事件封装也就是下面这样:
//兼容的事件绑定函数
function bindEvent(elem, type, handler) //type记得要加引号
{
if(!!elem.addEventListener)
{
elem.addEventListener(type, handler, false);
}
else
{
elem.attachEvent('on'+type, handler);
}
}
bindEvent(document,"click", function(){alert(1);}); //点击网页会弹出1
一般,这样的封装看着好似没有问题了,很全面。但,在每次执行 bindEvent 函数时,内部的 if 判断,都会执行一次,这样就白白浪费性能了。这种情况,我们可以使用 惰性加载 来改写:
var bindEvent = function( elem, type, handler ){
if ( window.addEventListener ){
addEvent = function( elem, type, handler ){
elem.addEventListener( type, handler, false );
}
}else if ( window.attachEvent ){
addEvent = function( elem, type, handler ){
elem.attachEvent( 'on' + type, handler );
}
}
bindEvent( elem, type, handler );
};
bindEvent(document,"click", function(){alert(1);}); //点击网页会弹出1
上面改写后的 bindEvent 函数,会在第一次执行时,走内部的 if 判断,if 判断的内部,会对 bindEvent 重新赋值一个函数。这样,今后我们再调用 bindEvent,就是走的 重新赋值 后的 bindEvent 了,此时它内部是没有 if 那些判断的了。是不是很nice。
上面 bindEvent 函数定义内部 最后一行 bindEvent( elem, type, handler ); 是为了,在第一次使用 bindEvent 时,走完了 if 判断,会执行一次在 if 判断内进行重新赋值后的 bindEvent。(有点绕)
本文这种改写是个小技巧,工作中遇到 某个函数需要大量重复调用时,而其内部又有许多 if 判断,此时,我们要敏锐的考虑到,有更优的写法哦。
参考:《js设计模式与应用实践》
想要打赏,请点击这里