利用函数的惰性载入提高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 相关文章推荐
XHTML-Strict 内允许出现的标签
Dec 11 Javascript
js操作模态窗口及父子窗口间相互传值示例
Jun 09 Javascript
js数字滑动时钟的简单实现(示例讲解)
Aug 14 Javascript
Node.js中sequelize时区的配置方法
Dec 10 Javascript
p5.js入门教程之小球动画示例代码
Mar 15 Javascript
vue-cli项目代理proxyTable配置exclude的方法
Sep 20 Javascript
Vue数据双向绑定的深入探究
Nov 27 Javascript
javascript中的event loop事件循环详解
Dec 14 Javascript
vue路由守卫+登录态管理实例分析
May 21 Javascript
使用Vue+Django+Ant Design做一个留言评论模块的示例代码
Jun 01 Javascript
JS实现联想、自动补齐国家或地区名称的功能
Jul 07 Javascript
使用JS实现简易计算器
Jun 14 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
风格模板初级不完全修改教程
2006/10/09 PHP
基于php验证码函数的使用示例
2013/05/03 PHP
PHP之生成GIF动画的实现方法
2013/06/07 PHP
php结合web uploader插件实现分片上传文件
2016/05/10 PHP
php利用云片网实现短信验证码功能的示例代码
2017/11/18 PHP
laravel 之 Eloquent 模型修改器和序列化示例
2019/10/17 PHP
基于jquery DOM写的类似微博发布的效果
2012/10/20 Javascript
JQUERY对单选框(radio)操作的小例子
2013/04/25 Javascript
解决js中window.open弹出的是上次的缓存页面问题
2013/12/29 Javascript
JavaScript中的substr()方法使用详解
2015/06/06 Javascript
使用jquery插件qrcode生成二维码
2015/10/22 Javascript
JavaScript中匿名函数的用法及优缺点详解
2016/06/01 Javascript
js 动态添加元素(div、li、img等)及设置属性的方法
2016/07/19 Javascript
javascript实现圣旨卷轴展开效果(代码分享)
2017/03/23 Javascript
Node实战之不同环境下配置文件使用教程
2018/01/02 Javascript
关于自定义Egg.js的请求级别日志详解
2018/12/12 Javascript
Vue 之孙组件向爷组件通信的实现
2019/04/23 Javascript
在vue+element ui框架里实现lodash的debounce防抖
2019/11/13 Javascript
Vue——前端生成二维码的示例
2020/12/19 Vue.js
用Python代码来绘制彭罗斯点阵的教程
2015/04/03 Python
在Gnumeric下使用Python脚本操作表格的教程
2015/04/14 Python
python简单获取本机计算机名和IP地址的方法
2015/06/03 Python
利用python循环创建多个文件的方法
2018/10/25 Python
PyQt5实现简易计算器
2020/05/30 Python
Python数据可视化:饼状图的实例讲解
2019/12/07 Python
python numpy数组中的复制知识解析
2020/02/03 Python
Watchshop德国:欧洲在线手表No.1
2019/06/20 全球购物
2013届毕业生求职信范文
2013/11/20 职场文书
实习生岗位职责
2014/04/12 职场文书
幼儿老师求职信
2014/06/30 职场文书
水利水电专业自荐信
2014/07/08 职场文书
2014年党员自我评议对照检查材料
2014/09/20 职场文书
2014财务部年度工作总结
2014/12/08 职场文书
大一学生个人总结
2015/02/15 职场文书
幼儿园2016年感恩节活动总结
2016/04/01 职场文书
Redis官方可视化工具RedisInsight安装使用教程
2022/04/19 Redis