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


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 相关文章推荐
js解析xml字符串和xml文档实现原理及代码(针对ie与火狐)
Feb 02 Javascript
鼠标经过显示二级菜单js特效
Aug 13 Javascript
js弹出div并显示遮罩层
Feb 12 Javascript
Area 区域实现post提交数据的js写法
Apr 22 Javascript
javascript数字时钟示例分享
Apr 23 Javascript
js H5 canvas投篮小游戏
Aug 18 Javascript
JS实现屏蔽网页右键复制及ctrl+c复制的方法【2种方法】
Sep 04 Javascript
js实现手机拍照上传功能
Jan 17 Javascript
JavaScript判断浏览器和hack滚动条的写法
Jul 23 Javascript
浅谈Vue.use的使用
Aug 29 Javascript
jQuery实现鼠标移入显示蒙版效果
Jan 11 jQuery
JS获取一个字符串中指定字符串第n次出现的位置
Feb 10 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
thinkphp在模型中自动完成session赋值示例代码
2014/09/09 PHP
PHP网站建设的流程与步骤分享
2015/09/25 PHP
php_pdo 预处理语句详解
2016/11/21 PHP
js数组操作学习总结
2013/11/04 Javascript
Redis基本知识、安装、部署、配置笔记
2015/03/05 Javascript
第八篇Bootstrap下拉菜单实例代码
2016/06/21 Javascript
JS禁止查看网页源代码的实现方法
2016/10/12 Javascript
扩展Bootstrap Tooltip插件使其可交互的方法
2016/11/07 Javascript
浅谈react-native热更新react-native-pushy集成遇到的问题
2017/09/30 Javascript
js实现Tab选项卡切换效果
2020/07/17 Javascript
Vue computed 计算属性代码实例
2020/04/22 Javascript
Vue利用localStorage本地缓存使页面刷新验证码不清零功能的实现
2020/09/04 Javascript
Python实现设置windows桌面壁纸代码分享
2015/03/28 Python
举例简单讲解Python中的数据存储模块shelve的用法
2016/03/03 Python
结合Python的SimpleHTTPServer源码来解析socket通信
2016/06/27 Python
详解python 字符串和日期之间转换 StringAndDate
2017/05/04 Python
python3写的简单本地文件上传服务器实例
2018/06/04 Python
新手如何发布Python项目开源包过程详解
2019/07/11 Python
Pandas中DataFrame的分组/分割/合并的实现
2019/07/16 Python
Python 函数绘图及函数图像微分与积分
2019/11/20 Python
python3 logging日志封装实例
2020/04/08 Python
在keras里实现自定义上采样层
2020/06/28 Python
Python变量格式化输出实现原理解析
2020/08/06 Python
微信端html5页面调用分享接口示例
2018/03/14 HTML / CSS
美国女士泳装店:Swimsuits For All
2017/03/02 全球购物
Vrbo西班牙:预订您的度假公寓(公寓、乡村房屋…)
2020/04/27 全球购物
internal修饰符起什么作用
2013/12/16 面试题
介绍下java.util.Arrays类
2012/10/16 面试题
保险专业大学生职业规划书
2014/03/03 职场文书
我爱读书演讲稿
2014/05/07 职场文书
宣传标语大全
2014/07/01 职场文书
学校节能宣传周活动总结
2014/07/09 职场文书
2014年班级工作总结
2014/11/14 职场文书
2014年社区教育工作总结
2014/12/02 职场文书
2014预防青少年违法犯罪工作总结
2014/12/10 职场文书
从结婚开始的恋爱故事。小说《我的美好婚事》TV动画化决定
2022/04/07 日漫