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


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接口 方便获取当前用户的ip地理位置
Nov 25 Javascript
节点的插入之append()和appendTo()的用法介绍
Jan 13 Javascript
jQuery中prop()方法用法实例
Jan 05 Javascript
HTML5使用DeviceOrientation实现摇一摇功能
Jun 05 Javascript
JavaScript中数据结构与算法(一):栈
Jun 19 Javascript
js实现页面a向页面b传参的方法
May 29 Javascript
深入理解JavaScript定时机制
Oct 27 Javascript
微信小程序 滚动到某个位置添加class效果实现代码
Apr 19 Javascript
微信小程序实现之手势锁功能实例代码
Jul 19 Javascript
vue文件运行的方法教学
Feb 12 Javascript
Vuex mutitons和actions初使用详解
Mar 04 Javascript
如何用JS实现简单的数据监听
May 06 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 stream_context_create()函数的使用示例
2015/05/12 PHP
Yii快速入门经典教程
2015/12/28 PHP
PHP互换两个变量值的方法(不用第三变量)
2016/11/14 PHP
Laravel 5.5基于内置的Auth模块实现前后台登陆详解
2017/12/21 PHP
JavaScript 函数式编程的原理
2009/10/16 Javascript
分享一个自己写的table表格排序js插件(高效简洁)
2011/10/29 Javascript
jquery ajax请求实例深入解析
2012/11/26 Javascript
js点击事件链接的问题解决
2014/04/25 Javascript
Javascript 计算字符串在localStorage中所占字节数
2015/10/21 Javascript
详解XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度
2016/09/14 Javascript
基于JQuery和原生JavaScript实现网页定位导航特效
2017/04/03 jQuery
Three.js基础学习教程
2017/11/16 Javascript
详解vue中点击空白处隐藏div的实现(用指令实现)
2018/04/19 Javascript
NodeJS 将文件夹按照存放路径变成一个对应的JSON的方法
2018/10/17 NodeJs
通过vue写一个瀑布流插件代码实例
2019/09/07 Javascript
VUE注册全局组件和局部组件过程解析
2019/10/10 Javascript
vue实现随机验证码功能(完整代码)
2019/12/10 Javascript
在vue中实现清除echarts上次保留的数据(亲测有效)
2020/09/09 Javascript
在python3环境下的Django中使用MySQL数据库的实例
2017/08/29 Python
Python向Excel中插入图片的简单实现方法
2018/04/24 Python
Centos下实现安装Python3.6和Python2共存
2018/08/15 Python
Python 通过打码平台实现验证码的实现
2019/05/13 Python
PyQt5使用QTimer实现电子时钟
2019/07/29 Python
Django 后台获取文件列表 InMemoryUploadedFile的例子
2019/08/07 Python
python3 selenium自动化 frame表单嵌套的切换方法
2019/08/23 Python
Pytorch 使用 nii数据做输入数据的操作
2020/05/26 Python
如何使用 Python 读取文件和照片的创建日期
2020/09/05 Python
可以随进度显示不同颜色的css3进度条分享
2014/04/11 HTML / CSS
纯css3实现照片墙效果
2014/12/26 HTML / CSS
基于HTML5 Canvas 实现弹出框效果
2017/06/05 HTML / CSS
如何使用amaze ui的分页样式封装一个通用的JS分页控件
2020/08/21 HTML / CSS
师范生实习个人的自我评价
2013/09/28 职场文书
项目资料员岗位职责
2013/12/10 职场文书
制药工程专业毕业生推荐信
2013/12/24 职场文书
《海底世界》教学反思
2014/04/16 职场文书
单位工作证明范文
2014/09/14 职场文书