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


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 相关文章推荐
Jquery增加鼠标中间功能mousewheel的实例代码
Sep 05 Javascript
jquery复选框多选赋值给文本框的方法
Jan 27 Javascript
PHP 数组current和next用法分享
Mar 05 Javascript
学习使用AngularJS文件上传控件
Feb 16 Javascript
JavaScript实现解析INI文件内容的方法
Nov 17 Javascript
jQuery实现锚点向下平滑滚动特效示例
Aug 29 jQuery
微信小程序 网络通信实现详解
Jul 23 Javascript
js单线程的本质 Event Loop解析
Oct 29 Javascript
40行代码把Vue3的响应式集成进React做状态管理
May 20 Javascript
如何在JavaScript中等分数组的实现
Dec 13 Javascript
JavaScript代码实现简单计算器
Dec 27 Javascript
原生js拖拽功能制作滑动条实例代码
Feb 05 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中判断数组是一维,二维,还是多维的解决方法
2013/05/04 PHP
Ajax+PHP实现的删除数据功能示例
2019/02/12 PHP
javascript Array.remove() 数组删除
2009/08/06 Javascript
JavaScript获取网页表单action属性的方法
2015/04/02 Javascript
jQuery子窗体取得父窗体元素的方法
2015/05/11 Javascript
详解JavaScript正则表达式中的global属性的使用
2015/06/16 Javascript
jQuery.Callbacks()回调函数队列用法详解
2016/06/14 Javascript
jQuery 遍历map()方法详解
2016/11/04 Javascript
利用JS轻松实现获取表单数据
2016/12/06 Javascript
详解基于angular路由的requireJs按需加载js
2017/01/20 Javascript
Vuejs 组件——props数据传递的实例代码
2017/03/07 Javascript
原生JS实现循环Nodelist Dom列表的4种方式示例
2018/02/11 Javascript
vue2单元测试环境搭建
2018/05/24 Javascript
jQuery AJAX 方法success()后台传来的4种数据详解
2018/08/08 jQuery
浅谈Vue render函数在ElementUi中的应用
2018/09/06 Javascript
vue 使用高德地图vue-amap组件过程解析
2019/09/07 Javascript
微信小程序实现点击导航条切换页面
2020/11/19 Javascript
Javascript生成器(Generator)的介绍与使用
2021/01/31 Javascript
[01:30]DOTA2上海特锦赛现场采访 Loda倾情献唱
2016/03/25 DOTA
[48:35]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 TNC vs Optic
2018/04/03 DOTA
Python(Tornado)模拟登录小米抢手机
2013/11/12 Python
python单链表实现代码实例
2013/11/21 Python
videocapture库制作python视频高速传输程序
2013/12/23 Python
Python3.6笔记之将程序运行结果输出到文件的方法
2018/04/22 Python
Pytorch Tensor的索引与切片例子
2019/08/18 Python
Keras 利用sklearn的ROC-AUC建立评价函数详解
2020/06/15 Python
如何解决pycharm调试报错的问题
2020/08/06 Python
Python离线安装各种库及pip的方法
2020/11/28 Python
比利时网上药店: Drogisterij.net
2017/03/17 全球购物
丝芙兰意大利官方网站:Sephora.it
2019/12/13 全球购物
几个常见的软件测试问题
2016/09/07 面试题
新员工培训个人的自我评价
2013/10/09 职场文书
护理助产毕业生的求职信
2014/03/02 职场文书
贷款担保书范文
2014/05/13 职场文书
运动会演讲稿50字
2014/08/25 职场文书
用React Native制作一个简单的游戏引擎
2021/05/27 Javascript