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


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 相关文章推荐
javascript事件模型代码
Jul 01 Javascript
完美解决AJAX跨域问题
Nov 01 Javascript
jQuery中:file选择器用法实例
Jan 04 Javascript
JavaScript判断FileUpload控件上传文件类型
Sep 28 Javascript
JS动态改变浏览器标题的方法
Apr 06 Javascript
图文详解Heap Sort堆排序算法及JavaScript的代码实现
May 04 Javascript
jquery组件WebUploader文件上传用法详解
Oct 23 Javascript
js阻止移动端页面滚动的两种方法
Jan 25 Javascript
vue 中自定义指令改变data中的值
Jun 02 Javascript
webpack4.0打包优化策略整理小结
Mar 30 Javascript
Vue+axios+WebApi+NPOI导出Excel文件实例方法
Jun 05 Javascript
Vue项目开发常见问题和解决方案总结
Sep 11 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学习笔记之基础知识
2014/11/08 PHP
PHP递归复制、移动目录的自定义函数分享
2014/11/18 PHP
详解WordPress中的头像缓存和代理中的缓存更新方法
2016/03/01 PHP
php实现算术验证码功能
2018/12/05 PHP
js修改table中Td的值(定义td的单击事件)
2013/01/10 Javascript
document.forms[].submit()使用介绍
2014/02/19 Javascript
一款基于jQuery的图片场景标注提示弹窗特效
2015/01/05 Javascript
浅谈JavaScript中的string拥有方法的原因
2015/08/28 Javascript
实例详解AngularJS实现无限级联动菜单
2016/01/15 Javascript
Node.js利用Net模块实现多人命令行聊天室的方法
2016/12/23 Javascript
详解javascript中对数据格式化的思考
2017/01/23 Javascript
用JavaScript和jQuery实现瀑布流
2017/03/19 Javascript
JS对象和字符串之间互换操作实例分析
2019/02/02 Javascript
微信小程序实现上传word、txt、Excel、PPT等文件功能
2019/05/23 Javascript
js遍历详解(forEach, map, for, for...in, for...of)
2019/08/28 Javascript
python和pyqt实现360的CLable控件
2014/02/21 Python
使用Python压缩和解压缩zip文件的教程
2015/05/06 Python
举例讲解Python中的算数运算符的用法
2015/05/13 Python
如何用Python实现简单的Markdown转换器
2018/07/16 Python
Python可迭代对象操作示例
2019/05/07 Python
10 行Python 代码实现 AI 目标检测技术【推荐】
2019/06/14 Python
Python实现微信好友的数据分析
2019/12/16 Python
TensorFlow2.1.0最新版本安装详细教程
2020/04/08 Python
如何基于线程池提升request模块效率
2020/04/18 Python
详解Python3.8+PyQt5+pyqt5-tools+Pycharm配置详细教程
2020/11/02 Python
HTML5触摸事件实现移动端简易进度条的实现方法
2018/05/04 HTML / CSS
手工制作的意大利礼服鞋:Ace Marks
2018/12/15 全球购物
Spotahome意大利:公寓和房间出租
2020/02/21 全球购物
Molton Brown美国官网:奢华美容、香水、沐浴和身体护理
2020/09/02 全球购物
数控专业大学生的自我鉴定
2013/11/13 职场文书
新驾驶员个人自我评价
2014/01/03 职场文书
中国文明网签名寄语
2014/01/18 职场文书
2014年父亲节活动方案
2014/03/06 职场文书
关于观后感的作文
2015/06/18 职场文书
海底两万里读书笔记
2015/06/26 职场文书
初中历史教学反思
2016/02/19 职场文书