注意: 如果你對閉包已經很熟了,TL;DR
這是一篇翻譯文章,
旨在分享優質的技術觀點,也同時透過翻譯來加強我自身對於文章知識的印象。
可能會進行語意調整,以確保內容的清晰流暢,但我會盡量保留原文的核心思想與資訊,
如果您對內容有任何疑問、想討論相關主題或指出我的翻譯問題,歡迎隨時與我聯繫!原文出處:
Why this problem is important ? - by includeRajat
契子
雖說近期沒工作,但覺得還是要維持對於專業知識的理解,不然之後回職場就被海放千里了啊,這時突然看到 Leetcode 的題目 - 2667. Create Hello World Function,點進去發現這題出奇的簡單。題目要求你製作一個不論傳入什麼參數結果都會回傳 “Hello World” 的函式。應該對於大多工程師來說都是可以秒解了,於是我開始好奇地去爬會不會有什麼解法或我所忽略的妙處。
結果每篇文章幾乎都是直接 return “Hello World” 來解題,沒什麼獨特的地方,而下方留言的開發者也幾乎不約而同的用開玩笑的角度瘋狂吹捧「這題超難」、「超強解法」 等等的玩笑。
在這麼多篇氣氛輕鬆的文章之中,我注意到本文的重點… 有個網友很認真的以「為什麼這題很重要」作為標題來論述這題目背後能帶出的概念,原本也只覺得搞笑的我,就跟著轉換了態度從中獲得不同的看法,所以希望翻譯成中文給自己加強這篇文章帶來的知識,以及轉換心態的重要性。
正文開始
為什麼 Leetcode 第 2667 題很重要?
我們在解題的時候會發現本題真的非常簡單,但為什麼 Leetcode 要 po 這題?
因為這題使用了一個大多面試都會詢問的重要概念 —— 閉包(Closure)。
什麼是閉包?
閉包是一種函式,他能夠讀取外層(封閉)語法作用域的變數,
即便外層函式已經返回(return),仍然可以進行讀取。
我們來拆解其定義 -
首先可以肯定的,必包是一種函式。
function someTypeOfFunction(y) { |
第二,
他可以獲取其語法作用域以外的變數。通常我們可以直接說它能獲得在函式之外宣告的變數。
const variable = "在函式之外宣告的變數"; |
第三,
即便 outerFunction
已經返回,我們仍然可以取得在閉包之外宣告的變數。
const outerFunction = () => { |
重點是,為什麼這很重要?
透過這種操作,我們就可以在 javascript 中建立私有變數 (private variable)。
function counter() { |
上面範例中 counter
會返回帶有兩個方法(increment
和 decrement
)的物件,這些方法都能夠取得 count
變數。而這個變數被封閉在返回的物件中、成為了一個私有變數。兩個方法可以修正 count
,但除此之外都沒有辦法能夠讀寫這個變數,從而確保了資料的隱蔽性。
常見的閉包用法:
- 物件導向中的私有變數、函式。
- 加工函式可以根據參數去建立特定行為的函式。
- 記憶(Memoization),暫存複雜函式的結果,避免重複運算。
- 事件監聽器與 callback 需要獲得封閉作用域的變數。
- 部分應用與柯里化,透過一些固定值來建立新函式。
- 使用
forEach
、map
、filter
或reduce
對陣列迭代,
這些函式都接受另一個函式作為參數,並可以利用閉包來取得外層作用域中的變數。 - 在引入 ES6 的 let 與 const 之前,可以用來模仿區塊作用域 (block scope)。
- 在 promise 跟異步程式中,可利用閉包來取得需要在 callback 中使用的變數。
- 在 Redux 中管理 state (React 生態圈中一種知名的狀態管理工具)
- 建立在程式庫 (codebase) 中,需在不同地方調用且需要獲得封閉作用域的工具函式。
Comments