javascript闭包的用处
谈及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;
【完】
色即是空,空即是色,受想行识,亦复如是。
javascript闭包的用处的更多相关文章
- javascript 闭包(转)
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- JavaScript闭包学习笔记
此文都是大牛们关于闭包的观点,在此只是总结. 闭包应用的两种情况即可——函数作为返回值,函数作为参数传递. 1 深入理解javascript原型和闭包 判断一个变量是不是对象非常简单.值类型的类型判断 ...
- 对于 Javascript 闭包理解
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- 深入理解javascript闭包(一)
闭包(closure)是Javascript语言的一个难点.也是它的特色,非常多高级应用都要依靠闭包实现. 一.什么是闭包? 官方"的解释是:闭包是一个拥有很多变量和绑定了这些变量的环境的表 ...
- 深入理解javascript闭包(一)
原文转自脚本之家(http://www.jb51.net/article/24101.htm) 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...
- JavaScript“闭包”精解
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. 详细了解 Javascript语言的特殊之处,就在于函数内部可以直接读 ...
- JavaScript学习总结(十六)——Javascript闭包(Closure)
原文地址: http://www.cnblogs.com/xdp-gacl/p/3703876.html 闭包(closure)是Javascript语言的一个难点,也是它的特色, 很多高级应用都要依 ...
- [转载]学习Javascript闭包(Closure)
学习Javascript闭包(Closure) 源地址: http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures ...
- javascript闭包和this对象
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...
随机推荐
- [LC] 438. Find All Anagrams in a String
Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. Strings ...
- The Pomodoro Technique
目录 简介 What to solve How to use Some applications 自我总结 结束语 简介 番茄工作法是简单易行的时间管理方法,是由弗朗西斯科·西里洛于1992年创立的一 ...
- JavaScript学习总结(七)Ajax和Http状态字
转自:http://segmentfault.com/a/1190000000691919 Ajax及其工作原理 AJAX 是一种与服务器交换数据无需刷新网页的技术,最早由Google公司在谷歌地图里 ...
- <USACO06FEB>奶牛零食Treats for the Cowsの思路
写不来dp的日常 ....就这样吧 #include<cstdio> #include<cstring> #include<iostream> #include&l ...
- 831. KMP字符串
给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字. 模板串P在模式串S中多次作为子串出现. 求出模板串P在模式串S中所有出现的位置的起始下标. 输入格式 第一行输入整 ...
- 我是一个Bug, 终极大Bug
我是一个Bug ,在这个系统中潜伏很久了,历经多轮测试的严酷考验而屹立不倒,如果Bug界按难度分类的话,我绝对属于地狱模式. 现在,我就等待一个倒霉蛋来触发, 可是他老是不来. 其实不能叫倒霉蛋 , ...
- JavaScript学习之内存
初学JavaScript时,看红皮书了解了JS基本类型和引用类型在内存中的位置,结果看了简书里的一篇文章,发现对这块的了解还是有些缺陷. 基本类型 JavaScript中的基本类型有五种:Undefi ...
- JAVA如何判断两个字符串是否相等
==比较引用,equals 比较值 1.java中字符串的比较:== 我们经常习惯性的写上if(str1==str2),这种写法在java中可能会带来问题 example1: String a=&qu ...
- Python计算给定日期的周内的某一天
先理一下思路:1.weekday会根据某个日期返回0到6的一个数字来表示星期几对吧,0==星期一我们来列一个表: [0,1,2,3,4,5,6] 2.知道了星期几之后,你可以计算出那一周相对于这个0到 ...
- C++银行储蓄程序代码
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...