详解 js 闭包_网站前端开发_前端开发者

网站前端开发_前端开发者node.jshttps://www.rokub.com

详解 JavaScript 闭包。 闭包( closure) 是 Javascript 语言的一个难点, 也是它的特色, 很多高级应用都要依靠闭包实现。 闭包的特性闭包有三个特性: 1. 函数嵌套函数 2. 函数内部可以引用外部的参数和变量 3. 参数和变量不会被垃圾回收机制回收 1231. 函数嵌套函数 2. 函数内部可以引用外部的参数和变量 3. 参数和变量不会被垃圾回收机制回收闭包的定义及其优缺点闭包 是指有权访问另一个函数作用域中的变量的函数, 创建闭包的最常见的方式就是在一个函数内创建另一个函数, 通过另一个函数访问这个函数的局部变量闭包的缺点就是常驻内存, 会增大内存使用量, 使用不当很容易造成内存泄露。 闭包是 javascript 语言的一大特点, 主要应用闭包场合主要是为了: 设计私有的方法和变量。 一般函数执行完毕后, 局部活动对象就被销毁, 内存中仅仅保存全局作用域。 但闭包的情况不同! 嵌套函数的闭包function aaa() {

vara=1;
returnfunction() {
alert(a++)
};
}
varfun = aaa();
fun();
1 执行后 a++,,然后a还在~fun();
2 fun = null;
a被回收!! 12345678910 functionaaa() {
vara=1;
returnfunction() {
alert(a++)
};
}
varfun = aaa();
fun();
1 执行后 a++,,然后a还在~fun();
2 fun = null;
a被回收!! 闭包会使变量始终保存在内存中, 如果不当使用会增大内存消耗。 javascript 的垃圾回收原理( 1)、 在 javascript 中, 如果一个对象不再被引用, 那么这个对象就会被 GC回收;( 2)、 如果两个对象互相引用, 而不再被第 3 者所引用, 那么这两个互相引用的对象也会被回收。 使用闭包的好处那么使用闭包有什么好处呢? 使用闭包的好处是: 1. 希望一个变量长期驻扎在内存中 2. 避免全局变量的污染 3. 私有成员的存在 1231. 希望一个变量长期驻扎在内存中 2. 避免全局变量的污染 3. 私有成员的存在一、 全局变量的累加 < script > vara = 1;
functionabc() {
a++;
alert(a);
}
abc();
2 abc();
3 < /script>123456789<script>vara =1;functionabc(){a ++;alert( a ) ;}abc( ) ;2abc( ) ;3</script > 二、 局部变量 < script > functionabc() {
vara=1;
a++;
alert(a);
}
abc();
2 abc();
2 < /script>12345678910<script>functionabc(){vara =1;a ++;alert( a ) ;}abc( ) ;2abc( ) ;2</script > 那么怎么才能做到变量a既是局部变量又可以累加呢? 三、 局部变量的累加 < script > functionouter() {
varx=10;
returnfunction() {
函数嵌套函数x++;
alert(x);
}
}
vary = outer();
外部函数赋给变量y;
y();
y函数调用一次, 结果为11, 相当于outer()(); y();
y函数调用第二次, 结果为12, 实现了累加 < /script>123456789101112<script>functionouter(){varx =10;returnfunction(){函数嵌套函数 x ++;alert( x ) ;}}vary =outer( ) ;外部函数赋给变量y;y( ) ;y函数调用一次,结果为11,相当于outer()(); y( ) ;y函数调用第二次,结果为12,实现了累加 </script > 函数声明与函数表达式在js中我们可以通过关键字function来声明一个函数: < script > functionabc() {
alert(123);
}
abc(); < /script>123456<script>functionabc(){alert( 123) ;}abc( ) ;</script > 我们也可以通过一个”()” 来将这个声明变成一个表达式: < script > (function () {
alert(123);
})();
然后通过() 直接调用前面的表达式即可, 因此函数可以不必写名字; < /script>12345<script>( function(){alert( 123) ;}) ( ) ;然后通过()直接调用前面的表达式即可,因此函数可以不必写名字; </script > 四、 模块化代码, 减少全局变量的污染 < script > varabc = (function () {
abc为外部匿名函数的返回值vara=1;
returnfunction() {
a++;
alert(a);
}
})();
abc();
2; 调用一次abc函数, 其实是调用里面内部函数的返回值 abc();
3 < /script>1234567891011<script>varabc =( function(){abc为外部匿名函数的返回值 vara =1;returnfunction(){a ++;alert( a ) ;}}) ( ) ;abc( ) ;2;调用一次abc函数,其实是调用里面内部函数的返回值 abc( ) ;3</script > 五、 私有成员的存在 < script > varaaa = (function () {
vara=1;
functionbbb() {
a++;
alert(a);
}
functionccc() {
a++;
alert(a);
}
return{
b: bbb,
json结构 c: ccc
}
})();
aaa.b();
2 aaa.c() 3 < /script>12345678910111213141516171819<script>varaaa =( function(){vara =1;functionbbb(){a ++;alert( a ) ;}functionccc(){a ++;alert( a ) ;}return{b :bbb ,json结构 c :ccc }}) ( ) ;aaa .b( ) ;2aaa .c( ) 3</script > 六.使用匿名函数实现累加使用匿名函数实现局部变量驻留内存中, 从而实现累加 < script type = “text/javascript” > functionbox() {
varage=100;
returnfunction() {
匿名函数age++;
returnage;
};
}
varb = box();
alert(b());
alert(b());
即alert(box()()); alert(b());
alert(b);

 

function () {
age++;
returnage;
}
b = null; 解除引用, 等待垃圾回收 < /script> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 / / 使用匿名函数实现局部变量驻留内存中, 从而实现累加 < script type = “text/javascript” > functionbox() {
varage=100;
returnfunction() {
匿名函数age++;
returnage;
};
}
varb = box();
alert(b());
alert(b());
即alert(box()()); alert(b());
alert(b);

 

function () {
age++;
returnage;
}
b = null; 解除引用, 等待垃圾回收 < /script>过度使用闭包会导致性能的下降。函数里放匿名函数,则产生了闭包七、在循环中直接找到对应元素的索引<!DOCTYPEhtml PUBLIC”-W3CDTD XHTML 1.0 TransitionalEN””http:www.w3.org/TR / xhtml1 / DTD / xhtml1 – transitional.dtd “><htmlxmlns=”
http: //www.w3.org / 1999 / xhtml “xml:lang=”en “> <head> <metahttp-equiv=”Content – Type “content=”text / html;charset = UTF – 8 “/> <title></title> <script> window.onload = function(){ var aLi =document.getElementsByTagName(‘li’); for(var i=0;i<aLi.length; i++){aLi[i].onclick = function () { 当点击时for循环已经结束 alert(i); }; } } </script> </head> <body> <ul> <li>123</li> <li>456</li> <li>789</li> <li>010</li> </ul> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <!DOCTYPE html PUBLIC ” – W3CDTD XHTML 1.0 TransitionalEN ” “http://www.w3.org / TR / xhtml1 / DTD / xhtml1 – transitional.dtd “>
<
htmlxmlns=”http://www.w3.org / 1999 / xhtml “
xml: lang = “en ” > < head > < meta http – equiv = “Content -Type “
content = “text /html;charset =UTF-8” / >
<
title > < /title> <script> window . onload = function ( ) { var aLi = document . getElementsByTagName ( ‘li’ ) ; for ( var i = 0 ; i < aLi.length ; i ++ ) {aLi[i].onclick = function () { 当点击时for循环已经结束 alert(i); } ; } } </script > < /head> <body> <ul> <li> 123 </li > < li > 456 < /li> <li> 789 </li > < li > 010 < /li> </ul > < /body> </html > 八、 使用闭包改写上面代码 < !DOCTYPE html PUBLIC “-W3CDTDXHTML1.0TransitionalEN “
“http://www.w3.org / TR / xhtml1 / DTD / xhtml1 – transitional.dtd ” >
<
html xmlns = “http:///www.w3.org / 1999 / xhtml “
xml: lang = “en ” > < head > < meta http – equiv = “Content -Type “
content = “text /html;charset =UTF-8” / > < title > < /title> <script> window.onload = function(){ var aLi = document.getElementsByTagName(‘li’); for (var i=0;i<aLi.length; i++){(function (i) { aLi[i].onclick = function () { alert(i); }; })(i); } }; </script > < /head> <body> <ul> <li>123</li > < li > 456 < /li> <li>789</li > < /ul> </body > < /html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <!DOCTYPE html PUBLIC “-W3CDTDXHTML1.0TransitionalEN “”http:/ / www.w3.org / TR / xhtml1 / DTD / xhtml1 – transitional.dtd “> <html xmlns=”
http: //www.w3.org / 1999 / xhtml ” xml : lang = “en “> <head> <meta http-equiv=”Content -Type ” content=”text /html;charset =UTF-8″ /> <title> </title> <script> window . onload = function ( ) { var aLi = document . getElementsByTagName ( ‘li’ ) ; for ( var i = 0 ; i < aLi.length ; i ++ ) {(function (i) { aLi[i].onclick = function () { alert(i); }; })(i) ; } } ; </script> </head> <body> <ul> <li> 123 </li> <li> 456 </li> <li> 789 </li> </ul> </body> </html>九.内存泄露问题由于 IE 的 js 对象和 DOM 对象使用不同的垃圾收集方法,因此闭包在 IE 中会导致内存泄露问题,也就是无法销毁驻留在内存中的元素function closure(){ var oDiv = document.getElementById(‘oDiv’);oDiv用完之后一直驻留在内存中 oDiv.onclick = function () {alert(‘oDiv.innerHTML’); 这里用oDiv导致内存泄露 }; } closure(); 最后应将oDiv解除引用来避免内存泄露 function closure(){ var oDiv = document.getElementById(‘oDiv’); var test = oDiv.innerHTML; oDiv.onclick = function () {alert(test); }; oDiv = null; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function closure ( ) { var oDiv = document . getElementById ( ‘oDiv’ ) ; oDiv用完之后一直驻留在内存中 oDiv . onclick = function ( ) {alert(‘oDiv.innerHTML’) ; 这里用oDiv导致内存泄露 } ; } closure ( ) ; 最后应将oDiv解除引用来避免内存泄露 function closure ( ) { var oDiv = document . getElementById ( ‘oDiv’ ) ; var test = oDiv . innerHTML ; oDiv . onclick = function ( ) {alert(test) ; } ; oDiv = null ; }扩展阅读:javascript学习总结(四)function函数部分。
赞(1)
前端开发者 » 详解 js 闭包_网站前端开发_前端开发者
64K

评论 抢沙发

评论前必须登录!