• <tbody id="9je1r"></tbody><tbody id="9je1r"><acronym id="9je1r"><rp id="9je1r"></rp></acronym></tbody>
      • <acronym id="9je1r"><acronym id="9je1r"><rp id="9je1r"></rp></acronym></acronym>

        亚洲无码Aⅴ,视频1页精品,欧美系列一区二区,曰韩色999

        Javacript的閉包是指什么

        2020/11/13 11:56:05   閱讀:2571    發(fā)布者:2571

        • 閉包:


        1.作為一個(gè)函數(shù)變量的一個(gè)引用,當(dāng)函數(shù)返回時(shí),其處于激活狀態(tài)。

        2.一個(gè)閉包就是當(dāng)一個(gè)函數(shù)返回時(shí),一個(gè)沒有釋放資源的棧區(qū)。


        簡(jiǎn)單的說,javascript允許使用內(nèi)部函數(shù)---即函數(shù)定義和函數(shù)表達(dá)式位于另一個(gè)函數(shù)的函數(shù)體內(nèi)。而且,這些內(nèi)部函數(shù)可以訪問它們所在的外部函數(shù)中聲明的所有局部變量、參數(shù)和聲明的其他內(nèi)部函數(shù)。當(dāng)其中一個(gè)這樣的內(nèi)部函數(shù)在包含它們的外部函數(shù)之外被調(diào)用時(shí),就會(huì)形成閉包。



        • 變量的作用域


        要理解閉包,首先必須理解Javascript特殊的變量作用域。

        變量的作用域無非就是兩種:全局變量和局部變量。

        Javascript語言的特殊之處,就在于函數(shù)內(nèi)部可以直接讀取全局變量。

        js code:

        var n = 999;

        function f1(){

        console.log(n);

        }

        f1();  //999

        另一方面,在函數(shù)外部自然無法讀取函數(shù)內(nèi)的局部變量。

        js code:

        function f1(){

        var n = 999;

        }

        console.log(n);  //error

        這里有一個(gè)地方需要注意,函數(shù)內(nèi)部聲明變量的時(shí)候,一定要使用var命令。如果不用的話,你實(shí)際上聲明了一個(gè)全局變量。

        js code

        function f1(){

        n = 999;

        }

        f1();

        console.log(n);  //999

        • 如何從外部讀取局部變量?


        出于種種原因,我們有時(shí)候需要得到函數(shù)內(nèi)的局部變量。但是,前面已經(jīng)說過了,正常情況下,這是辦不到的,只有通過變通方法才能實(shí)現(xiàn)。

        那就是在函數(shù)的內(nèi)部,再定義一個(gè)函數(shù)。

        js code

        function f1(){

        n = 999;

        function f2(){

        console.log(n);  //999

        }

        }

        在上面的代碼中,函數(shù)f2就被包括在函數(shù)f1內(nèi)部,這時(shí)f1內(nèi)部的所有局部變量,對(duì)f2都是可見的。但是反過來就不行,f2內(nèi)部的局部變量對(duì)f1就是不可見的。這就是javascript語言特有的‘鏈?zhǔn)阶饔糜颉Y(jié)構(gòu)(chain scope),子對(duì)象會(huì)一級(jí)一級(jí)地向上尋找所有父對(duì)象的變量。所以,父對(duì)象的所有變量,對(duì)子對(duì)象都是可見的,反之則不成立。

        既然f2可以讀取f1中的局部變量,那么只要把f2作為返回值,我們就可以在f1外部讀取它的內(nèi)部變量了。

        js code

        function f1(){

        n = 999;

        function f2(){

        console.log(n);

        }

        return f2;

        }

        var result = f1();  //返回的是f2函數(shù)

        result();  //999

        • 閉包的概念


        上一節(jié)代碼中的f2函數(shù),就是閉包。

        閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù),函數(shù)沒有被釋放,整條作用域鏈上的局部變量都將得到保留。

        由于在javascript語言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡(jiǎn)單理解成‘定義在一個(gè)函數(shù)內(nèi)部的函數(shù)’。

        所以,在本質(zhì)上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接的一座橋梁。

        • 閉包的用途


        閉包可以用在許多地方。它的最大用處有兩個(gè),一個(gè)是前面提到的可以讀取函數(shù)內(nèi)部的變量,另一個(gè)就是讓這些變量的值始終保持在內(nèi)存中。

        js code

        function f1(){

        var n = 999;

        nAdd = function(){

        n += 1;

        }

        function f2(){

        console.log(n);

        }

        return f2;

        }

        var result = f1();

        result();  //從函數(shù)外部通過閉包f2獲取到函數(shù)f1內(nèi)部局部變量的值

        nAdd();  //從函數(shù)外部通過閉包修改局部變量n的值

        result();  //再次通過閉包f2獲取到函數(shù)f1內(nèi)部局部變量的值

        在這段代碼中,result實(shí)際上就是閉包f2函數(shù)。它一共運(yùn)行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數(shù)f1中的局部變量n 一直保存在內(nèi)存中,并沒有在f1調(diào)用后被自動(dòng)清除。

        為什么會(huì)這樣呢?原因就在于f1是f2的父函數(shù),而f2被賦給了一個(gè)全局變量,這導(dǎo)致f2始終在內(nèi)存中,不會(huì)再調(diào)用結(jié)束后,被垃圾回收機(jī)制(garbage collection)回收。

        這段代碼中另一個(gè)值得注意的地方,就是‘nAdd=function(){n+=1}’這一行,首先在nAdd前面沒有使用var關(guān)鍵字,因此nAdd是一個(gè)全局變量,而不是局部變量。其次,nAdd的值是一個(gè)匿名函數(shù)(anonymous function),而這個(gè)匿名函數(shù)本身也是一個(gè)閉包,所以nAdd相當(dāng)于是一個(gè)setter,可以在函數(shù)外部對(duì)函數(shù)內(nèi)部的局部變量進(jìn)行操作。

        • 使用閉包的注意點(diǎn)


        1>由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會(huì)造成網(wǎng)頁(yè)的性能問題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法時(shí),在退出函數(shù)之前,將不使用的局部變量全部刪除。

        2>閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對(duì)象(object)使用,把閉包當(dāng)作它的公用方法,把內(nèi)部變量當(dāng)作它的私有屬性,這時(shí)一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。
        亚洲无码Aⅴ,视频1页精品,欧美系列一区二区,曰韩色999
            • <tbody id="9je1r"></tbody><tbody id="9je1r"><acronym id="9je1r"><rp id="9je1r"></rp></acronym></tbody>
            • <acronym id="9je1r"><acronym id="9je1r"><rp id="9je1r"></rp></acronym></acronym>
              兴和县| 绥阳县| 宜兴市| 赤城县| 财经| 旌德县| 蕲春县| 平湖市| 中山市| 出国| 崇州市| 西青区| 通化市| 金门县| 玛沁县| 泰来县| 红安县| 仁化县| 电白县| 宁远县| 房山区| 固安县| 绥江县| 江门市| 南丰县| 安徽省| 邯郸市| 宁蒗| 许昌县| 德庆县| 阳山县| 全南县| 田东县| 涡阳县| 麻阳| 正蓝旗| 仁化县| 祁东县| 项城市| 乌鲁木齐市| 吴旗县|