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


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继承方式实例
Oct 29 Javascript
原生Js实现按的数据源均分时间点幻灯片效果(已封装)
Dec 28 Javascript
jquery自定义属性(类型/属性值)
May 21 Javascript
jQuery DOM插入节点操作指南
Mar 03 Javascript
jQuery遍历json的方法(推荐)
Jun 12 Javascript
Bootstrap的基本应用要点浅析
Dec 19 Javascript
Node.JS文件系统解析实例详解
May 15 Javascript
基于jQuery对象和DOM对象和字符串之间的转化实例
Aug 08 jQuery
mockjs,json-server一起搭建前端通用的数据模拟框架教程
Dec 18 Javascript
JavaScript累加、迭代、穷举、递归等常用算法实例小结
May 08 Javascript
11个教程中不常被提及的JavaScript小技巧(推荐)
Apr 17 Javascript
微信小程序开发常见问题及解决方案
Jul 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/04/01 PHP
浅谈php冒泡排序
2014/12/30 PHP
smarty自定义函数htmlcheckboxes用法实例
2015/01/22 PHP
WordPress中注册菜单与调用菜单的方法详解
2015/12/18 PHP
PHP有序表查找之二分查找(折半查找)算法示例
2018/02/09 PHP
PHP基于cookie实现统计在线人数功能示例
2019/01/16 PHP
cookie丢失问题(认证失效) Authentication (用户验证信息)也会丢失
2009/06/04 Javascript
Input 特殊事件onpopertychange和oninput
2009/06/17 Javascript
利用onresize使得div可以随着屏幕大小而自适应的代码
2010/01/15 Javascript
js控制页面控件隐藏显示的两种方法介绍
2013/10/09 Javascript
Nodejs+express+html5 实现拖拽上传
2014/08/08 NodeJs
js判断所有表单项不为空则提交表单的实现方法
2016/09/09 Javascript
nodejs连接mysql数据库简单封装示例-mysql模块
2017/04/10 NodeJs
React中的refs的使用教程
2018/02/13 Javascript
JavaScript闭包相关知识解析
2019/10/19 Javascript
js实现上下左右键盘控制div移动
2020/01/16 Javascript
Kettle中使用JavaScrip调用jar包对文件内容进行MD5加密的操作方法
2020/09/04 Javascript
python解析html开发库pyquery使用方法
2014/02/07 Python
改进Django中的表单的简单方法
2015/07/17 Python
用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动
2015/11/05 Python
基于循环神经网络(RNN)的古诗生成器
2018/03/26 Python
异步任务队列Celery在Django中的使用方法
2018/06/07 Python
python实现黑客字幕雨效果
2018/06/21 Python
vscode写python时的代码错误提醒和自动格式化的方法
2020/05/07 Python
如何利用pycharm进行代码更新比较
2020/11/04 Python
HTML5 source标签:媒介元素定义媒介资源
2018/01/29 HTML / CSS
百思买美国官网:Best Buy
2016/07/28 全球购物
Gap中国官网:美式休闲风服饰
2017/02/05 全球购物
百度JavaScript笔试题
2015/01/15 面试题
市场营销职业生涯规划书范文
2014/01/12 职场文书
文明学生标兵事迹
2014/01/21 职场文书
中文师范生自荐信
2014/01/30 职场文书
总经理司机岗位职责
2014/02/06 职场文书
高一新生军训感言
2014/03/02 职场文书
技术总监管理职责范本
2014/03/06 职场文书
Nginx图片服务器配置之后图片访问404的问题解决
2022/03/21 Servers