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


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图片平滑连续滚动插件
Apr 27 Javascript
js检查页面上有无重复id的实现代码
Jul 17 Javascript
删除节点的jquery代码
Jan 13 Javascript
textarea焦点的用法实现获取焦点清空失去焦点提示效果
May 19 Javascript
一个字符串反转函数可实现字符串倒序
Sep 15 Javascript
浅谈javascript中this在事件中的应用
Feb 15 Javascript
JavaScript使用concat连接数组的方法
Apr 06 Javascript
JS实现弹出浮动窗口(支持鼠标拖动和关闭)实例详解
Aug 06 Javascript
Bootstrap table表格简单操作
Feb 07 Javascript
利用NPM淘宝的node.js镜像加速nvm
Mar 27 Javascript
如何使用webpack打包一个库library的方法步骤
Dec 18 Javascript
vue结合el-upload实现腾讯云视频上传功能
Jul 01 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
杏林同学录(四)
2006/10/09 PHP
php compact 通过变量创建数组
2016/11/15 PHP
PhpStorm2020 + phpstudyV8 +XDebug的教程详解
2020/09/17 PHP
cssQuery()的下载与使用方法
2007/01/12 Javascript
讲两件事:1.this指针的用法小探. 2.ie的attachEvent和firefox的addEventListener在事件处理上的区别
2007/04/12 Javascript
JavaScript 继承详解(三)
2009/07/13 Javascript
jquery 事件执行检测代码
2009/12/09 Javascript
Jquery异步请求数据实例代码
2011/12/28 Javascript
window.open打开页面居中显示的示例代码
2013/12/27 Javascript
jquery和javascript中如何将一元素的内容赋给另一元素
2014/01/09 Javascript
实践中学习AngularJS表单
2016/03/21 Javascript
Angularjs 制作购物车功能实例代码
2016/09/14 Javascript
jquery实现输入框实时输入触发事件代码
2016/12/21 Javascript
jQuery实现圣诞节礼物传送(花式轮播)
2016/12/25 Javascript
详谈js模块化规范
2017/07/07 Javascript
一文读懂ES7中的javascript修饰器
2019/05/06 Javascript
微信小程序中如何计算距离某个节日还有多少天
2019/07/15 Javascript
js实现网页随机验证码
2020/10/19 Javascript
原生小程序封装跑马灯效果
2020/10/21 Javascript
使用Python的Tornado框架实现一个一对一聊天的程序
2015/04/25 Python
Python实现的简单dns查询功能示例
2017/05/24 Python
python取代netcat过程分析
2018/02/10 Python
python 判断字符串中是否含有汉字或非汉字的实例
2019/07/15 Python
django页面跳转问题及注意事项
2019/07/18 Python
Keras 切换后端方式(Theano和TensorFlow)
2020/06/19 Python
python使用matplotlib:subplot绘制多个子图的示例
2020/09/24 Python
营业经理岗位职责
2013/11/10 职场文书
项目计划书范文
2014/01/09 职场文书
优秀本科毕业生自荐信
2014/07/04 职场文书
2014年办公室工作总结范文
2014/11/12 职场文书
本溪水洞导游词
2015/02/11 职场文书
2015年清明节网上祭英烈活动总结
2015/03/26 职场文书
2015年电话销售工作总结范文
2015/04/20 职场文书
学生会干部任命书
2015/09/21 职场文书
2015年新教师个人工作总结
2015/10/14 职场文书
winserver2019安装软件一直卡在应用程序正在为首次使用做准备
2022/06/10 Servers