iT邦幫忙

0

記憶體模型 執行環境 (Execution Context)、執行堆疊 (Execution Stack)、堆積 (Heap)、閉包(Closure)

  • 分享至 

  • xImage
  •  

執行環境 (Execution Context)

只有函式執行時,才會創建一個新的臨時執行環境。這個環境會在函式 return (結束) 後立即銷毀,從堆疊上移除 (除非閉包機制將其部分記憶體保留在堆積上)。

建立環境兩階段

創建階段 (Creation Phase)
(待新增)

執行階段 (Execute Phase)
(待新增)

堆疊 (Stack) 是結構化的,它知道每個函式佔用多少空間,並且嚴格按照 LIFO 順序管理。
堆積 (Heap) 是非結構化的,因為它要儲存各種大小不一、壽命不定的數據,彼此之間沒有嚴格的順序關係。

執行堆疊 (Execution Stack)/呼叫堆疊(Call Stack)

這是 JS 引擎用來管理函式呼叫順序的機制。

運作方式:當程式執行時,每次呼叫一個函式,就會將該函式相關的資訊(稱為堆疊框,stack frame)推入堆疊的最頂端。

後進先出 (LIFO):由於函式是後進先出 (Last-In-First-Out) 的原則,最後被呼叫的函式會最先執行完畢。當一個函式執行完畢後,它的堆疊框會從堆疊中移除,程式會回到呼叫它的那個函式繼續執行。
Javascript 是一種「單執行續 (single-thread)」的語言,意思就是一次只能做一件事情,如果安排了很多事情要給他做,他就會讓這些事情去排隊,再一件一件做。

後進先出 (LIFO)

最後進來的,最先出去 (Last-In, First-Out)。
堆疊就是用這個原則來管理函式:最後被呼叫的函式,必須先執行完畢並退出,才能執行底下的函式。

堆積 (Heap)

這是用於長期、非結構化儲存的區域。
長期:所有的物件 (Objects)、陣列 (Arrays)、函式定義,以及閉包物件本身,都儲存在堆積上。
非結構化:數據不是按照嚴格的 LIFO 順序管理,而是以分散的方式儲存複雜物件。

閉包(Closure)

概念:指一個函式能夠持續存取其外部作用域變數的現象。這是我們在程式碼中討論的抽象行為。

閉包物件 (Closure Object)

實作:指JS引擎在堆積(Heap)上創建出來、用來物理性地儲存那些被記住的外部變數的數據結構。
是堆積上的一個物件,讓一個已經被銷毀的執行環境,(堆疊)中的變數,仍然能被外部的函式(也在堆積上)存取。

觸發條件:詞法作用域 (Lexical Scoping) 是閉包的基礎。它決定了函式在定義時,就會鎖定它周圍的作用域變數,與實際執行位置無關。只要一個函式 function() {},被定義在另一個作用域內部,並且參考了外部作用域的變數,它就會形成閉包。無論這個函式是被單獨回傳,還是作為物件的方法被包裝回傳,這個規則都成立。而只有函式才會形成閉包,物件 {} 則不會。

雙層/多層函式:閉包可以發生在兩層、三層甚至更多層的函式中,只要內層函式參考了它任何外層的變數。

物件內的函式:如果一個物件的方法 (method) 引用了該物件構造函式(如 class)中的私有變數,它也會形成閉包。

函式內的物件:函式回傳一個物件時,該物件只是在堆積上有一個外部引用。雖然它也不會被回收,但它沒有保留外部函式的作用域,就不會形成閉包。

閉包(Closure)vs閉包物件 (Closure Object)

當我們說 閉包 時,我們談論的是行為;
當我們說 閉包物件 時,我們談論的是讓這個行為得以發生的記憶體容器。兩者是一體的。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言