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


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 相关文章推荐
腾讯与新浪的通过IP地址获取当前地理位置(省份)的接口
Jul 26 Javascript
JSChart轻量级图形报表工具(内置函数中文参考)
Oct 11 Javascript
JavaScript控制Session操作方法
Jan 17 Javascript
js使下拉列表框可编辑不止是选择
Dec 12 Javascript
jQuery的context属性用法实例
Dec 27 Javascript
原生js和jquery实现图片轮播特效
Apr 23 Javascript
jQuery实现鼠标经过提示信息的地图热点效果
Apr 26 Javascript
通过js获取上传的图片信息(临时保存路径,名称,大小)然后通过ajax传递给后端的方法
Oct 01 Javascript
深入理解jQuery layui分页控件的使用
Aug 17 Javascript
JS 事件绑定、事件监听、事件委托详细介绍
Sep 28 Javascript
浅谈js中的this问题
Aug 31 Javascript
VUE中使用MUI方法
Feb 12 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代码运行时间查看类代码分享
2011/08/06 PHP
file_get_contents获取不到网页内容的解决方法
2013/03/07 PHP
关于二级目录拖拽排序的实现(源码示例下载)
2013/04/26 PHP
PHP获取ip对应地区和使用网络类型的方法
2015/03/11 PHP
PHP获取当前日期和时间及格式化方法参数
2015/05/11 PHP
php实现通过ftp上传文件
2015/06/19 PHP
PHP最常用的正则表达式
2017/02/13 PHP
PHP如何实现订单的延时处理详解
2017/12/30 PHP
浅谈PHP之ThinkPHP框架使用详解
2020/07/21 PHP
JavaScript之引用类型介绍
2012/08/10 Javascript
js 数组去重的四种实用方法
2014/09/09 Javascript
JavaScript父子窗体间的调用方法
2015/03/31 Javascript
Nodejs学习笔记之测试驱动
2015/04/16 NodeJs
JS实现定时自动关闭DIV层提示框的方法
2015/05/11 Javascript
jQuery 1.9.1源码分析系列(十五)之动画处理
2015/12/03 Javascript
一道优雅面试题分析js中fn()和return fn()的区别
2016/07/05 Javascript
判断横屏竖屏(三种)
2017/02/13 Javascript
JS按条件 serialize() 对应标签的使用方法
2017/07/24 Javascript
vue2.0+vue-dplayer实现hls播放的示例
2018/03/02 Javascript
解决nodejs的npm命令无反应的问题
2018/05/17 NodeJs
vue将单页面改造成多页面应用的方法
2018/11/25 Javascript
Python 读写文件和file对象的方法(推荐)
2016/09/12 Python
基于python实现在excel中读取与生成随机数写入excel中
2018/01/04 Python
python字符串的拼接方法总结
2019/11/18 Python
使用Tensorflow将自己的数据分割成batch训练实例
2020/01/20 Python
Python 面向对象之类class和对象基本用法示例
2020/02/02 Python
HTML5自定义视频播放器源码
2020/01/06 HTML / CSS
澳大利亚办公室装修:JasonL Office Furniture
2019/06/25 全球购物
简单的JAVA编程面试题
2013/03/19 面试题
计算机专业个人求职自荐信
2013/09/21 职场文书
大学毕业登记表自我鉴定
2013/10/09 职场文书
学雷锋月活动总结
2014/04/25 职场文书
党员剖析材料范文
2014/09/30 职场文书
拾金不昧表扬稿
2015/01/16 职场文书
有趣的二维码:使用MyQR和qrcode来制作二维码
2021/05/10 Python