天天看點

JS進階 04-00 變量、作用域和記憶體問題

按照ECMA-262的定義,JavaScript的變量與其他語言的變量有很大差別。JavaScript變量松散類型的本質,決定了它隻是在特定時間用于儲存特定值的一個名字而已。由于不存在定義某個變量必須要儲存何種資料類型值的規則,變量的值及其資料類型可以在腳本的生命周期内改變。盡管從某種角度看,這可能是一個既有趣又強大,同時又容易出問題的特性,但JavaScript變量實際的複雜程度還遠不止如此。

JavaScript變量可以用來儲存兩種類型的值:基本類型值和引用類型值。基本類型的值源自以下5 種基本資料類型:Undefined、Null、Boolean、Number 和 String。基本類型值和引用類型值具有以下特點:

  • 基本類型值在記憶體中占據固定大小的空間,是以被儲存在棧記憶體中;
  • 從一個變最向另一個變量複制基本類型的值,會建立這個值的一個副本;
  • 引用類型的值是對象,儲存在堆記憶體中;
  • 包含引用類型值的變量實際上包含的并不是對象本身,而是一個指向該對象的指針;
  • 從一個變量向另一個變量複制引用類型的值,複制的其實是指針,是以兩個變就最終都指向同 一個對象;
  • 确定一個值是哪種基木類型可以使用​

    ​typeof​

    ​​操作符,而确定一個值是哪種引用類型可以使用​

    ​instanceof​

    ​ 操作符
  • 執行環境有全局執行環境(也稱為全局環境)和函數執行環境之分;
  • 每次進入一個新執行環境,都會建立一個用于搜尋變量和函數的作用域鍊;
  • 函數的局部環境不僅有權通路國數作用域中的變量,而且有權通路其包含(父)環境,乃至全 局環境;
  • 全局環境隻能通路在全局環境中定義的變量和函數,而不能直接通路局部環境中的任何資料;
  • 變赴的執行環境有助于确定應該何時釋放記憶體。
  • 離開作用域的值将被自動标記為可以回收,是以将在垃圾收集期間被删除。
  • “标記清除”是目前主流的垃圾收集算法,這種算法的思想是給目前不使用的值加上标記,然 後再回收其記憶體。
  • 另一種垃圾收集算法是“引用計數”,這種算法的思想是跟蹤記錄所有值被引用的次數。JavaScript 引擎目前都不再使用這種算法;但在IE中通路非原生JavaScript對象(如DOM元素)時,這種算法仍然可能會導緻問題。
  • 當代碼中存在循環引用現象時,“引用計數” 算法就會導緻問題。
  • 解除變量的引用不僅有助于消除循環引用現象,而且對垃圾收集也有好處。為了確定有效地回 收記憶體,應該及時解除不再使用的全局對象、全局對象屬性以及循環引用變量的引用。

繼續閱讀