閉包的定義javascript
閉包是指函數有自由獨立的變量。換句話說,定義在閉包中的函數能夠「記憶」它建立時候的環境。java
閉包的淺顯理解數組
function makeFunc() { var name = "Mozilla"; function displayName() { alert(name); } return displayName; } var myFunc = makeFunc(); myFunc();
這段代碼看起來彆扭卻能正常運行。一般,函數中的局部變量僅在函數的執行期間可用。一旦 makeFunc()
執行事後,咱們會很合理的認爲 name 變量將再也不可用。雖然代碼運行的沒問題,但實際並非這樣的。安全
這個謎題的答案是 myFunc
變成一個 閉包 了。 閉包是一種特殊的對象。它由兩部分構成:函數,以及建立該函數的環境。環境由閉包建立時在做用域中的任何局部變量組成。在咱們的例子中,myFunc
是一個閉包,由 displayName
函數和閉包建立時存在的 "Mozilla" 字符串造成。閉包
爲了更好滴理解這句話,簡單的看下圖:函數
閉包能夠實現私有變量。this
function Animal(type) { var data = []; data['type'] = type; this.getType = function () { return data['type']; } } var fluffy = new Animal('dog'); fluffy.getType(); // 返回 'dog'
在這個例子中,Animal類中建立了一個本地數組data。當 Animal對象被實例化時,傳遞了一個type的值並將該值放置在data數組中。由於它是私有的,因此該值沒法被覆蓋(Animal函數定義了它的範圍)。一旦對象被實例化了,讀取type值的惟一方式是調用getType方法。由於getType是在Animal中定義的,所以憑藉Animal產生的閉包,getType能夠進到data中。這樣的話,雖能夠讀到對象的類型卻沒法改變。這有點相似C#中的擁有私有的set訪問器並經過構造函數來實現注入的屬性。從這個意義上來說,javascript的函數就是閉包。spa
閉包的做用code
簡單地來講就是圍繞着它的定義來的:對象
1.能夠保存獨立的變量。由於是閉包的內部函數的做用域只是存在於函數的內部,因此能夠保證變量的安全。
2.定義在閉包中的函數能夠「記憶」它建立時候的環境。通俗的講就是當閉包中的函數被賦值給閉包外部的變量的時候,它的引用就指向了外部的臨時變量。只要這種引用關係一直存在,閉包建立時的環境就會被保存起來。 就能間接保持原構造函數體當時用到的臨時變量值。