學習 JavaScript (八) 引用類型之 Object

內存問題是 JavaScript 比較底層的東西,依葫蘆畫瓢學會了怎麼使用變量,可是對於內存的概念依然模糊,今天讓咱們一塊兒來了解一下內存在這門語言是怎麼樣的存在。前端

內存在不一樣類型的數值面前表現有很大的不一樣。咱們把值賦給一個變量,解析器必須肯定這個值是什麼類型,先來了解變量的兩個類型:程序員

  • 基本類型:簡單的數據段:Undefined、Null、Boolean、Number、String,按值訪問,能夠直接操做實際的值。算法

  • 引用類型:保存在內存中的對象:Object、Array。。JavaScript 賦值保存着對象的某個變量時,操做的是對象的引用;在爲對象添加屬性的時候,操做的是實際的對象。瀏覽器

複製基本類型的數據時,計算機會從新分配一個位置給新的變量;可是複製引用類型的數據,計算機只是複製了一個指針,指向原有的對象。因此改變其中一個引用類型數據的屬性時,訪問另外一個引用類型數據的屬性能獲得同樣的結果,好比:bash

複製基本類型並改變其中一個變量:微信

let a = 20;
let b = a;
b = 30;
console.log(a) // 20
複製代碼

基礎類型數據.jpg

複製引用類型並改變其中一個變量的屬性:函數

let m = {a:10, b:20};
let n = m;
n.a = 15;
console.log(m.a) // 15
複製代碼

引用類型數據.jpg

m,n 都指向一個引用類型的對象,因此改變 n 的屬性會致使 m 的屬性改變。上面表示的是變量之間基本的複製,可是注意:** 在全部函數的參數傳遞中,都是按值傳遞的,不是按照引用傳遞的 **。好比:源碼分析

function setName(obj){
   obj.name = "Nicholas";
   obj = new Object();
   obj.name = "Greg";
}

let person = new Object();
setName(person);
alert(person.name); // "Nicholas"
複製代碼

JS 內存空間分爲棧(stack)、堆(heap)、池(通常也會歸類爲棧中)。其中「棧」存放基本類型變量,遵循後進先出的原則;「堆」存放引用類型,堆存取數據的方式,則與書架與書很是類似,知道名字就能取出來用;池存放常量。性能

檢測一個變量是否是基本類型,用 typeof 操做符就能夠搞定,可是這個操做符在遇到對象或者 null 時,返回 Object,咱們不知道具體的類型。這時候,用 instanceof 來確認是什麼類型的對象。學習

內存泄漏與回收

再也不用到的內存,沒有及時釋放,就叫作內存泄露。

大多數語言提供自動內存管理,減輕程序員的負擔,這被稱爲「垃圾回收機制」(garbage collector)。原理很簡單:找出那些再也不繼續使用的變量,而後釋放其佔用的內存。

JavaScript 具備自動垃圾收集機制,不用程序員操太多心。而不一樣的瀏覽器可能會採起不一樣的回收策略,現代瀏覽器最經常使用的方式是標記清除,其次是引用計數。

  • 標記清除。垃圾收集器會給內存中的全部變量都添加標記,而後清除一些還會被使用的標記,即凡是環境中還會用到的變量,被其餘變量引用的變量。還有標記的變量就會被垃圾收集器刪除,完成內存的清除工做。
  • 引用計數。原理也很簡單,跟蹤每一個變量被引用的次數。這裏會產生一個棘手的問題,就是遇到 「循環引用」 就沒招了。解決的方法是再也不使用的對象,咱們把它設置成空對象 Null 。看下面的例子:
function(){
    let a = new Object();
    let b = new Object();
    
    a.oneObject = b;
    b.anotherObject = a;
}

複製代碼

上面的代碼中,a 和 b 經過各自的屬性實現相互引用,二者的被引用次數都是 2 。若是採用標記清楚策略,因爲函數執行結束,這兩個對象都離開了做用域,都會被清除。可是,採用引用計數策略,a 和 b 都還繼續存在,由於他們的引用次數永遠不會是 0。此時,只有手動斷開引用。

function(){
    let a = new Object();
    let b = new Object();
    
    a.oneObject = b;
    b.anotherObject = a;
    
    // 消除循環:
    a.oneObject = null
    b.anotherObject = null;
}

複製代碼

歡迎你們關注微信公衆號:** 可視化技術( visteacher )**

不只有前端和可視化,還有算法、源碼分析、書籍相送

我的網站:blog.kurryluo.com

各個分享平臺的 KurryLuo 都是在下。

用心學習,認真生活,努力工做!

相關文章
相關標籤/搜索