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


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在光标位置插入内容的实现代码
Jun 18 Javascript
js+css使DIV始终居于屏幕中间 左下 左上 右上 右下的代码集合
Mar 10 Javascript
jquery 淡入淡出效果的简单实现
Feb 07 Javascript
jQuery中:input选择器用法实例
Jan 03 Javascript
jQuery中serializeArray()与serialize()的区别实例分析
Dec 09 Javascript
详解jQuery Mobile自定义标签
Jan 06 Javascript
javascript仿百度输入框提示自动下拉补全
Jan 07 Javascript
javascript拖拽效果延伸学习
Apr 04 Javascript
jQuery插件Validation表单验证详解
May 26 jQuery
浅谈Vue组件及组件的注册方法
Aug 24 Javascript
JavaScript实现汉字转换为拼音及缩写的方法示例
Mar 28 Javascript
vue 实现Web端的定位功能 获取经纬度
Aug 08 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
什么是调频(FM)、调幅(AM)、短波(SW)、长波(LW)
2021/03/01 无线电
使用WAMP搭建PHP本地开发环境
2017/05/10 PHP
Javascript异步编程模型Promise模式详细介绍
2014/05/08 Javascript
基于jquery实现轮播特效
2016/04/22 Javascript
jQuery unbind 删除绑定事件详解
2016/05/24 Javascript
JavaScript自学笔记(必看篇)
2016/06/23 Javascript
js实现方块上下左右移动效果
2017/08/17 Javascript
使用jquery+iframe做一个ajax上传效果(实例)
2017/08/24 jQuery
vue.js中引入vuex储存接口数据及调用的详细流程
2017/12/14 Javascript
JS实现的简单折叠展开动画效果示例
2018/04/28 Javascript
jquery3和layui冲突导致使用layui.layer.full弹出全屏iframe窗口时高度152px问题
2019/05/12 jQuery
解决IOS端微信H5页面软键盘弹起后页面下方留白的问题
2019/06/05 Javascript
vue3.0 自适应不同分辨率电脑的操作
2021/02/06 Vue.js
python函数缺省值与引用学习笔记分享
2013/02/10 Python
python实现封装得到virustotal扫描结果
2014/10/05 Python
利用一个简单的例子窥探CPython内核的运行机制
2015/03/30 Python
举例详解Python中yield生成器的用法
2015/08/05 Python
Python创建对称矩阵的方法示例【基于numpy模块】
2017/10/12 Python
python使用Apriori算法进行关联性解析
2017/12/21 Python
Python机器学习之决策树算法
2017/12/22 Python
Django unittest 设置跳过某些case的方法
2018/12/26 Python
Django框架自定义session处理操作示例
2019/05/27 Python
PyQt5实现从主窗口打开子窗口的方法
2019/06/19 Python
pytorch:torch.mm()和torch.matmul()的使用
2019/12/27 Python
Python连接Impala实现步骤解析
2020/08/04 Python
添柏岚英国官方网站:Timberland英国
2019/11/28 全球购物
数据库设计的包括哪两种,请分别进行说明
2016/07/15 面试题
旅游管理本科生求职信
2013/10/14 职场文书
自考毕业自我鉴定范文
2013/10/27 职场文书
应届毕业生自我鉴定范文
2013/12/27 职场文书
试用期员工考核制度
2014/01/22 职场文书
个人四风问题整改措施思想汇报
2014/10/04 职场文书
2015年库房工作总结
2015/04/30 职场文书
成绩单家长意见
2015/06/03 职场文书
MySQL创建索引需要了解的
2021/04/08 MySQL
利用Python读取微信朋友圈的多种方法总结
2021/08/23 Python