利用函数的惰性载入提高javascript代码执行效率


Posted in Javascript onMay 05, 2014

在 javascript 代码中,因为各浏览器之间的行为的差异,我们经常会在函数中包含了大量的 if 语句,以检查浏览器特性,解决不同浏览器的兼容问题。 例如,我们最常见的为 dom 节点添加事件的函数:

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

每次调用 addEvent 函数的时候,它都要对浏览器所支持的能力进行检查,首先检查是否支持addEventListener 方法,如果不支持,再检查是否支持 attachEvent 方法,如果还不支持,就用 dom 0 级的方法添加事件。 这个过程,在 addEvent 函数每次调用的时候都要走一遍,其实,如果浏览器支持其中的一种方法,那么他就会一直支持了,就没有必要再进行其他分支的检测了, 也就是说,if 语句不必每次都执行,代码可以运行的更快一些。

解决的方案就是称之为惰性载入的技巧。

所谓惰性载入,就是说函数的if分支只会执行一次,之后调用函数时,直接进入所支持的分支代码。 有两种实现惰性载入的方式,第一种事函数在第一次调用时,对函数本身进行二次处理,该函数会被覆盖为符合分支条件的函数,这样对原函数的调用就不用再经过执行的分支了, 我们可以用下面的方式使用惰性载入重写 addEvent()。

function addEvent (type, element, fun) { 
if (element.addEventListener) { 
addEvent = function (type, element, fun) { 
element.addEventListener(type, fun, false); 
} 
} 
else if(element.attachEvent){ 
addEvent = function (type, element, fun) { 
element.attachEvent('on' + type, fun); 
} 
} 
else{ 
addEvent = function (type, element, fun) { 
element['on' + type] = fun; 
} 
} 
return addEvent(type, element, fun); 
}

在这个惰性载入的 addEvent() 中,if 语句的每个分支都会为 addEvent 变量赋值,有效覆盖了原函数。 最后一步便是调用了新赋函数。下一次调用 addEvent() 的时候,便会直接调用新赋值的函数,这样就不用再执行if 语句了。

第二种实现惰性载入的方式是在声明函数时就指定适当的函数。 这样在第一次调用函数时就不会损失性能了,只在代码加载时会损失一点性能。 一下就是按照这一思路重写的 addEvent()。

var addEvent = (function () { 
if (document.addEventListener) { 
return function (type, element, fun) { 
element.addEventListener(type, fun, false); 
} 
} 
else if (document.attachEvent) { 
return function (type, element, fun) { 
element.attachEvent('on' + type, fun); 
} 
} 
else { 
return function (type, element, fun) { 
element['on' + type] = fun; 
} 
} 
})();

这个例子中使用的技巧是创建一个匿名的自执行函数,通过不同的分支以确定应该使用那个函数实现,实际的逻辑都一样, 不一样的地方就是使用了函数表达式(使用了 var 定义函数)和新增了一个匿名函数,另外每个分支都返回一个正确的函数,并立即将其赋值给变量 addEvent。

惰性载入函数的优点只执行一次 if 分支,避免了函数每次执行时候都要执行 if 分支和不必要的代码,因此提升了代码性能,至于那种方式更合适,就要看您的需求而定了。

Javascript 相关文章推荐
JavaScript中使用Object.create()创建对象介绍
Dec 30 Javascript
JQuery中上下文选择器实现方法
May 18 Javascript
JavaScript获取IP获取的是IPV6 如何校验
Jun 12 Javascript
js实现的页面加载完毕之前loading提示效果完整示例【附demo源码下载】
Aug 02 Javascript
jQuery中常用动画效果函数(日常整理)
Sep 17 Javascript
vue实现页面加载动画效果
Sep 19 Javascript
JS获取当前地理位置的方法
Oct 25 Javascript
使用 Node.js 模拟滑动拼图验证码操作的示例代码
Nov 02 Javascript
JavaScript实现一个简易的计算器实例代码
May 10 Javascript
在vue中实现点击选择框阻止弹出层消失的方法
Sep 15 Javascript
vue-cli点击实现全屏功能
Mar 07 Javascript
javascript 内存模型实例详解
Apr 18 Javascript
JavaScript加入收藏夹功能(兼容IE、firefox、chrome)
May 05 #Javascript
IE 下Enter提交表单存在重复提交问题的解决方法
May 04 #Javascript
javascript 获取元素样式必杀技
May 04 #Javascript
javascript操作excel生成报表全攻略
May 04 #Javascript
javascript如何使用bind指定接收者
May 04 #Javascript
用jquery.sortElements实现table排序
May 04 #Javascript
jquery实现的鼠标拖动排序Li或Table
May 04 #Javascript
You might like
回帖脱衣服的图片实现代码
2014/02/15 PHP
php ajax实现文件上传进度条
2016/03/29 PHP
火狐浏览器(firefox)下获得Event对象以及keyCode
2008/11/13 Javascript
无缝滚动js代码通俗易懂(自写)
2013/06/19 Javascript
js获取日期:昨天今天和明天、后天
2014/06/11 Javascript
node.js中的fs.rmdirSync方法使用说明
2014/12/16 Javascript
JavaScript中的值类型详细介绍
2014/12/29 Javascript
AngularJS使用自定义指令替代ng-repeat的方法
2016/09/17 Javascript
AngularJS删除路由中的#符号的方法
2016/09/20 Javascript
javascript实现右下角广告框效果
2017/02/01 Javascript
vuejs2.0实现分页组件使用$emit进行事件监听数据传递的方法
2017/02/22 Javascript
JavaScript如何获取到导航条中HTTP信息
2017/10/10 Javascript
Vue仿今日头条实例详解
2018/02/06 Javascript
mpvue中使用flyjs全局拦截的实现代码
2018/09/13 Javascript
详解Python中dict与set的使用
2015/08/10 Python
Python读写txt文本文件的操作方法全解析
2016/06/26 Python
python数据抓取分析的示例代码(python + mongodb)
2017/12/25 Python
Python装饰器知识点补充
2018/05/28 Python
Numpy中矩阵matrix读取一列的方法及数组和矩阵的相互转换实例
2018/07/02 Python
django开发post接口简单案例,获取参数值的方法
2018/12/11 Python
Python使用crontab模块设置和清除定时任务操作详解
2019/04/09 Python
PyTorch中的padding(边缘填充)操作方式
2020/01/03 Python
python开发实例之python使用Websocket库开发简单聊天工具实例详解(python+Websocket+JS)
2020/03/18 Python
keras 获取某层输出 获取复用层的多次输出实例
2020/05/23 Python
Anaconda+vscode+pytorch环境搭建过程详解
2020/05/25 Python
详解Python中的Lock和Rlock
2021/01/26 Python
巴西体育用品商店:Lojão dos Esportes
2018/07/21 全球购物
毕业生自荐书
2013/12/18 职场文书
开业庆典邀请函
2014/01/08 职场文书
领导视察欢迎词
2014/01/15 职场文书
学生会副主席竞聘书
2014/03/31 职场文书
2015年元旦活动总结
2014/05/09 职场文书
四风问题原因分析及整改措施
2014/10/24 职场文书
医生辞职信范文
2015/03/02 职场文书
有关三国演义的读书笔记
2015/06/25 职场文书
Mysql开启外网访问
2022/05/15 MySQL