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


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中this关键字使用方法详解
Mar 08 Javascript
javascript 强制刷新页面的实现代码
Dec 13 Javascript
网页中表单按回车就自动提交的问题的解决方案
Nov 03 Javascript
JS+CSS3实现超炫的散列画廊特效
Jul 16 Javascript
JS 调用微信扫一扫功能
Dec 22 Javascript
详解JavaScript RegExp对象
Feb 04 Javascript
js基于myFocus实现轮播图效果
Feb 14 Javascript
jQuery插件HighCharts实现的2D堆条状图效果示例【附demo源码下载】
Mar 14 Javascript
es6数值的扩展方法
Mar 11 Javascript
vue-mugen-scroll组件实现pc端滚动刷新
Aug 16 Javascript
Vue 实现复制功能,不需要任何结构内容直接复制方式
Nov 09 Javascript
js实现QQ邮箱邮件拖拽删除功能
Aug 27 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加密解密的代码
2006/10/09 PHP
php 删除cookie和浏览器重定向
2009/03/16 PHP
php 升级到 5.3+ 后出现的一些错误,如 ereg(); ereg_replace(); 函数报错
2015/12/07 PHP
php实现的http请求封装示例
2016/11/08 PHP
php实现算术验证码功能
2018/12/05 PHP
PHP实现微信退款的方法示例
2019/03/26 PHP
thinkPHP5框架路由常用知识点汇总
2019/09/15 PHP
jQuery源码解读之hasClass()方法分析
2015/02/20 Javascript
JS控制伪元素的方法汇总
2016/04/06 Javascript
Laravel中常见的错误与解决方法小结
2016/08/30 Javascript
深入对Vue.js $watch方法的理解
2017/03/20 Javascript
Vue 过渡实现轮播图效果
2017/03/27 Javascript
JS实现简单短信验证码界面
2017/08/07 Javascript
vue中关闭eslint的方法分析
2018/08/04 Javascript
layUI实现列表查询功能
2019/07/27 Javascript
JavaScript 实现同时选取多个时间段的方法
2019/10/17 Javascript
windows下create-react-app 升级至3.3.1版本踩坑记
2020/02/17 Javascript
Bootstrap table 服务器端分页功能实现方法示例
2020/06/01 Javascript
jQuery实现购物车全功能
2021/01/11 jQuery
Python使用ntplib库同步校准当地时间的方法
2016/07/02 Python
python requests post多层字典的方法
2018/12/27 Python
python手机号前7位归属地爬虫代码实例
2020/03/31 Python
Python3-异步进程回调函数(callback())介绍
2020/05/02 Python
python不到50行代码完成了多张excel合并的实现示例
2020/05/28 Python
python 5个顶级异步框架推荐
2020/09/09 Python
Python3.9.1中使用match方法详解
2021/02/08 Python
感情真挚的毕业生求职信
2014/07/19 职场文书
财务工作失职检讨书
2014/11/21 职场文书
个人总结与自我评价2015
2015/03/11 职场文书
卫生院义诊活动总结
2015/05/07 职场文书
本科毕业答辩开场白
2015/05/27 职场文书
小马王观后感
2015/06/11 职场文书
学习商务礼仪心得体会
2016/01/22 职场文书
学习nginx基础知识
2021/09/04 Servers
详解Python中*args和**kwargs的使用
2022/04/07 Python
python pygame 开发五子棋双人对弈
2022/05/02 Python