『新手日記』Day-18 Closures(閉包)
終於進路閉包了,第一次看到時的完全看不懂,經過了幾天的加強其他觀念,慢慢的了解了他的意思
MDN解釋
A closure is the combination of a function bundled(綑綁) together (enclosed) with references to its surrounding(周圍) state (the lexical environment(詞法環境)).In other words, a closure gives you access to an outer function’s scope from an inner function.In JavaScript, closures are created(創建) every time a function is created, at function creation time.閉包(Closure)是函式以及該函式被宣告時所在的作用域環境(lexical environment)的組合。
大家是否跟我一樣是懂非懂?我們看一下範例:
閉包的目的
這個寫有一個缺點,任何人都可以去更改 counter這個變數,為了他不被污染我想到把他放進function裏面。
很棒,程式一樣可以執行,但這樣卻變成我的counter永遠都是1,這並不是我想要的,那要怎麼改呢?我的想法是,一樣放在外面但最外面用function包起來
這樣就完成了我的需求。這就是一個簡單的閉包設定,因此我們可以歸類一下閉包想解決的問題:
1.變數資料存在於的 Local Scope 裡,讓外部環境無法直接存取,以確保動作安全。
我們希望操控的變數宣告於一個 Local Scope 內,限制它的存取權。因此閉包的第一個要素:函數。
2.即使 Local 的執行環境結束,Local 環境內建立的資料還是能持續存活
先破題-閉包的第二個要素:Reference。到這邊時我有一個苦惱很久的問題:
let sellTicket = getSellTicketClosure();sellTicket(‘OneJar’)
為什麼可以執行?我原本的想法:getSellTicketClosure(sellTicket(‘OneJar’))
這就要牽扯到了『Pass by value 還是 Pass by reference』
****『新手日記』Day-17 Pass by value 和 Pass by reference每天到網路上找一張適合的照片或是當天的心情的過程居然可以變得如此開心!**
medium.com
由於他是一個Object,從這篇文章我們可以知道,要從「行為」上面來判別到底是屬於哪一種。
因為我們並沒有對變數重新賦值,因此他是屬於Reference
所以他在傳遞的是一個『位子』,我們換一個寫法相信大家就更好理解:
這樣是不是更好理解了…吧
這邊簡單總結一下:
閉包 (Closures) 是一個能存取父作用域的函數,即使父作用域已經結束
Closures重點整理:
Closures
Closures運用的技巧:
1.函數對變數的 Local Scope 封裝。
2.內部函數對外層函數變數的引用。
3.回傳內部函數的物件,形成Closures。
Closures實際上儲存的是對外層函數變數的引用 (References)。
每一個Closures中保存的都是一個獨立的環境,不同閉包間不互相干擾。
可以用立即函數的寫法來簡化語法。
理解Closures時才發現,為什麼參考資料的作者要我先去讀Pass by value 和Pass by reference,這個沒先讀熟還真的沒辦法瞭解其運作原理,我自己在***let sellTicket = getSellTicketClosure();sellTicket(‘OneJar’)***真的卡住不懂為什麼我可以用這個方式呼叫函式,在重新看完作者的文章跟自己的筆記後大概瞭解為什麼了,但應該是自己真的還沒有全盤瞭解吧,寫出來的文字並沒有辦法完整表達出原本的意思,有興趣了解的可以參考下面這篇文章,如果有寫錯的地方在請大家指正!!!
參考資料
ithelp.ithome.com.tw
www.fooish.com
blog.techbridge.cc
書籍:0 陷阱!0 誤解!8 天重新認識 JavaScript!