日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

闭包详解

發(fā)布時間:2023/12/24 综合教程 36 生活家
生活随笔 收集整理的這篇文章主要介紹了 闭包详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

閉包的特性

閉包有三個特性:

1.函數(shù)嵌套函數(shù)
2.函數(shù)內(nèi)部可以引用外部的參數(shù)和變量
3.參數(shù)和變量不會被垃圾回收機制回收

閉包的定義及其優(yōu)缺點

閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的最常見的方式就是在一個函數(shù)內(nèi)創(chuàng)建另一個函數(shù),通過另一個函數(shù)訪問這個函數(shù)的局部變量。

閉包的缺點就是常駐內(nèi)存,會增大內(nèi)存使用量,使用不當(dāng)很容易造成內(nèi)存泄露。

閉包是javascript語言的一大特點,主要應(yīng)用閉包場合主要是為了:設(shè)計私有的方法和變量。

一般函數(shù)執(zhí)行完畢后,局部活動對象就被銷毀,內(nèi)存中僅僅保存全局作用域。但閉包的情況不同!

嵌套函數(shù)的閉包

   function aaa() {  
          var a = 1;  
          return function(){
           alert(a++)
          };  
        }         
        var fun = aaa();  
        fun();// 1 執(zhí)行后 a++,,然后a還在~  
        fun();// 2   
        fun = null;//a被回收??! 

閉包會使變量始終保存在內(nèi)存中,如果不當(dāng)使用會增大內(nèi)存消耗。

javascript的垃圾回收原理

(1)、在javascript中,如果一個對象不再被引用,那么這個對象就會被GC回收;
(2)、如果兩個對象互相引用,而不再被第3者所引用,那么這兩個互相引用的對象也會被回收。

使用閉包的好處

那么使用閉包有什么好處呢?使用閉包的好處是:

1.希望一個變量長期駐扎在內(nèi)存中
2.避免全局變量的污染
3.私有成員的存在

一、全局變量的累加

var a = 1;
function abc(){
        a++;
        alert(a);
}
abc();              //2
abc();            //3

二、局部變量

function abc(){
        var a = 1;
        a++;
        alert(a);
}
abc();                       //2
abc();                    //2

那么怎么才能做到變量a既是局部變量又可以累加呢?

三、局部變量的累加

function outer(){
        var x=10;
        return function(){             //函數(shù)嵌套函數(shù)
                x++;
                alert(x);
        }
}
var y = outer();              //外部函數(shù)賦給變量y;
y();                 //y函數(shù)調(diào)用一次,結(jié)果為11,相當(dāng)于outer()();
y();                //y函數(shù)調(diào)用第二次,結(jié)果為12,實現(xiàn)了累加

函數(shù)聲明與函數(shù)表達(dá)式

在js中我們可以通過關(guān)鍵字function來聲明一個函數(shù):

function abc(){
        alert(123);
}
abc();

我們也可以通過一個"()"來將這個聲明變成一個表達(dá)式:

(function (){
        alert(123);
})();                   //然后通過()直接調(diào)用前面的表達(dá)式即可,因此函數(shù)可以不必寫名字;

四、模塊化代碼,減少全局變量的污染

var abc = (function(){      //abc為外部匿名函數(shù)的返回值
        var a = 1;
        return function(){
                a++;
                alert(a);
        }
})();
abc();    //2 ;調(diào)用一次abc函數(shù),其實是調(diào)用里面內(nèi)部函數(shù)的返回值    
abc();    //3

五、私有成員的存在

var aaa = (function(){
        var a = 1;
        function bbb(){
                a++;
                alert(a);
        }
        function ccc(){
                a++;
                alert(a);
        }
        return {
                b:bbb,             //json結(jié)構(gòu)
                c:ccc
        }
})();
aaa.b();     //2
aaa.c()      //3

六.使用匿名函數(shù)實現(xiàn)累加

//使用匿名函數(shù)實現(xiàn)局部變量駐留內(nèi)存中,從而實現(xiàn)累加
 function box(){
     var age = 100;
     return function(){          //匿名函數(shù)
          age++;
          return age;
     };
     
 } 
var b = box();
alert(b());
alert(b());    //即alert(box()());
alert(b());
alert(b);            //     function () {
                        //   age++;
                       // return age;
                      //       }

b = null;  //解除引用,等待垃圾回收

過度使用閉包會導(dǎo)致性能的下降。函數(shù)里放匿名函數(shù),則產(chǎn)生了閉包。

七、在循環(huán)中直接找到對應(yīng)元素的索引

<body>
<ul>
    <li>123</li>
    <li>456</li>
    <li>789</li>
    <li>010</li>
 </ul>
</body>
<script>
    window.onload = function(){
            var aLi = document.getElementsByTagName('li');
            for (var i=0;i<aLi.length;i++){
                    aLi[i].onclick = function(){        //當(dāng)點擊時for循環(huán)已經(jīng)結(jié)束
                    alert(i);
                    };
            }
    }
</script>

使用閉包改寫上面代碼:

<body>
    <ul>
        <li>123</li>
        <li>456</li>
        <li>789</li>
    </ul>
</body>
<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>    

八、內(nèi)存泄露問題

由于IEjs對象和DOM對象使用不同的垃圾收集方法,因此閉包在IE中會導(dǎo)致內(nèi)存泄露問題,也就是無法銷毀駐留在內(nèi)存中的元素。

function closure(){
    var oDiv = document.getElementById('oDiv');//oDiv用完之后一直駐留在內(nèi)存中
    oDiv.onclick = function () {
        alert('oDiv.innerHTML');//這里用oDiv導(dǎo)致內(nèi)存泄露
    };
}
closure();
//最后應(yīng)將oDiv解除引用來避免內(nèi)存泄露
function closure(){
    var oDiv = document.getElementById('oDiv');
    var test = oDiv.innerHTML;
    oDiv.onclick = function () {
        alert(test);
    };
    oDiv = null;
}

總結(jié)

以上是生活随笔為你收集整理的闭包详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。