利用函数的惰性载入提高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 禁止复制网页
Jun 11 Javascript
JQuery toggle使用分析
Nov 16 Javascript
传智播客学习之java 反射
Nov 22 Javascript
xheditor与validate插件冲突的解决方案
Apr 15 Javascript
jquery获得页面元素的坐标值实现思路及代码
Apr 15 Javascript
jQuery实现的超酷苹果风格图标滑出菜单效果代码
Sep 16 Javascript
解决JS请求服务器gbk文件乱码的问题
Oct 16 Javascript
详解vue-meta如何让你更优雅的管理头部标签
Jan 18 Javascript
vue动态绑定class的几种常用方式小结
May 21 Javascript
vant-ui组件调用Dialog弹窗异步关闭操作
Nov 04 Javascript
js实现日历
Nov 07 Javascript
js实现弹框效果
Mar 24 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
PHP安全配置详细说明
2011/09/26 PHP
PHP图片自动裁切应付不同尺寸的显示
2014/10/16 PHP
PHP SOCKET编程详解
2015/05/22 PHP
thinkPHP简单遍历数组方法分析
2016/05/16 PHP
PHP获取真实客户端的真实IP
2017/03/07 PHP
PHP简单读取xml文件的方法示例
2017/04/20 PHP
Yii2第三方类库插件Imagine的安装和使用
2017/07/06 PHP
IE6下JS动态设置图片src地址问题
2010/01/08 Javascript
基于jquery的一个浮动框(扩展性比较好 )
2010/08/27 Javascript
JQuery的read函数与js的onload不同方式实现
2013/03/18 Javascript
JavaScript为事件句柄绑定监听函数实例详解
2015/12/15 Javascript
jquery mobile开发常见问题分析
2016/01/21 Javascript
jQuery中ztree 点击文本框弹出下拉框的实例代码
2017/02/05 Javascript
微信小程序实战之仿android fragment可滑动底部导航栏(4)
2020/04/16 Javascript
js canvas实现适用于移动端的百分比仪表盘dashboard
2017/07/18 Javascript
Node.js学习之查询字符串解析querystring详解
2017/09/28 Javascript
jquery 验证用户名是否重复代码实例
2019/05/14 jQuery
Openlayers绘制聚合标注
2020/09/28 Javascript
Python实现将MySQL数据库表中的数据导出生成csv格式文件的方法
2018/01/11 Python
django中的HTML控件及参数传递方法
2018/03/20 Python
Python计算一个给定时间点前一个月和后一个月第一天的方法
2018/05/29 Python
使用PM2+nginx部署python项目的方法示例
2018/11/07 Python
python处理“
2019/06/10 Python
django的聚合函数和aggregate、annotate方法使用详解
2019/07/23 Python
Python脚本如何在bilibili中查找弹幕发送者
2020/06/04 Python
python tkinter实现连连看游戏
2020/11/16 Python
python字符串拼接+和join的区别详解
2020/12/03 Python
CSS3制作3D立方体loading特效
2020/11/09 HTML / CSS
Omio西班牙:全欧洲低价大巴、火车和航班搜索和比价
2017/02/11 全球购物
德国在线香料制造商:Gewürzland
2020/03/10 全球购物
医生进修自我鉴定
2014/01/19 职场文书
《莫泊桑拜师》教学反思
2014/04/23 职场文书
党员个人剖析材料
2014/09/30 职场文书
大三学生英语考试作弊检讨书
2015/01/01 职场文书
如何使用Maxwell实时同步mysql数据
2021/04/08 MySQL
Python djanjo之csrf防跨站攻击实验过程
2021/05/14 Python