閉包概念:html
閉包就是有權訪問另外一個函數做用域中變量的函數.
分析這句話:閉包
1.閉包是定義在函數中的函數.
2.閉包能訪問包含函數的變量.
3.即便包含函數執行完了, 被閉包引用的變量也得不到釋放.函數
例子分析-1: function add(){ var i = 0 arr = []; for(; i < 10; i++){ arr.push(function(){ alert(i); }); } return arr; } var temp = add(); temp[0](); 你們猜猜這個結果是多少? 0, i, 10? 我想你們會說是0. 可是結果是10. 我想你們想的應該是這樣滴: i = 0, arr.push(function(){ alert(0); }) i = 1, arr.push(function(){ alert(1); }) ... i = 10, arr.push(function(){ alert(10); }) 咋一看, 這個確實合理, 根據閉包的定義, 具體這個固然是上面分析的那樣了. 問題就出在這個變量的理解上. 1.i是變量不假, 可是i在for循環的時候, 一直在不斷變化. 也就是說這個i在參與for循環的時候, 值是不肯定的, 等到for執行完後, i的值才肯定. 2.每次push一個匿名函數表達式時, 那只是定義一個函數, 並沒去執行那個函數, 因此那個函數裏引用的外部變量都是原封不動的放進去的. 換句話說, 就是這個匿名函數在最後執行的時候, 纔會去查找做用域鏈, 直至找到那個變量i爲止. 也就是: i = 0, arr.push(function(){ alert(i); }) i = 1, arr.push(function(){ alert(i); }) ... i = 10, arr.push(function(){ alert(i); }) 執行add()時, i參與循環完畢, i = 10. 執行temp[0]()時, 匿名函數會查找i, 先看本身, 個人i有值嗎?沒有. 再找他的上級函數, i有值嗎?有, i = 10. 查找結束. 至此, 無論執行temp[0](), 仍是temp[5](), 仍是temp[10](), 結果都是10. 改一下上面的例子, 讓它符合咱們的預期要求. 例子分析-2: function add(){ var i = 0 arr = []; for(; i < 10; i++){ arr.push( (function(n){ return function(){ alert(n); } })(i)//注意這個變化 ); } return arr; } var temp = add(); temp[0](); temp[1](); ... 此次結果是預期的,結果是 0 , 1 , 2, 3 ... 10 分析一下循環那部分. (function(n){ return function(){ alert(n); } })(i) 這個叫作當即執行的匿名函數表達式(不清楚這種寫法的, 能夠先google下, 或者看個人單獨一篇專門介紹) i這個是時候就被當作參數傳遞了, 每次這個匿名函數執行時, i都會把本身的值複製一份給n return語句中的匿名函數引用着n, 此時已經和i無關了. 每次匿名函數表達式執行時, 都會保存一個不一樣的n. return語句中的匿名函數每次也引用着不一樣的n。 形象點就是這樣: arr.push( (function(n = i = 0){ return function(){ alert(n = 0); } })(i = 0) ) arr.push( (function(n = i = 1){ return function(){ alert(n = 1); } })(i = 1) ) ... 閉包的介紹就到此爲止了.
轉自http://www.cnblogs.com/tinkbe...google