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


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 相关文章推荐
Sample script that deletes a SQL Server database
Jun 16 Javascript
Javascript学习指南
Dec 01 Javascript
javascript+css3 实现动态按钮菜单特效
Feb 06 Javascript
jquery插件Jplayer使用方法简析
Apr 22 Javascript
JS读取XML文件数据并以table形式显示数据的方法(兼容IE与火狐)
Jun 02 Javascript
简单实现js浮动框
Dec 13 Javascript
详解express与koa中间件模式对比
Aug 07 Javascript
JavaScript树的深度优先遍历和广度优先遍历算法示例
Jul 30 Javascript
JS实现百度网盘任意文件强制下载功能
Aug 31 Javascript
详解vue-cli3 中跨域解决方案
Apr 10 Javascript
jQuery实现中奖播报功能(让文本滚动起来) 简单设置数值即可
Mar 20 jQuery
jQuery+css实现的点击图片放大缩小预览功能示例【图片预览 查看大图】
May 29 jQuery
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
星际争霸 Starcraft 秘技补丁
2020/03/14 星际争霸
php下批量挂马和批量清马代码
2011/02/27 PHP
利用PHP自动生成印有用户信息的名片
2016/08/01 PHP
Yii框架的布局文件实例分析
2019/09/04 PHP
My Desktop :) 桌面式代码
2008/12/29 Javascript
jQuery 图片切换插件(代码比较少)
2012/05/07 Javascript
js禁止页面刷新禁止用F5键刷新禁止右键的示例代码
2013/09/23 Javascript
查找页面中所有类为test的结点的方法
2014/03/28 Javascript
jquery实现像栅栏一样左右滑出式二级菜单效果代码
2015/08/24 Javascript
JS插件overlib用法实例详解
2015/12/26 Javascript
jQuery实现简单的下拉菜单导航功能示例
2017/12/07 jQuery
解决Vue中mounted钩子函数获取节点高度出错问题
2018/05/18 Javascript
JS实现头条新闻的经典轮播图效果示例
2019/01/30 Javascript
elementUI 动态生成几行几列的方法示例
2019/07/11 Javascript
15 分钟掌握vue-next响应式原理
2019/10/13 Javascript
python测试驱动开发实例
2014/10/08 Python
Python编写百度贴吧的简单爬虫
2015/04/02 Python
初步介绍Python中的pydoc模块和distutils模块
2015/04/13 Python
Python数据类型学习笔记
2016/01/13 Python
Python的Socket编程过程中实现UDP端口复用的实例分享
2016/03/19 Python
python实现汉诺塔方法汇总
2016/07/25 Python
Numpy中stack(),hstack(),vstack()函数用法介绍及实例
2018/01/09 Python
python使用logging模块发送邮件代码示例
2018/01/18 Python
python3.7 使用pymssql往sqlserver插入数据的方法
2019/07/08 Python
Django学习之文件上传与下载
2019/10/06 Python
Python numpy线性代数用法实例解析
2019/11/15 Python
Django 创建后台,配置sqlite3教程
2019/11/18 Python
python numpy数组中的复制知识解析
2020/02/03 Python
TensorFlow tf.nn.softmax_cross_entropy_with_logits的用法
2020/04/19 Python
Gap中国官网:美式休闲风服饰
2017/02/05 全球购物
介绍一下.NET构架下remoting和webservice
2014/05/08 面试题
鲜果饮品店创业计划书
2014/01/21 职场文书
法人身份证明书
2014/10/08 职场文书
优秀大学生事迹材料
2014/12/24 职场文书
节水宣传标语口号
2015/12/26 职场文书
Android中的Launch Mode详情
2022/06/05 Java/Android