利用函数的惰性载入提高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 相关文章推荐
jQuery中size()方法用法实例
Dec 27 Javascript
JavaScript中的值类型转换介绍
Dec 31 Javascript
javascript原型模式用法实例详解
Jun 04 Javascript
简单的jQuery入门指引
Jul 28 Javascript
three.js实现围绕某物体旋转
Jan 25 Javascript
jQuery插件HighCharts绘制简单2D柱状图效果示例【附demo源码】
Mar 21 jQuery
JavaScript模块模式实例详解
Oct 25 Javascript
不使用JavaScript实现菜单的打开和关闭效果demo
May 01 Javascript
javascript面向对象三大特征之继承实例详解
Jul 24 Javascript
JavaScript鼠标悬停事件用法解析
May 15 Javascript
Nuxt配置Element-UI按需引入的操作方法
Jul 06 Javascript
springboot+VUE实现登录注册
May 27 Vue.js
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
用PHP编程开发“虚拟域名”系统
2006/10/09 PHP
PHP计划任务之关闭浏览器后仍然继续执行的函数
2010/07/22 PHP
php对二维数组进行排序的简单实例
2013/12/19 PHP
php socket实现的聊天室代码分享
2014/08/16 PHP
PHP生成随机密码方法汇总
2015/08/27 PHP
thinkphp在低版本Nginx 下支持PATHINFO的方法分享
2016/05/27 PHP
Javascript 网页水印(非图片水印)实现代码
2010/03/01 Javascript
JavaScript下利用fso判断文件是否存在的代码
2010/12/11 Javascript
33个优秀的jQuery 教程分享(幻灯片、动画菜单)
2011/07/08 Javascript
JavaScript高级程序设计 阅读笔记(二十) js错误处理
2012/08/14 Javascript
当前页禁止复制粘贴截屏代码小集
2013/07/24 Javascript
处理及遍历XML文档DOM元素属性及方法整理
2013/08/23 Javascript
JavaScript中document.forms[0]与getElementByName区别
2015/01/21 Javascript
Bootstrap表单布局
2016/07/19 Javascript
javascript中sort排序实例详解
2016/07/24 Javascript
jQuery实现鼠标经过像翻页和描点链接效果
2016/08/08 Javascript
js使用generator函数同步执行ajax任务
2017/09/05 Javascript
微信小程序—setTimeOut定时器的问题及解决
2019/07/26 Javascript
VUE+Element实现增删改查的示例源码
2020/11/23 Vue.js
JavaScript仿京东轮播图效果
2021/02/25 Javascript
[02:07]DOTA2新英雄展现中国元素,完美“圣典”亮相央视
2016/12/19 DOTA
[43:24]2018DOTA2亚洲邀请赛3月29日 小组赛A组 LGD VS Liquid
2018/03/30 DOTA
python数据封装json格式数据
2018/03/04 Python
Python 离线工作环境搭建的方法步骤
2019/07/29 Python
python快速编写单行注释多行注释的方法
2019/07/31 Python
解决Python paramiko 模块远程执行ssh 命令 nohup 不生效的问题
2020/07/14 Python
python 下载m3u8视频的示例代码
2020/11/11 Python
彻底解决Python包下载慢问题
2020/11/15 Python
存储过程的优点有哪些
2012/09/27 面试题
餐厅销售主管职责范本
2014/02/19 职场文书
建筑工程专业大学生求职信
2014/04/23 职场文书
小学综治宣传月活动总结
2014/07/02 职场文书
小学生国庆演讲稿
2014/09/05 职场文书
个人委托书范本
2014/09/13 职场文书
暂停营业通知
2015/04/25 职场文书
MyBatis核心源码深度剖析SQL语句执行过程
2022/05/20 Java/Android