閉包是指有權訪問另外一個函數做用域中的變量的函數(有點拗口吧),簡單點就是在一個函數的內部建立另一個函數,並返回這個函數的引用。(這也是建立閉包的經常使用方式)閉包
function outerFunc (outerNum) { return function innerFunc(innerNum) { outerNum=outerNum+innerNum; return outerNum; } } var inner=outerFunc(1); var a1=inner(11); console.log(a1)//輸出爲12 var a2=inner(2); console.log(a2)//輸出爲14
上面的代碼就建立了一個閉包,裏面的innerFunc有權訪問外面函數的變量outerNum。函數
不明白,不要緊,咱們先看執行這個函數的內存狀況spa
在JavaScript裏面,有一個概念叫作做用域,咱們定義一個下面的函數code
function sample (value1,value2) { var temp; temp=value1+value1; return temp; } var result=sample(5,6);
當sample函數執行時的做用域鏈以下對象
後臺的每一個執行環境都有一個表示變量的對象(變量對象)。全局環境的變量對象始終存在,而像sample()函數這樣的局部環境變量對象,則只在函數的執行過程當中存在。blog
當sample(5,6)執行完畢後,sample的執行環境的做用域鏈就會被銷燬,sample()的活動對象就沒有被引用了,那麼sample()的活動對象就會被銷燬,如上圖的紅色虛線框表示就要被銷燬的。由於全局變量對象是須要整個執行環境被銷燬纔會被銷燬(整個程序執行完畢,程序退出後)。ip
如今咱們回到最初的閉包,看看這個閉包的做用域鏈又是怎樣的內存
如上圖,當outerFunc(1)執行後,outerFunc的執行環境做用域鏈就要被銷燬,就是紅色虛線框的部分表示被銷燬的,原本outerFunc()的活動對象也是要被銷燬的,可是系統檢測到,outerFunc()的活動對象還被innerFunc的執行環境做用域鏈引用,因此它就被保存了下來,也就是說裏面的值也被保存了下來作用域
執行完inner(11)後,outerNum=12,再執行inner(2)的話,outerNum=14io