JS內存機制

在看JS內存機制之前我們先來看一下JS是門什麼樣的語言,他又有哪些變量類型。

動靜態,強弱類型

靜態:在使用之前就需要確認其變量數據類型。

動態:在運行過程中需要檢查數據類型

強類型:不支持隱式類型轉換。

弱類型:支持隱式類型轉換。

而JS呢,則是一種動態弱類型的語言。

JS的變量類型

JS的變量類型分爲8種,注意⚠️:其中Symbol爲ES6新增,BigInt爲ES11新增

類型

描述

Number

基於IEE754標準的雙精度64位二進制格式的值,範圍爲2的63次方減一到負的2的63次方減一

String

用於表示文本數據,⚠️JS裏面字符串是不可變的

Boolean

布爾值,只有true和false

Undefined

一個沒有被賦值的變量值爲undefined,變量提升的默認值也是undefined

Null

空的初始值,只有一個值Null

Symbol

符號類型,唯一且不可修改

BigInt

可以用任意精度表示數字,即使超出Number的安全範圍也可以正常操作

Object

對象,可以看作一組屬性的集合

注意:⚠️

  • typeOf Null 爲Object,原因在於在JS最初版本000開頭的爲對象,而Null全爲0,故導致爲Object。
  • 前七種稱爲基本數據類型(原始數據類型),最後一種爲複雜數據類型又稱爲引用數據類型(合成數據類型)。

 

JS的內存

js的內存空間分爲棧(stack)、堆(heap)、池(一般也會歸類棧中)。其中棧存放變量,堆存放複雜對象,池存放常量,所以也叫常量池。

棧空間就是我們之前反覆提及的調用棧是用來存儲執行上下文的。基本數據類型的變量值都被保存在執行上下文中,而執行上下文又被壓入到棧中,所以你也可以認爲基本數據類型都是存放在棧中的(除了閉包)

複雜數據類型的變量都是存儲在堆中的,而複雜數據類型的引用則是存儲在棧中的。當訪問複雜數據類型的時候相當於多了一道轉手的流程。

對比

區別

數據結構

棧結構

堆結構

存儲內容

基本數據類型和複雜數據類型的引用

複雜數據類型和閉包

空間

空間比較小

空間很大

經過以上我們可以得出除閉包外,基本數據類型的變量都是存儲在棧中,而複雜數據類型都是存儲在堆中,而複雜數據類型的引用則存儲在棧中。

注意⚠️:原始類型的賦值會完整複製變量值,而引用類型的賦值是複製引用地址。

問題

爲什麼一定要分堆和棧兩個存儲空間呢?

原因在於 JavaScript 引擎需要用棧來維護程序執行期間上下文的狀態,如果棧空間大了話,所有的數據都存放在棧空間裏面,那麼會影響到上下文切換的效率,進而又影響到整個程序的執行效率

JS變量有哪幾類?

JS裏面堆存儲和棧存儲有什麼區別?

Null和Undefined的區別?

原因:

其實最初JS也是隻有null,但後來JS的設計者覺得這樣不太好,原因有如下兩點

  • null像在Java裏一樣,被當成一個對象。但是,JavaScript的數據類型分成原始類型(primitive)和合成類型(complex)兩大類,Brendan Eich覺得表示"無"的值最好不是對象。
  • JS的最初版本沒有包括錯誤處理機制,發生數據類型不匹配時,往往是自動轉換類型或者默默地失敗。Brendan Eich覺得,如果null自動轉爲0,很不容易發現錯誤。

區別:

null是一個表示"無"的對象,轉爲數值時爲0;undefined是一個表示"無"的原始值,轉爲數值時爲NaN。

null代表沒有對象,即此處不應該有值,用法:

  1. 作爲函數的參數,表示該函數的參數不是對象。
  2. 作爲對象原型鏈的終點。

undefined表示"缺少值",就是此處應該有一個值,但是還沒有定義,使用:

一變量二函數一對象

  1. 變量被聲明瞭,但沒有賦值時,就等於undefined。
  2. 調用函數時,應該提供的參數沒有提供,該參數等於undefined。
  3. 函數沒有返回值時,默認返回undefined。
  4. 對象沒有賦值的屬性,該屬性的值爲undefined。

 

參考

阮一峯Null和undefined區別

瀏覽器工作原理與實戰

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