閉包(closure)是Javascript語言的一個難點,也是它的特點,不少高級應用都要依靠閉包實現。 關於閉包的概念,咱們須要瞭解js的變量。 首先js的變量能夠是任何東西,屬性、方法、對象,均可以做爲變量。變量分爲全局變量和局部變量。在Js中函數的內部能夠讀取全局變量,這點和JAVA類似。閉包
var i=100; function f1(){ alert(i); } f1();//100
可是局部變量,卻不能在外邊直接使用,這點也和Java類似,會出現錯誤。函數
function f1(){ var i=100; } f1(); alert(i);//i is not defined
值得注意的一點,就是什麼內部變量的時候,必定要注意使用var。否則的話你申明的就是一個全局變量。code
function f1(){ i=100; } f1(); alert(i);//100
由此能夠看出來,就是把一下不須要用在全局的變量,放到一個封閉的空間(函數、對象、命名空間)中,可是咱們卻須要裏面的一些變量,那麼這個時候就須要閉包了,閉包就是連接外部函數和內部函數的橋樑。。對象
###2.調用局部變量ip
通常而言,咱們須要調用一個簡單的局部變量是不能實現的。作用域
function f1(){ var i=100; } alert(f1.i);//undefined
咱們須要使用返回值,獲取內部內部變量。rem
function Counter(start) { var count = start; return { increment: function() { count++; }, get: function() { return count; } } } var result = Counter(4); console.log(result.increment()); console.log(result.get());
這裏,Counter 函數返回兩個閉包,函數 increment 和函數 get。 這兩個函數都維持着 對外部做用域 Counter 的引用,所以總能夠訪問此做用域內定義的變量 count。get
###3.循環中閉包io
for(var i = 0; i < 10; i++) { setTimeout(function() { console.log(i); }, 1000); }
上面的代碼不會輸出數字 0 到 9,而是會輸出數字 10 十次。 當 console.log 被調用的時候,匿名函數保持對外部變量 i 的引用,此時 for循環已經結束, i 的值被修改爲了 10. 爲了獲得想要的結果,須要在每次循環中建立變量 i 的拷貝。console
使用下面方式
for(var i = 0; i < 10; i++) { setTimeout((function() { console.log(i); })(i), 1000); }
自執行匿名函數: 常見格式:(function() { /* code */ })(); 解釋:包圍函數(function(){})的第一對括號向腳本返回未命名的函數,隨後一對空括號當即執行返回的未 命名函數,括號內爲匿名函數的參數。 做用:能夠用它建立命名空間,只要把本身全部的代碼都寫在這個特殊的函數包裝內,那麼外部就不能訪問,除非你容許(變量前加上window,這樣該函數或變量就成爲全局)。各JavaScript庫的代碼也基本是這種組織形式。 常見形式: (function () { /* code */ } ()); !function () { /* code */ } (); ~function () { /* code */ } (); -function () { /* code */ } (); +function () { /* code */ } (); function(){ /* code */}();