一道閉包題引起的思考

先看一下這個例子。javascript

function box() {
var a = 1;
return function() {
a++;
alert(a);
}
}
box()();//2
box()();//2
var c=box();
c();//2
c();//3

好久前在知乎碰到了這個問題,當時實在是不知道怎麼徹底解釋,後來從新翻看《javascript高級程序設計》的時候才恍然大悟。java

個人理解是能夠用執行環境來解釋。閉包

《javascript高級程序設計》裏面有這麼一段話:「在js裏面當執行流進入一個函數的時候,函數的環境會被推入到一個環境棧裏面,函數執行結束後又會將環境彈出。」函數

這樣前兩個box()()實際上每次執行的時候,函數環境都被推入到棧裏面,結束後又會被彈出,首先是box環境被推入棧中,而後裏面閉包函數環境推入到棧中,執行結束後會先彈出閉包的環境,再彈出box的環境,因此兩個互不影響,都是2。設計

可是c=box()的時候,由於c一直保持着box()的執行,因此box的執行環境一直在棧中,後面兩個c()運行的時候,會推入閉包的執行環境,執行c()結束後才彈出閉包的執行環境,實際上box這個執行環境一直還在棧中,因此a就都在同一個執行環境裏面了。code

後來我請教了一下在百度工做的師兄,他的解釋是這樣的:ip

每一個函數的做用域都是獨一無二的,函數執行完后里面的東西都會清空,因此box()()執行兩次後都是2。作用域

而c,即box(),實際是一直引用着box裏面的a變量,因此一直不會被清空。io

這個相似於:function

var a=1;
  function c(){
   a++;
   alert(a);
  }
  c(); //2
  c(); //3
相關文章
相關標籤/搜索