![](https://www.codedata.com.tw/wp-content/uploads/2013/04/di-51.jpg)
認識 Lambda/Closure(2)什麼是 Closure?
認識 Lambda/Closure(1)從 JavaScript 的函式物件談起 << 前情 簡化來說,Closure 是擁有閒置變數(Free variable)的運算式。閒置變數真正扮演的角色依當時參考的語彙環境(Lexical environment)而定。支援閉包的程式語言通常具有一級函式(First-class function)。建立函式不等於建立閉包。如果函式的閒置變數與當時語彙環境綁定,該函式才稱為閉包。 那麼何為閒置變數?閒置變數是指對於函式而言,既非區域變數也非參數的變數,像區域變數或參數,其作用範圍基本上在被定義的函式範圍中。它是被綁定變數(Bound variable)。 有沒有白話一點的寫法?唔!…就是… 舉個例子來說: function init() { var local = 10; setInterval(function() { alert(new Date() + ': ' + local); }, 3000); } window.onload = init; 以上程式片段中,單看粗體字部份, 區域變數理應在函式呼叫過後即失去其作用。在上例中,網頁資源載入完成後會呼叫向 這就好比 那實際如何應用 Closure 呢?常見的應用之一,就是在 JavaScript 中模擬私用性(private)。我們知道,JavaScript 本身是基於原型的(Prototype-based)語言,對於熟悉基於類別的(Class-based)語言使用者,經常需要模擬類別,而對於類別私有成員封裝,JavaScript 並沒有 function Account(bal) { var balance = bal; this.getBalance = function() { return balance; }; this.deposit = function(money) { if(money > 0) { balance += money; } }; } var account = new Account(1000); account.deposit(500); // OK account.getBalance(); // OK account.balance = 1000; // Error 上例是個用來模擬類別的典型範例,最後一行是錯誤的,因為 var account = {}; Account.call(accoount, 10000); 在我前一篇文章中談過,JavaScript 中,函式實際上是物件,因而也可以擁有方法。JavaScript 中每個函式物件都會擁有 然而,account 物件上並沒有新增 看來, 以上的討論,大概讓我們瞭解 Closure 的基本概念與作用,我不打算談太多 JavaScript 中閉包的應用,有興趣的話,可以參考 JavaScript Essence: 閉包(Closure)。 我們將逐步討論不同語言中對一級函式與閉包的支援,逐步帶出 Java 中引入 Lambda 語法的考量點有哪些。下一篇文章,會先來看看 Python 3 是如何支援一級函式與閉包。 |