您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關javascript的閉包是什么意思,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
在javascript中,當兩個函數彼此嵌套時,內部的函數就是閉包。閉包是指有權訪問另一個函數作用域中的變量的函數,創建閉包的最常見的方式就是在一個函數內創建另一個函數,通過另一個函數訪問這個函數的局部變量。
本教程操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。
閉包(closure)就是能夠讀取其他函數內部變量的函數。在javascript中,只有函數內部的子函數才能讀取局部變量,所以閉包可以理解成 “定義在一個函數內部的函數”。在本質上,閉包是將函數內部和函數外部連接起來的橋梁。(閉包的最典型的應用是實現回調函數(callback) )。
優點:
????1、保護函數內的變量安全
????2、在內存中維持一個變量(用的太多就變成了缺點,占內存) ;
????3、邏輯連續,當閉包作為另一個函數調用的參數時,避免你脫離當前邏輯而單獨編寫額外邏輯。
????4、方便調用上下文的局部變量。
????5、加強封裝性,可以達到對變量的保護作用。
缺點:
????1、常駐內存,會增大內存使用量,使用不當很容易造成內存泄露。
????2、還有有一個非常嚴重的問題,那就是內存浪費問題,這個內存浪費不僅僅因為它常駐內存,更重要的是,對閉包的使用不當會造成無效內存的產生。
特性:
????1、函數嵌套函數
????2、內部函數可以訪問外部函數的變量
????3、參數和變量不會被回收。
要理解閉包,僅理解上邊關于閉包的概念是不行的。首先要理解javascript的特殊的變量作用域。
1、變量的作用域無非就兩種:全局變量和局部變量。
2、javascript語言的特別之處就在于:函數內部可以直接讀取全局變量,但是在函數外部無法讀取函數內部的局部變量。
3、注意點:在函數內部聲明變量的時候,一定要使用var命令。如果不用的話,你實際上聲明的是一個全局變量!
??在Javascript中閉包的創建過程,如以下程序所示。
function a () { var i = 0; function b () { alert (i++); } return b; } var c = a(); c(); //函數調用
代碼特點
這段代碼有兩個特點:
??????1、函數b嵌套在函數a內部;
??????2、函數a返回函數b。
這樣在執行完var c = a( )后,變量c實際上是指向了函數b,再執行c( )后就會彈出一個窗口顯示i的值(第一次為1)。這段代碼其實就創建了一個閉包,這是因為函數a外的變量c引用了函數a內的函數b。也就是說,當函數a的內部函數b被函數a外的一個變量引用的時候,就創建了一個閉包。
作用
簡而言之,閉包的作用就是在a執行完并返回后,閉包使得Javascript的垃圾回收機制不會收回a所占用的資源,因為a的內部函數b的執行需要依賴a中的變量。
在上面的例子中,由于閉包的存在使得函數a返回后,a中的i始終存在,這樣每次執行c(),i都是自加1后alert出i的值。
那么我們來想象另一種情況,如果a返回的不是函數b,情況就完全不同了。因為a執行完后,b沒有被返回給a的外界,只是被a所引用,而此時a也只會被b引 用,因此函數a和b互相引用但又不被外界打擾(被外界引用),函數a和b就會被回收。
應用場景
1、保護函數內的變量安全。函數a中i只有函數b才能訪問,而無法通過其他途徑訪問到,因此保護了i的安全性。
2、在內存中維持一個變量。由于閉包,函數a中i的一直存在于內存中,因此每次執行c(),都會給i自加1。
??出于種種原因,我們有時候需要獲取到函數內部的局部變量。但是,上面(三、變量作用域)已經說過了,正常情況下,這是辦不到的!只有通過變通的方法才能實現。那就是在函數內部,再定義一個函數。
function demo1 () { var n = 6699; function demo2 () { alert(n); // 6699 } }
在上面的代碼中,函數 demo2 就被包括在函數demo1內部,這時demo1內部的所有局部變量,對demo2都是可見的。但是反過來就不行,demo2內部的局部變量,對demo1就是不可見的。
這就是Javascript語言特有的”鏈式作用域”結構(chain scope),子對象會一級一級地向上尋找所有父對象的變量。所以,父對象的所有變量,對子對象都是可見的,反之則不成立。
既然demo2可以讀取demo1中的局部變量,那么只要把demo2作為返回值,我們不就可以在demo1外部讀取它的內部變量了嗎!
閉包可以用在許多地方。它的最大用處有兩個,一個是前面提到的可以讀取函數內部的變量,另一個就是讓這些變量的值始終保持在內存中,不會在demo1調用后被自動清除。
那為什么會這樣呢?原因就在于demo1是demo2的父函數,而demo2被賦給了一個全局變量,這導致demo2始終在內存中,而demo2的存在依賴于demo1,因此demo1也始終在內存中,不會在調用結束后,被垃圾回收機制(garbage collection)回收。
1、由于閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。
2、閉包會在父函數外部,改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。
1、閉包是指有權訪問另一個函數作用域中的變量的函數,創建閉包的最常見的方式就是在一個函數內創建另一個函數,通過另一個函數訪問這個函數的局部變量。閉包的缺點就是常駐內存,會增大內存使用量,使用不當很容易造成內存泄露。
2、不適合場景:返回閉包的函數是個非常大的函數。
????閉包的典型框架應該就是jquery了。
????閉包是javascript語言的一大特點,主要應用閉包場合主要是為了:設計私有的方法和變量。
????這在做框架的時候體現更明顯,有些方法和屬性只是運算邏輯過程中的使用的,不想讓外部修改這些屬性,因此就可以設計一個閉包來只提供方法獲取。
3、 不必糾結到底怎樣才算閉包,其實你寫的每一個函數都算作閉包,即使是全局函數,你訪問函數外部的全局變量時,就是閉包
的體現。
關于“javascript的閉包是什么意思”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。