point
記憶體空間管理 資料類型 資料結構 執行內容
變數對象 使用中的物件 範圍 範圍鏈 閉包
important
在學習記憶體空間之前,我們需要對三種資料結構有一個直觀的認知。他們分別是堆(heap),棧(stack)與隊列(queue)。 JavaScript的執行內容產生之後,會建立一個叫做變數對象的特殊對象
基礎資料類型都是一些簡單的資料區段,JavaScript中有5中基礎資料類型,分別是Undefined、Null、Boolean、Number、String。基礎資料類型都是按值訪問,因為我們可以直接操作儲存在變數中的實際的值。
與其他語言不同,JS的引用資料類型,比如數組Array,它們值的大小是不固定的。引用資料類型的值是儲存在堆記憶體中的對象
JavaScript不允許直接存取堆記憶體中的位置,因此我們不能直接操作對象的堆記憶體空間。在操作對象時,實際上是在操作對象的引用而不是實際的對象。
JavaScript有自動垃圾收集機制,那麼這個自動垃圾收集機制的原理是什麼呢。其實很簡單,就是找出那些不再繼續使用的值,然後釋放其佔用的記憶體。垃圾收集器會每隔固定的時間段就執行一次釋放操作。在JavaScript中,最常用的是通過標記清除的演算法來找到哪些對象是不再繼續使用 在局部範圍中,當函數執行完畢,局部變數也就沒有存在的必要了,因此垃圾收集器很容易做出判斷並回收。但是全域變數什麼時候需要自動釋放記憶體空間則很難判斷,因此在我們的開發中,需要盡量避免使用全域變數。 每次當控制器轉到可執行代碼的時候,就會進入一個執行內容。執行內容可以理解為當前代碼的執行環境,它會形成一個範圍。全域環境、函數環境
因此在一個JavaScript程式中,必定會產生多個執行內容,在我的上一篇文章中也有提到,JavaScript引擎會以棧的方式來處理它們,這個棧,我們稱其為函數調用棧(call stack)。棧底永遠都是全域上下文,而棧頂就是當前正在執行的上下文。
執行內容可以理解為函數執行的環境,每一個函數執行時,都會給對應的函數建立這樣一個執行環境。
全域上下文在瀏覽器視窗關閉後出棧
執行內容的生命週期,建立階段:建立變數對象、建立範圍鏈、確定this指向 執行階段:變數賦值、函數引用、其他代碼 調用啟用時,會開始建立對應的執行內容,在執行內容產生的過程中,變數對象,範圍鏈,以及this的值會分別被確定。 我們已經知道,當調用一個函數時(啟用),一個新的執行內容就會被建立。而一個執行內容的生命週期可以分為兩個階段。
建立階段 在這個階段中,執行內容會分別建立變數對象,建立範圍鏈,以及確定this的指向。
代碼執行階段 建立完成之後,就會開始執行代碼,這個時候,會完成變數賦值,函數引用,以及執行其他代碼。
變數對象的建立,依次經曆了以下幾個過程。 建立arguments對象。檢查當前上下文中的參數,建立該對象下的屬性與屬性值。 檢查當前內容相關的函式宣告,也就是使用function關鍵字聲明的函數。在變數對象中以函數名建立一個屬性,屬性值為指向該函數所在記憶體位址的引用。如果函數名的 屬性已經存在,那麼該屬性將會被新的引用所覆蓋。 檢查當前上下文中的變數聲明,每找到一個變數聲明,就在變數對象中以變數名建立一個屬性,屬性值為undefined。如果該變數名的屬性已經存在,為了防止同名的 函數被修改為undefined,則會直接跳過,原屬性值不會被修改。 範圍鏈,是由當前環境與上層環境的一系列變數對象組成,它保證了當前執行環境對符合存取權限的變數和函數的有序訪問。範圍鏈是由一系列變數對象組成,我們可以在這個單向通道中,查詢變數對象中的標識符,這樣就可以訪問到上一層範圍中的變數了
很多人會誤解為當前範圍與上層範圍為內含項目關聯性,但其實並不是。以最前端為起點,最末端為終點的單方向通道我認為是更加貼切的形容。所有的最末端都為全域變數對象。
是進入執行階段之後,變數對象轉變為了使用中的物件,裡面的屬性都能被訪問了,然後開始進行執行階段的操作
如果再面試的時候被問到變數對象和使用中的物件有什麼區別,就又可以自如的應答了,他們其實都是同一個對象,只是處於執行內容的不同生命週期。不過只有處於函數調用棧棧頂的執行內容中的變數對象,才會變成使用中的物件。
全域上下文有一個特殊的地方,它的變數對象,就是window對象。而這個特殊,在this指向上也同樣適用,this也是指向window。 在JavaScript中,我們可以將範圍定義為一套規則,這套規則用來管理引擎如何在當前範圍以及嵌套的子範圍中根據變數名或者函數名進行變數尋找,只存在全域範圍與函數範圍。 範圍與執行內容是完全不同的兩個概念。我知道很多人會混淆他們,但是一定要仔細區分。JavaScript代碼的整個執行過程,分為兩個階段,代碼編譯階段與代碼執行階段。編譯階段由編譯器完成,將代碼翻譯成可執行代碼,這個階段範圍規則會確定。執行階段由引擎完成,主要任務是執行可執行代碼,執行內容在這個階段建立。一個是在編譯階段確定的,一個是在執行階段建立的
原文地址:http://www.jianshu.com/p/cd3fee40ef59