JavaScript惰性载入函数

时间:2022-01-18 13:18:03

因为各大浏览器所使用的JS引擎不同,所以在实现某一个功能时都或多或少的存在差异,导致在写代码时要针对每一个功能给出兼容浏览器的不同实现方式,这样在运行代码时就会造成性能的损耗。所以就出现了惰性载入函数的概念。原理就是:当前浏览器第一次支持以该方法实现某功能,那么在这个页面运行期间会一直都支持该方法。


一般在写兼容性较好的代码时,我们会使用多个if分支语句来判断当前浏览器支持哪种方法,这时如果每次调用函数都把if分支走一遍显然是损耗性能的。下面来看一个简单的例子:

function addEventHandler(element, eventType, func){
if (element.addEventListener){
element.addEventListener(eventType, func, false);
}
else if (element.attachEvent){
element.attachEvent('on' + eventType, func);
}
else{
element['on' + eventType] = func;
}

}

上面的函数,是一个简单的兼容各大浏览器的一个事件注册函数,如果采用上面的这种方式来定义函数,那么函数会在每次执行时都把if分支走一遍,显然不是明智的选择。下面来看一下如何用惰性载入函数来处理中情况吧!

一. 第一种实现方法:函数覆盖

function addEventHandler(element, eventType, func){
if (typeof addEventListener == 'function'){
addEventHandler = function (element, eventType, func){
element.addEventListener(eventType, func, false);
}
}
}else if (typeof attachEvent == 'function'){
addEventHandler = function (element, eventType, func){
element.attachEvent('on' + eventType, func);
}
}else{
addEventHandler = function (element, eventType, func){
element['on' + eventType] = func;
}
}
return addEventHandler(element, eventType, func);
}

将代码改为如上的方式,就可以在整个页面运行期间如果多次调用该函数,只走一遍if分支,因为在第一次运行函数时,if分支中的函数就覆盖了外部的函数。比如在Chrome浏览器中,第一次执行代码后,打印addEventHandler函数将变为如下这样:

function (element, eventType, func){
element.addEventListener(eventType, func, false);
}

可以看出分支中的同名函数覆盖了外部的函数。

二. 第二种实现方法:自执行函数

var addEventHandler = (function (element, eventType, func){
if (typeof addEventListener == 'function'){
return function (){
element.addEventListener(eventType, func, false);
}
}else if (typeof attachEvent == 'function'){
return function (){
element.attachEvent('on' + eventType, func);
}
}else{
return function (){
element['on' + eventType] = func;
}
}
})();

用自执行函数的方法,函数定义在全局环境的话,当页面一经载入将针对该浏览器的实现方法赋给了addEventHandler函数,只是在第一次载入时耗费资源,将页面载入后,打印addEventHandler函数如下:

function (){
element.addEventListener(eventType, func, false);
}

以上是惰性载入函数的实现方式,两种方式都可以避免执行不必要的代码。具体使用根据自己的需求而定。