利用函数的惰性载入提高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 Change与bind事件代码
Sep 29 Javascript
A标签触发onclick事件而不跳转的多种解决方法
Jun 27 Javascript
Textarea根据内容自适应高度
Oct 28 Javascript
jQuery中ajax的load()与post()方法实例详解
Jan 05 Javascript
JS基于MSClass和setInterval实现ajax定时采集信息并滚动显示的方法
Apr 18 Javascript
js改变html的原有内容实现方法
Oct 05 Javascript
JavaWeb表单及时验证功能在输入后立即验证(含用户类型,性别,爱好...的验证)
Jun 09 Javascript
Javascript实现的StopWatch功能示例
Jun 13 Javascript
Vue的MVVM实现方法
Aug 16 Javascript
JS实现仿微信支付弹窗功能
Jun 25 Javascript
webpack+vue-cli项目中引入外部非模块格式js的方法
Sep 28 Javascript
vue实现移动端悬浮窗效果
Dec 01 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
PHP5 安装方法
2006/10/09 PHP
PHP变量的定义、可变变量、变量引用、销毁方法
2013/12/20 PHP
一个简单的php路由类
2016/05/29 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
通过修改referer下载文件的方法
2008/05/11 Javascript
javascript jQuery插件练习
2008/12/24 Javascript
Javascript this 关键字 详解
2014/10/22 Javascript
javaScript实现可缩放的显示区效果代码
2015/10/26 Javascript
基于jQuery1.9版本如何判断浏览器版本类型
2016/01/12 Javascript
js字符串操作总结(必看篇)
2016/11/22 Javascript
ajax接收后台数据在html页面显示
2017/02/19 Javascript
VueJS如何引入css或者less文件的一些坑
2017/04/25 Javascript
JavaScrpt中如何使用 cookie 设置查看与删除功能
2017/07/09 Javascript
ckeditor一键排版功能实现方法分析
2020/02/06 Javascript
jQuery实现的移动端图片缩放功能组件示例
2020/05/01 jQuery
浅谈vue websocket nodeJS 进行实时通信踩到的坑
2020/09/22 NodeJs
Vue+Java 通过websocket实现服务器与客户端双向通信操作
2020/09/22 Javascript
Python中变量交换的例子
2014/08/25 Python
用Python中的字典来处理索引统计的方法
2015/05/05 Python
python 打印对象的所有属性值的方法
2016/09/11 Python
浅谈Scrapy框架普通反爬虫机制的应对策略
2017/12/28 Python
78行Python代码实现现微信撤回消息功能
2018/07/26 Python
tensorflow 打印内存中的变量方法
2018/07/30 Python
解决python中画图时x,y轴名称出现中文乱码的问题
2019/01/29 Python
为什么你还不懂得怎么使用Python协程
2019/05/13 Python
使用Python爬虫库requests发送表单数据和JSON数据
2020/01/25 Python
使用python计算三角形的斜边例子
2020/04/15 Python
解决PyCharm IDE环境下,执行unittest不生成测试报告的问题
2020/09/03 Python
Python 转移文件至云对象存储的方法
2021/02/07 Python
美国鲜花递送:UrbanStems
2021/01/04 全球购物
几个Shell Script面试题
2012/08/31 面试题
采购员岗位职责
2013/11/15 职场文书
生物制药自我鉴定
2014/01/25 职场文书
应届大学生自荐书
2014/06/17 职场文书
关于青春的演讲稿三分钟
2014/08/22 职场文书
餐厅周年庆活动方案
2014/08/25 职场文书