善用事件代理,警惕闭包的性能陷阱。


Posted in Javascript onJanuary 20, 2011

简言之,闭包是产生一个没有被释放资源的栈区。换言之,就是一个不可控的内存空间占用,如果与事件相关联,JS的垃圾回收机制也不会去触碰该区域。
例如:我们有个项目需要实现在一个div中有上百个热点区域(a标签),类似淘宝店铺广告位自定义,那么按照传统的做法,我们会如下做一个最典型的闭包使用的实例,目的是改变this的作用域,在其处理函数内部调用其他属于该作用域的方法或属性。

var apply = function() { 
this.div = document.getElementById("div的id"); 

this.hot = this.div.getElementsByTagName("a"); 

for(var i=0; i<this.hot.length; i++) { 


this.hot[i].onclick = function(me) { 



return function() { 




me.edit(this); 



} 


}(this); 

} 
} 
apply.prototype = { 

edit: function(target) { 

} 
}

这里产生的问题,就是每一次的循环,都会往内存当中写入一个如上所描述的不可控的内存地址,当然,你找不到它,也没办法在不需要使用的时候清理它,js的回收机制也不知道他何时是无用的,产生垃圾地址。并且,当div内的dom结构发生改变的时候,你又需要重新去找到这些a标签然后给他绑定事件。
当然你也可以把this添加到一个局部变量:var me = this; 至少如此是你可以控制的,你可以随时的将局部变量me置为null,js的垃圾回收机制会知道何时去清理掉这些无用的数据。但是这样也不是最好的解决方案,并且估计很多人也不会喜欢这种并不美观的编码方式。
最好的解决办法,当然还是并不需要去关心那些内部的结构,也不为内部的任何一个元素申明任何一个变量,那么就是事件代理的工作。何谓事件代理,即不需要为每一个子对象绑定事件,通过冒泡机制找到当前触发事件的元素,并通过你自己的一系列规则找到最终的处理函数。
如果使用事件代理的模式,该如何实现如上描述的需求?如下:
var apply = function() { 
this.div = document.getElementById("div的id"); 

this.div.onclick = function(me) { 


return function() { 



var _event = arguments.callee.caller.arguments[0]; 



var target = _event.target || _event.srcElement; 



if(target.tagName == "a") 




me.edit(target); 



else 




return false; 


} 

}(this); 
} 
apply.prototype = { 

edit: function(target) { 

} 
}

现在,我们只关心容器元素是何物,而不用关心他的内部有多少个a,他们是否发生改变等。性能的差别是显然的。
10来分钟随便写写,有点混乱,希望对一些朋友有用,如有差错之处,还望各位指点。

auntion / 2011-11-15
mail Auntion@gmail.com
QQ 82874972
原创文章,转载请留下此部分信息

Javascript 相关文章推荐
js获取指定日期前后的日期代码
Aug 20 Javascript
JavaScript 中的日期和时间及表示标准介绍
Aug 21 Javascript
JS字符串拼接在ie中都报错的解决方法
Mar 27 Javascript
JS实现浏览器状态栏文字从右向左弹出效果代码
Oct 27 Javascript
AngularJS 表达式详解及实例代码
Sep 14 Javascript
jQuery Easyui datagrid editor为combobox时指定数据源实例
Dec 19 Javascript
AngularJS ng-repeat指令及Ajax的应用实例分析
Jul 06 Javascript
Vue项目使用CDN优化首屏加载问题
Apr 01 Javascript
JavaScript设计模式之缓存代理模式原理与简单用法示例
Aug 07 Javascript
vue 使用自定义指令实现表单校验的方法
Aug 28 Javascript
微信小程序实现图片翻转效果的实例代码
Sep 20 Javascript
JavaScript算法学习之冒泡排序和选择排序
Nov 02 Javascript
jqeury eval将字符串转换json的方法
Jan 20 #Javascript
通过Jquery遍历Json的两种数据结构的实现代码
Jan 19 #Javascript
JQuery动态给table添加、删除行 改进版
Jan 19 #Javascript
jQuery 1.5最新版本的改进细节分析
Jan 19 #Javascript
基于Jquery与WebMethod投票功能实现代码
Jan 19 #Javascript
jQuery '行 4954 错误: 不支持该属性或方法' 的问题解决方法
Jan 19 #Javascript
Jquery插件 easyUI属性汇总
Jan 19 #Javascript
You might like
php文章内容分页并生成相应的htm静态页面代码
2010/06/07 PHP
PHP-Fcgi下PHP的执行时间设置方法
2013/08/02 PHP
Thinkphp中的curd应用实用要点
2015/01/04 PHP
PHP翻页跳转功能实现方法
2020/11/30 PHP
PHP实现原生态图片上传封装类方法
2016/11/08 PHP
JS 控制非法字符的输入代码
2009/12/04 Javascript
jquery处理页面弹出层查询数据等待操作实例
2015/03/25 Javascript
jquery实现可关闭的倒计时广告特效代码
2015/09/02 Javascript
js实现无缝滚动特效
2015/12/20 Javascript
浅谈js的html元素的父节点,子节点
2016/08/06 Javascript
JavaScript编码风格指南(中文版)
2016/08/26 Javascript
简单实现JavaScript图片切换效果
2016/11/28 Javascript
node安装--linux下的快速安装教程
2017/03/21 Javascript
React复制到剪贴板的示例代码
2017/08/22 Javascript
jQuery Validate插件ajax方式验证输入值的实例
2017/12/21 jQuery
vue中改变选中当前项的显示隐藏或者状态的实现方法
2018/02/08 Javascript
快速了解Node中的Stream流是什么
2019/02/13 Javascript
Echarts动态加载多条折线图的实现代码
2019/05/24 Javascript
微信小程序class封装http代码实例
2019/08/24 Javascript
js实现点赞按钮功能的实例代码
2020/03/06 Javascript
JavaScript实现手机号码 3-4-4格式并控制新增和删除时光标的位置
2020/06/02 Javascript
pandas的object对象转时间对象的方法
2018/04/11 Python
python画一个玫瑰和一个爱心
2020/08/18 Python
python cookie反爬处理的实现
2020/11/01 Python
安全检查管理制度
2014/02/02 职场文书
社团招新策划书
2014/02/04 职场文书
春季运动会广播稿大全
2014/02/19 职场文书
细节决定成败演讲稿
2014/05/12 职场文书
还款承诺书范文
2014/05/20 职场文书
工商管理专业毕业生自我鉴定2014
2014/10/04 职场文书
高中教师个人工作总结
2015/02/10 职场文书
营运督导岗位职责
2015/04/10 职场文书
2015秋季运动会通讯稿
2015/07/18 职场文书
承诺书的内容有哪些,怎么写?
2019/06/21 职场文书
python3实现Dijkstra算法最短路径的实现
2021/05/12 Python
SpringBoot SpringEL表达式的使用
2021/07/25 Java/Android