利用函数的惰性载入提高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 02 Javascript
Javascript 中的 && 和 || 使用小结
Apr 25 Javascript
实现51Map地图接口(示例代码)
Nov 22 Javascript
js控制分页打印、打印分页示例
Feb 08 Javascript
Jquery实现兼容各大浏览器的Enter回车切换输入焦点的方法
Sep 01 Javascript
JSON对象 详解及实例代码
Oct 18 Javascript
[js高手之路]单例模式实现模态框的示例
Sep 01 Javascript
vue中使用cropperjs的方法
Mar 01 Javascript
VeeValidate在vue项目里表单校验应用案例
May 09 Javascript
详解JavaScript对数组操作(添加/删除/截取/排序/倒序)
Apr 28 Javascript
小程序点击图片实现png转jpg
Oct 22 Javascript
vue 实现tab切换保持数据状态
Jul 21 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正则走开
2008/03/15 PHP
php使用GD创建保持宽高比缩略图的方法
2015/04/17 PHP
php代码检查代理ip的有效性
2016/08/19 PHP
php 一维数组的循环遍历实现代码
2017/04/10 PHP
JavaScript调用堆栈及setTimeout使用方法深入剖析
2013/02/16 Javascript
jquery实现简单合拢与展开网页面板的方法
2015/09/01 Javascript
JS实现状态栏跑马灯文字效果代码
2015/10/24 Javascript
Bootstrap3制作自己的导航栏
2016/05/12 Javascript
VUEJS实战之修复错误并且美化时间(2)
2016/06/13 Javascript
Js获取当前日期时间及格式化代码
2016/09/17 Javascript
EasyUI中的dataGrid的行内编辑
2017/06/22 Javascript
get  post jsonp三种数据交互形式实例详解
2017/08/25 Javascript
详解vue 计算属性与方法跟侦听器区别(面试考点)
2018/04/23 Javascript
解决vue select当前value没有更新到vue对象属性的问题
2018/08/30 Javascript
Vue中的$set的使用实例代码
2018/10/08 Javascript
element vue validate验证名称重复 输入框与后台重复验证 特殊字符 字符长度 及注意事项小结【实例代码】
2018/11/20 Javascript
jQuery实现的自定义轮播图功能详解
2018/12/28 jQuery
react中使用css的7中方式(最全总结)
2019/02/11 Javascript
layui 实现表单和文件上传一起传到后台的例子
2019/09/16 Javascript
Vue自定义组件双向绑定实现原理及方法详解
2020/09/03 Javascript
[59:00]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第一场 3月7日
2021/03/11 DOTA
python使用新浪微博api上传图片到微博示例
2014/01/10 Python
简洁的十分钟Python入门教程
2015/04/03 Python
python数组复制拷贝的实现方法
2015/06/09 Python
举例讲解Python中的Null模式与桥接模式编程
2016/02/02 Python
Python数据分析matplotlib设置多个子图的间距方法
2018/08/03 Python
使用Python在Windows下获取USB PID&VID的方法
2019/07/02 Python
pandas read_excel()和to_excel()函数解析
2019/09/19 Python
Python操作Word批量生成合同的实现示例
2020/08/28 Python
详解使用HTML5 Canvas创建动态粒子网格动画
2016/12/14 HTML / CSS
企业办公室主任岗位职责
2014/02/19 职场文书
大学生推广普通话演讲稿
2014/09/21 职场文书
班主任经验交流材料
2014/12/16 职场文书
休学证明范本
2015/06/19 职场文书
Python的这些库,你知道多少?
2021/06/09 Python
Java中PriorityQueue实现最小堆和最大堆的用法
2021/06/27 Java/Android