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


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 相关文章推荐
jQuery 验证插件 Web前端设计模式(asp.net)
Oct 17 Javascript
javascript学习笔记(七)利用javascript来创建和存储cookie
Apr 08 Javascript
原生javascript兼容性测试实例
Jul 01 Javascript
JS delegate与live浅析
Dec 21 Javascript
javascript实现淘宝幻灯片广告展示效果
Apr 27 Javascript
jQuery下拉框的简单应用
Jun 24 Javascript
jquery操作ID带有变量的节点实例
Dec 07 Javascript
js阻止默认右键的下拉菜单方法
Jan 02 Javascript
vue实现文件上传功能
Aug 13 Javascript
JavaScript碎片—函数闭包(模拟面向对象)
Mar 13 Javascript
javascript实现遮罩层动态效果实例
May 14 Javascript
webpack常用构建优化策略小结
Nov 21 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 mysql索引问题
2008/06/07 PHP
phpmyadmin 3.4 空密码登录的实现方法
2010/05/29 PHP
采用header定义为文件然后readfile下载(隐藏下载地址)
2014/01/31 PHP
php-fpm添加service服务的例子
2018/04/27 PHP
jQuery下通过$.browser来判断浏览器.
2011/04/05 Javascript
ASP.NET jQuery 实例10 动态修改hyperlink的URL值
2012/02/03 Javascript
一个基于jquery的文本框记数器
2012/09/19 Javascript
JavaScript数组Array对象增加和删除元素方法总结
2015/01/20 Javascript
Angular中的Promise对象($q介绍)
2015/03/03 Javascript
javascript实现随时变化着的背景颜色
2015/04/02 Javascript
JavaSacript中charCodeAt()方法的使用详解
2015/06/05 Javascript
jquery UI Datepicker时间控件的使用及问题解决
2016/04/28 Javascript
完美解决JS文件页面加载时的阻塞问题
2016/12/18 Javascript
Bootstrap 模态框(Modal)插件代码解析
2016/12/21 Javascript
JS使用插件cryptojs进行加密解密数据实例
2017/05/11 Javascript
原生JavaScrpit中异步请求Ajax实现方法
2017/11/03 Javascript
用JavaScript实现贪吃蛇游戏
2020/10/23 Javascript
[33:42]LGD vs OG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[01:23:45]DOTA2-DPC中国联赛 正赛 CDEC vs Dragon BO3 第一场 1月22日
2021/03/11 DOTA
浅谈Python 对象内存占用
2016/07/15 Python
Python断言assert的用法代码解析
2018/02/03 Python
python解决字符串倒序输出的问题
2018/06/25 Python
pandas 按照特定顺序输出的实现代码
2018/07/10 Python
Opencv+Python实现图像运动模糊和高斯模糊的示例
2019/04/11 Python
python turtle库画一个方格和圆实例
2019/06/27 Python
python爬虫中url管理器去重操作实例
2020/11/30 Python
HTML5 新旧语法标记对我们有什么好处
2012/12/13 HTML / CSS
机电一体化专业应届生求职信
2013/11/27 职场文书
工程质量月活动方案
2014/02/19 职场文书
超市开学活动方案
2014/03/01 职场文书
入职担保书范文
2014/05/21 职场文书
学习型班组申报材料
2014/05/31 职场文书
运动会口号16字
2014/06/07 职场文书
2016年五一劳动节专题校园广播稿
2015/12/17 职场文书
缓存替换策略及应用(以Redis、InnoDB为例)
2021/07/25 Redis
使用python绘制横竖条形图
2022/04/21 Python