對執行上下文的理解

執行上下文

 

執行上下文總共有三種類型

  • 全局執行上下文:只有一個,瀏覽器中的全局對象就是 window 對象,this 指向這個全局對象。
  • 函數執行上下文:存在無數個,只有在函數被調用的時候纔會被創建,每次調用函數都會創建一個新的執行上下文。
  • Eval 函數執行上下文: 指的是運行在 eval 函數中的代碼,很少用而且不建議使用。

棧數據結構

棧的結構就是後進先出**(LIFO)**

 

堆數據結構

就是引用類型,像數組和對象,我們知道索引就可以獲取對應的值

堆數據結構是一種樹狀結構。它的存取數據的方式與書架和書非常相似。我們只需要知道書的名字就可以直接取出書了,並不需要把上面的書取出來。JSON格式的數據中,我們存儲的key-value可以是無序的,因爲順序的不同並不影響我們的使用,我們只需要關心書的名字。

隊列

隊列是一種先進先出(FIFO)的數據結構,這是事件循環(Event Loop)的基礎結構

變量的存放

從上面看其實這已經很明顯了,已知數據類型有8種,String、null、undefind、boolean、Object、symbol(唯一值)、Number、bigInt(大數值/谷歌67) 除了Object 爲引用類型,其他的都是基本類型 .

基本類型 :是存在棧內存中的,佔有一定的空間,通過值來訪問,

引用類型因爲這種值的大小不固定,因此不能把它們保存到棧內存中,但內存地址大小的固定的,因此保存在堆內存中,在棧內存中存放的只是該對象的訪問地址。當查詢引用類型的變量時, 先從棧中讀取內存地址, 然後再通過地址找到堆中的值。對於這種,我們把它叫做按引用訪問

其實除了這兩個外,其實還有一個概念,叫,其實他也是棧的一種,存儲的是常量,故也叫常量池

有一個疑問:那麼閉包中的數據是存在哪裏的:

閉包中的變量並不保存中棧內存中,而是保存在堆內存中,這也就解釋了函數之後之後爲什麼閉包還能引用到函數內的變量

閉包的簡單定義是:函數 A 返回了一個函數 B,並且函數 B 中使用了函數 A 的變量,函數 B 就被稱爲閉包。

函數 A 彈出調用棧後,函數 A 中的變量這時候是存儲在堆上的,所以函數B依舊能引用到函數A中的變量。現在的 JS 引擎可以通過逃逸分析辨別出哪些變量需要存儲在堆上,哪些需要存儲在棧上。

內存空間管理

JavaScript的內存生命週期是

  • 1、分配你所需要的內存
  • 2、使用分配到的內存(讀、寫)
  • 3、不需要時將其釋放、歸還

JavaScript有自動垃圾收集機制,最常用的是通過標記清除的算法來找到哪些對象是不再繼續使用的,使用a = null其實僅僅只是做了一個釋放引用的操作,讓 a 原本對應的值失去引用,脫離執行環境,這個值會在下一次垃圾收集器執行操作時被找到並釋放。

在局部作用域中,當函數執行完畢,局部變量也就沒有存在的必要了,因此垃圾收集器很容易做出判斷並回收。但是全局變量什麼時候需要自動釋放內存空間則很難判斷,因此在開發中,需要儘量避免使用全局變量。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章