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


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扩展插件Validate—6 radio、checkbox、select的验证
Sep 05 Javascript
JavaScript中将一个值转换为字符串的方法分析[译]
Sep 21 Javascript
网页整体变灰白色(兼容各浏览器)实例
Apr 21 Javascript
Javascript实现页面跳转的几种方式分享
Oct 26 Javascript
JS判断两个时间大小的示例代码
Jan 28 Javascript
javascript中的遍历for in 以及with的用法
Dec 22 Javascript
js与jquery回车提交的方法
Feb 03 Javascript
谈谈jQuery Ajax用法详解
Nov 27 Javascript
jquery dataTable 获取某行数据
May 05 jQuery
Vue中使用的EventBus有生命周期
Jul 12 Javascript
vue-cli3脚手架的配置及使用教程
Aug 28 Javascript
JS实现点星星消除小游戏
Mar 24 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部分常见问题总结
2006/10/09 PHP
PHP count()函数讲解
2019/02/03 PHP
javascript基本语法分析说明
2008/06/15 Javascript
鼠标滑上去后图片放大浮出效果的js代码
2011/05/28 Javascript
js+xml生成级联下拉框代码
2012/07/24 Javascript
Javascript实现视频轮播在pc端与移动端均可
2013/09/29 Javascript
jQuery中选择器小问题(新人难免遇到)
2014/03/31 Javascript
jquery常用特效方法使用示例
2014/04/25 Javascript
PHP PDO操作总结
2014/11/17 Javascript
javascript跨域请求包装函数与用法示例
2016/11/03 Javascript
基于jQuery和Bootstrap框架实现仿知乎前端动态列表效果
2016/11/09 Javascript
AngularJS实现的锚点楼层跳转功能示例
2018/01/02 Javascript
基于打包工具Webpack进行项目开发实例
2018/05/29 Javascript
vue.js与后台数据交互的实例讲解
2018/08/08 Javascript
vue this.reload 方法 配置
2018/09/12 Javascript
vue+elementUI 复杂表单的验证、数据提交方案问题
2019/06/24 Javascript
vue ajax 拦截原理与实现方法示例
2019/11/29 Javascript
解决Vue @submit 提交后不刷新页面问题
2020/07/18 Javascript
[54:10]Spirit vs NB Supermajor小组赛 A组败者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
常用python数据类型转换函数总结
2014/03/11 Python
Python网络爬虫项目:内容提取器的定义
2016/10/25 Python
浅谈django开发者模式中的autoreload是如何实现的
2017/08/18 Python
Python列表list排列组合操作示例
2018/12/18 Python
Django异步任务之Celery的基本使用
2019/03/23 Python
使用python判断jpeg图片的完整性实例
2019/06/10 Python
tensorflow pb to tflite 精度下降详解
2020/05/25 Python
Python数据库封装实现代码示例解析
2020/09/05 Python
HTML5 实现图片上传预处理功能
2020/02/06 HTML / CSS
加拿大最大的相机店:Henry’s
2017/05/17 全球购物
好的自荐信的要求
2013/10/30 职场文书
数学教学随笔感言
2014/02/17 职场文书
建筑投标担保书
2014/05/20 职场文书
计算机考试作弊检讨书1000字
2015/01/01 职场文书
会计求职自荐信范文
2015/03/04 职场文书
毕业答辩开场白范文
2015/05/27 职场文书
基于Python实现西西成语接龙小助手
2022/08/05 Golang