變量的做用域無非就是兩種:全局變量和局部變量。閉包
函數內部聲明變量的時候,必定要使用var命令。若是不用的話,你實際上聲明瞭一個全局變量!函數
有權訪問另外一個函數做用域的變量,常見的建立方式就是在一個函數內部建立另外一個函數,經過另外一個函數訪問這個函數的局部變量。性能
簡單的說就是,閉包就是可以讀取其餘函數內部變量的函數。this
因爲在Javascript語言中,只有函數內部的子函數才能讀取局部變量,所以能夠把閉包簡單理解成"定義在一個函數內部的函數"。code
MDN中定義的是:對象
閉包是指可以訪問自由變量的函數。換句話說,在閉包中定義的函數能夠「記憶」它被建立的環境。注:自由變量是既不是在本地聲明又不做爲參數傳遞的一類變量。ip
function A(){ function B(){ console.log("Hello Closure!"); } return B; } var b = A(); b();//Hello Closure!
因此經過這個例子能夠簡單理解閉包。內存
* 定義一個函數A() * A中定義了函數B() * A中返回B * 執行A(),把A的返回結果賦值給變量b * 執行b()
總結一句話:函數A的內部函數B被函數A外的一個變量b引用。因此當一個內部函數被其外部函數以外的變量引用時,就造成了一個閉包資源
在一個模塊中定義一個變量,但願這個變量保存在內存中又不會污染全局變量,就用閉包來定義這個模板。作用域
它的最大用處有兩個,一個是前面提到的能夠讀取函數內部的變量,另外一個就是讓這些變量的值始終保持在內存中。
注意:可使用以後,給它加null,接觸引用。
例子1:
var name = "The Window"; // 全局 var object = { name: "My Object", // 局部 getNameFunc: function () { // 對象中的方法,this指向obj這個對象 return function () { // 閉包 return this.name; // this指向window }; } }; alert(object.getNameFunc()()); // The Window
例子2:
var name = "The Window"; // 全局 var object = { name: "My Object", // 局部 getNameFunc: function () { // 對象中的方法,this指向obj這個對象 var that = this; // 將getNameFunc()的this保存在that變量中 return function () { // 閉包 return that.name; // that指向object }; } }; alert(object.getNameFunc()()); // My Object
例子3:
var name = "The Window"; // 全局 var object = { name: "My Object", // 局部 getNameFunc: function () { return function () { // 閉包 var that = this; return that.name; }; } }; alert(object.getNameFunc()()); // The Window
例子4:
var name = "The Window"; // 全局 var object = { name: "My Object", // 局部 getNameFunc: function () { // 對象中的方法,this指向obj這個對象 return function () { // 閉包 var that = this; // 將getNameFunc()的this保存在that變量中 return that.name; // this指向window }; } }; alert(object.getNameFunc().call(object)); // My Object call改變this指向