溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

javascript的閉包是什么意思

發(fā)布時間:2021-10-18 12:39:58 來源:億速云 閱讀:133 作者:小新 欄目:web開發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)javascript的閉包是什么意思,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

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

本教程操作環(huán)境:windows7系統(tǒng)、javascript1.8.5版、Dell G3電腦。

一、閉包是什么?

閉包(closure)就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。在javascript中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,所以閉包可以理解成 “定義在一個函數(shù)內(nèi)部的函數(shù)”。在本質(zhì)上,閉包是將函數(shù)內(nèi)部和函數(shù)外部連接起來的橋梁。(閉包的最典型的應(yīng)用是實現(xiàn)回調(diào)函數(shù)(callback) )。

二、JS中閉包的優(yōu)缺點及特性

優(yōu)點:

????1、保護(hù)函數(shù)內(nèi)的變量安全

????2、在內(nèi)存中維持一個變量(用的太多就變成了缺點,占內(nèi)存) ;

????3、邏輯連續(xù),當(dāng)閉包作為另一個函數(shù)調(diào)用的參數(shù)時,避免你脫離當(dāng)前邏輯而單獨編寫額外邏輯。

????4、方便調(diào)用上下文的局部變量。

????5、加強封裝性,可以達(dá)到對變量的保護(hù)作用。

缺點:

????1、常駐內(nèi)存,會增大內(nèi)存使用量,使用不當(dāng)很容易造成內(nèi)存泄露。
????2、還有有一個非常嚴(yán)重的問題,那就是內(nèi)存浪費問題,這個內(nèi)存浪費不僅僅因為它常駐內(nèi)存,更重要的是,對閉包的使用不當(dāng)會造成無效內(nèi)存的產(chǎn)生。

特性:

????1、函數(shù)嵌套函數(shù)

????2、內(nèi)部函數(shù)可以訪問外部函數(shù)的變量

????3、參數(shù)和變量不會被回收。

三、變量作用域

要理解閉包,僅理解上邊關(guān)于閉包的概念是不行的。首先要理解javascript的特殊的變量作用域。

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

2、javascript語言的特別之處就在于:函數(shù)內(nèi)部可以直接讀取全局變量,但是在函數(shù)外部無法讀取函數(shù)內(nèi)部的局部變量。

3、注意點:在函數(shù)內(nèi)部聲明變量的時候,一定要使用var命令。如果不用的話,你實際上聲明的是一個全局變量!

四、用代碼詮釋閉包

??在Javascript中閉包的創(chuàng)建過程,如以下程序所示。

function a () {
   var i = 0;
   function b () {
      alert (i++);
   }
  return b;
}
var c = a();
c();  //函數(shù)調(diào)用

代碼特點

這段代碼有兩個特點:

??????1、函數(shù)b嵌套在函數(shù)a內(nèi)部;

??????2、函數(shù)a返回函數(shù)b。

這樣在執(zhí)行完var c = a( )后,變量c實際上是指向了函數(shù)b,再執(zhí)行c( )后就會彈出一個窗口顯示i的值(第一次為1)。這段代碼其實就創(chuàng)建了一個閉包,這是因為函數(shù)a外的變量c引用了函數(shù)a內(nèi)的函數(shù)b。也就是說,當(dāng)函數(shù)a的內(nèi)部函數(shù)b被函數(shù)a外的一個變量引用的時候,就創(chuàng)建了一個閉包。

作用

簡而言之,閉包的作用就是在a執(zhí)行完并返回后,閉包使得Javascript的垃圾回收機制不會收回a所占用的資源,因為a的內(nèi)部函數(shù)b的執(zhí)行需要依賴a中的變量。

在上面的例子中,由于閉包的存在使得函數(shù)a返回后,a中的i始終存在,這樣每次執(zhí)行c(),i都是自加1后alert出i的值。

那么我們來想象另一種情況,如果a返回的不是函數(shù)b,情況就完全不同了。因為a執(zhí)行完后,b沒有被返回給a的外界,只是被a所引用,而此時a也只會被b引 用,因此函數(shù)a和b互相引用但又不被外界打擾(被外界引用),函數(shù)a和b就會被回收。

應(yīng)用場景

1、保護(hù)函數(shù)內(nèi)的變量安全。函數(shù)a中i只有函數(shù)b才能訪問,而無法通過其他途徑訪問到,因此保護(hù)了i的安全性。

2、在內(nèi)存中維持一個變量。由于閉包,函數(shù)a中i的一直存在于內(nèi)存中,因此每次執(zhí)行c(),都會給i自加1。

五、如何從外部讀取函數(shù)內(nèi)部的局部變量?

??出于種種原因,我們有時候需要獲取到函數(shù)內(nèi)部的局部變量。但是,上面(三、變量作用域)已經(jīng)說過了,正常情況下,這是辦不到的!只有通過變通的方法才能實現(xiàn)。那就是在函數(shù)內(nèi)部,再定義一個函數(shù)。

function demo1 () {
    var n = 6699;
    function demo2 () {
      alert(n); // 6699
    }
  }

在上面的代碼中,函數(shù) demo2 就被包括在函數(shù)demo1內(nèi)部,這時demo1內(nèi)部的所有局部變量,對demo2都是可見的。但是反過來就不行,demo2內(nèi)部的局部變量,對demo1就是不可見的。

這就是Javascript語言特有的”鏈?zhǔn)阶饔糜颉苯Y(jié)構(gòu)(chain scope),子對象會一級一級地向上尋找所有父對象的變量。所以,父對象的所有變量,對子對象都是可見的,反之則不成立。

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

六、閉包的用途

閉包可以用在許多地方。它的最大用處有兩個,一個是前面提到的可以讀取函數(shù)內(nèi)部的變量,另一個就是讓這些變量的值始終保持在內(nèi)存中,不會在demo1調(diào)用后被自動清除。

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

七、使用閉包的注意點

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

2、閉包會在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對象(object)使用,把閉包當(dāng)作它的公用方法(Public Method),把內(nèi)部變量當(dāng)作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。

八、總結(jié):

1、閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的最常見的方式就是在一個函數(shù)內(nèi)創(chuàng)建另一個函數(shù),通過另一個函數(shù)訪問這個函數(shù)的局部變量。閉包的缺點就是常駐內(nèi)存,會增大內(nèi)存使用量,使用不當(dāng)很容易造成內(nèi)存泄露。

2、不適合場景:返回閉包的函數(shù)是個非常大的函數(shù)。

????閉包的典型框架應(yīng)該就是jquery了。

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

????這在做框架的時候體現(xiàn)更明顯,有些方法和屬性只是運算邏輯過程中的使用的,不想讓外部修改這些屬性,因此就可以設(shè)計一個閉包來只提供方法獲取。

3、 不必糾結(jié)到底怎樣才算閉包,其實你寫的每一個函數(shù)都算作閉包,即使是全局函數(shù),你訪問函數(shù)外部的全局變量時,就是閉包
的體現(xiàn)。

關(guān)于“javascript的閉包是什么意思”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI