谈及javascript的闭包,可能想到的就是内存泄露,慎用闭包,但是实际上闭包还有更多好的作用:

1,可以将for循环的变量封闭在闭包环境中,下面这种情况,无论点击1-5div,最终打印的都是5,因为点击事件是异步,for循环时候,i是同一个,最终都会进阶到5,所以输出5。使用闭包进行i变量的封闭保存。

<html>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</body>
<script>
var nodes = document.getElementsByTagName('div');
for(var i = 0;i<nodes.length;i++){
nodes[i].onclick = function(){
console.log(i)
}
}
</script>
</html>
for(var i = 0;i<nodes.length;i++){
(function(k){
nodes[k].onclick = function(){
console.log(k)
}
})(i)
}

2,封装变量

可以将一些不需要暴露在全局的变量封装成“私有变量”,比如下面的cache变量是可以抽成局部变量,不需要暴漏在全局,闭包就可以封装变量。

var mult = (function(){
var cache = {};
return function(){
var args = Array.prototype.join.call(arguments,',');
if(cache[args]){
return cache[args]
}
var a = 1;
for(var i = 0,l = arguments.length;i<l;i++){
a = a * arguments[i]
}
return cache[args] = a;
}
})() console.log(mult(1,2,3))

3,延续局部变量的寿命

var report = function(src){
var img = new Image();
img.src = src;
} report('http://xxx.com/getUserInfo')

该函数在低版本的浏览器会存在数据上报丢失的bug,原因是report函数在调用结束后,img局部变量被销毁,或许没来得及发送http请求,请求就丢失掉,应该将img变量用闭包封闭起来。

var report = (function(){
var imgs = [];
return function(src){
var img = new Image();
imgs.push(img);
img.src = src;
}
})()

闭包会导致内存泄露,尽量减少闭包的使用,这种说话恐怕有点骇人听闻,不过局部变量在函数退出时候没有被销毁确实会导致内存泄露,但是闭包的好处却常常被忽略,有时候我们主动选择将变量封闭在闭包中,可能后续还会用到这个变量,这时候放在全局和放在闭包中对内存的影响是一致的,如果将来需要回收这些变量,可以手动设为null即可。

使用闭包容易导致循环引用。如果闭包的作用域链中存在一些DOM节点,这时就容易引起内存泄露。其实一些变量的内存泄露就是变量没有被及时回收,这些对系统的影响不是很大,最可怕的就是循环引用,会立马导致内存飙升,这个是要重视的点。

解决循环引用带来的内存泄露,也是将其中的变量设置为null即可。

说说js循环引用的例子:

var a={b:1};
a.b=a;

猜测下a的最终输出,{b:{b:{b:{b:......}}}}

用console打印是不会报错的,但是JSON.stringify(a)会报错,循环引用使用该语法报错。

var a={"name":"zzz"};
var b={"name":"vvv"};
a.child=b;
b.parent=a;

上面的例子也是一个循环引用。a和b对象互相引用,内存得不到释放。

还有js对象和COM对象的循环引用:

IE中有一部分对象并不是原生的js对象,而是COM对象,采用计数策略,例子:

var element = document.getElementById("some_element");
var myObject = new Object();
myObject.element = element;
element.someObject = myObject;

一个DOM元素和原生js对象之间存在循环引用,即使DOM从页面移除,也不会被回收,因为myObject仍然在引用。

避免循环引用发生,最好在不用时候切断js对象和dom元素之间的连接。

myObject.element = null;

element.someObject = null;

【完】

色即是空,空即是色,受想行识,亦复如是。

  

最新文章

  1. C#学习笔记-ContextMenuStrip
  2. (iOS)项目总结-项目中遇到的各种的问题和解决方法
  3. knockoutJS+knockout.multimodels使用记录
  4. 入门Linux
  5. js获取文本框输入的值
  6. (转)SqlServer数据库大型应用解决方案总结
  7. uploadify插件的使用
  8. N-Queens 解答
  9. 03.Msbuild
  10. Oracle Applications Multiple Organizations Access Control for Custom Code
  11. Centos7完全分布式搭建Hadoop2.7.3
  12. 显示图像的SIFT flow描述子
  13. mysql-linux定时备份mysql数据库
  14. 简易DVD查询系统
  15. Service 和 IntentService的区别;
  16. JSON数据的各种操作
  17. LED驱动程序分析
  18. IIS中利用ARR实现反向代理
  19. iOS:UIButton按钮的详解
  20. 【MySQL函数】日期篇

热门文章

  1. ISIS
  2. ROC曲线、KS曲线
  3. spring事务管理(xml配置)与spring自带连接数据库JdbcTemplate
  4. struts2 标签s:select在table中单行显示
  5. 4k高分屏下,chm帮助文档,api文档打开后字体过小的解决
  6. string删除与查找erase,find
  7. CentOS7下MySQL5.7的安装-RPM方式
  8. Redis 中 byte格式 写入、取出
  9. Python【map、reduce、filter】内置函数使用说明
  10. classnames