前言:
參考文檔http://www.runoob.com/js/js-f...html
問:爲何有它?web
答:由於私有變量。閉包
JavaScript變量按照做用範圍能夠分爲全局變量和局部變量。
私有變量須要用閉包。函數
全局變量:code
var a = 4; function myFunction() { return a * a; }
或者:htm
a = 4; function myFunction() { return a * a; }
又或者:對象
function myFunction() { a = 4; return a * a; }
局部變量:生命週期
function myFunction() { var a = 4; return a * a; }
或者:ip
function myFunction(a) { return a * a; }
在web頁面中全局變量屬於window對象。
局部變量只能用於定義它的函數內部。作用域
全局和局部變量即使名稱相同,它們也是兩個不一樣的變量。修改其中一個,不會影響另外一個的值。
注意: 變量聲明是若是不使用 var 關鍵字,那麼它就是一個全局變量,即使它在函數內定義。
變量生命週期:
全局變量的做用域是全局性的,即在整個JavaScript程序中,全局變量到處都在。
而在函數內部聲明的變量,只在函數內部起做用。這些變量是局部變量,做用域是局部性的;函數的參數也是局部性的,只在函數內部起做用。
實例解析閉包:
仍是以計數器爲例。簡單易懂。
var counter = 0; function add() { counter += 1; } add(); add(); add(); // 計數器如今爲 3
這裏的counter是全局變量,容易被其餘地方不當心修改了值。這時再試試局部變量:
function add() { var counter = 0; counter += 1; } add(); add(); add(); // 本意是想輸出 3, 但事與願違,輸出的都是 1 !
JavaScript內嵌函數能夠解決該問題。但仍是存在另外一個問題,就是每次執行這個函數裏的counter=0這個賦值操做都會被執行一次。
就是說返回的結果仍是1。
function add() { var counter = 0; function plus() {counter += 1;} plus(); return counter; } var a = add(); console.log(a); var b = add(); console.log(b);
因此還須要處理這個問題,就是確保counter=0只執行一次。這時須要閉包。
JavaScript閉包:
這裏還會用到函數自我調用。由於它只執行一次。
var add = (function () { var counter = 0; return function () {return counter += 1;} })(); add(); add(); add(); // 計數器爲 3
實例解析:
變量add指定了函數自我調用的返回字值。
自我調用函數只執行一次。設置計數器爲 0。並返回函數表達式。
add變量能夠做爲一個函數使用。很是棒的部分是它能夠訪問函數上一層做用域的計數器。
這個叫做 JavaScript閉包。它使得函數擁有私有變量變成可能。
計數器受匿名函數的做用域保護,只能經過add方法修改。
注意: 閉包是可訪問上一層函數做用域裏變量的函數,即使上一層函數已經關閉。