javascript支持閉包(closure)的概念,Javascript里的閉包是一種特殊的對象,由函數和函數創建時所處的環境組成,環境里包括了閉包被創建時所在的作用域里的所有本地變量。
function makeFunc() { var name = "Mozilla"; function displayName() { alert(name); } return displayName;}var myFunc = makeFunc();myFunc();上例子中,myFunc就是閉包。
循環創建的閉包都關聯到相同的變量i, 在第一個print執行時,i已經為10。
為了解決這個問題,一個方法是使用更多的閉包
for (var i = 0; i < 10; i++) { (function (i) { function print() { console.log(i); } setTimeout(print, 1000); }) (i);}for (var i = 0; i < 10; i++) { (function () { var ii = i; function print() { console.log(ii); } setTimeout(print, 1000); }) ();}for (var i = 0; i < 10; i++) { var print = (function () { var ii = i; return function print() { console.log(ii); } }) (); setTimeout(print, 1000);}//same output: 0 1 2 3 4 5 6 7 8 9上述不同的寫法都是利用更多的閉包來創建獨立的閉包環境,都有一樣的結果。
另一個方法時用ES6的let關鍵字聲明變量:
for (let i = 0; i < 10; i++) { function print() { console.log(i); } setTimeout(print, 1000);}//output: 0 1 2 3 4 5 6 7 8 9Javascript沒有類似Java這里面向對象語言的方法訪問權限的功能,不過通過閉包,可以模擬出私有方法:
var counter = (function() { var privateCounter = 0; function changeBy(val) { privateCounter += val; } return { increment: function() { changeBy(1); }, decrement: function() { changeBy(-1); }, value: function() { return privateCounter; } }; })();console.log(counter.value()); // logs 0counter.increment();counter.increment();console.log(counter.value()); // logs 2counter.decrement();console.log(counter.value()); // logs 1counter.increment, counter.decrement, counter.value為公共的方法,共享同一個環境形成閉包,而counter內部privateCounter和changeBy則被私有化,對外不可見。這種做法提供了代碼隱藏和封裝的一些益處。
更多MDN
新聞熱點
疑難解答