當內部 (inner) 函式被回傳後,除了自己本身的程式碼外,也可以 穿越 取得了內部函式「當時環境」的變數值,記住了執行當時的環境,這就是「閉包」。 (by Kuro)
用自己的話畫重點:
內部函式必須要用回傳 (
return
) 的方式,取得外部函式的變數 or 參數作運用。
閉包的用意在於 —
避免增加全域變數,但又能取得區域變數的值,取得的方法為 return
內部函式。
此例的 return function(){return ++count}
即為閉包,var count = 0;
為區域變數,但可以透過外部的呼叫,取得 count
的值,既沒有汙染到全域變數,也可以新增很多個變數 countFuc1.2.3.4….
去取得各自作用域的 count
值出來。
var
的作用域 (scope) 最小單位是function
,不是for (){ }
也不是if (){ }
常會出錯的地方在 - 把 for
迴圈中的 i
帶入迴圈中的內部函式,i
只會是以迴圈結束後最後的值帶入函式,無法累次帶進,原因就是 "var i
的作用域 (scope) 最小單位是 function
,不是 for
"。
以下方例子做解釋,i
的作用域在 setupHelp( )
,i
為全 "域" 變數,此域即為 setupHelp( )
,在 i
進入showHelp ( )
之前就會先把迴圈跑完,再將最後的值帶入 showHelp ( )
,永遠得不到想要的結果!
事情總是要有解決辦法,當遇到 for
迴圈時,有三種取得 i
值的方法
立即函式 (IIFE — Immediately Invoked Functions Expressions)
for
迴圈中,每跑一次 i
就會跑一次立即函式,也可以運用在 setTimeout()
上,如下例:
內部的閉包函式用參數的方式送出給外層的另一個閉包
- 寫法 1:
- 寫法 2:(外層閉包用立即函式)
把
var
換成 ES2015 的新關鍵字let
let
的作用域 (scope)是{ }
區塊,e.g. if (){ }
, for (){ }
都是,所以解決了原先 var
作用域在 function(){ }
的問題!