1、堆疊(stack)和堆(heap)
stack為自動分配的記憶體空間,它由系統自動釋放;而heap則是動態分配的記憶體,大小也不一定會自動釋放
2、資料型別
JS分兩種資料型別:
js的六或七大資料型別:Number, String, Boolean, Undefined , Null , Object, Symbol(ES6)
基本資料型別:Number、String、Boolean、Null、 Undefined、Symbol(ES6),這些型別可以直接操作保存在變數中的實際值,
參考資料型別:Object(在JS中除了基本資料型別以外的都是物件,資料是物件,函式是物件,正則運算式是物件)
3、基本資料型別(存放在堆疊中)
基本資料型別是指存放在堆疊中的簡單資料段,資料大小確定,記憶體空間大小可以分配,它們是直接按值存放的,所以可以直接按值訪問,基本資料型別的值是沒有辦法添加屬性和方法的
var a = 10; var b = a; b = 20; console.log(a); // 10值 console.log(b); // 20值
下圖演示了這種基本資料型別賦值的程序:

4、參考資料型別(存放在堆記憶體中的物件,每個空間大小不一樣,要根據情況進行特定的配置)
參考型別是存放在堆記憶體中的物件,變數其實是保存的在堆疊記憶體中的一個指標(保存的是堆記憶體中的參考地址),這個指標指向堆記憶體,
參考型別資料在堆疊記憶體中保存的實際上是物件在堆記憶體中的參考地址,通過這個參考地址可以快速查找到保存中堆記憶體中的物件
var obj1 = new Object(); var obj2 = obj1; obj2.name = "我有名字了"; console.log(obj1.name); // 我有名字了
說明這兩個參考資料型別指向了同一個堆記憶體物件,obj1賦值給obj2,實際上這個堆記憶體物件在堆疊記憶體的參考地址復制了一份給了obj2,但是實際上他們共同指向了同一個堆記憶體物件,所以修改obj2其實就是修改那個物件,所以通過obj1訪問也能訪問的到,

var a = [1,2,3,4,5]; var b = a; // 傳址 ,物件中傳給變數的資料是參考型別的,會存盤在堆中; var c = a[0]; //傳值,把物件中的屬性/陣列中的陣列項賦值給變數,這時變數C是基本資料型別,存盤在堆疊記憶體中;改變堆疊中的資料不會影響堆中的資料 alert(b);//1,2,3,4,5 alert(c);//1 //改變數值 b[4] = 6; c = 7; alert(a); //[1,2,3,4,6];
alert(a[0]);//1
從上面我們可以得知,當我改變b中的資料時,a中資料也發生了變化;但是當我改變c的資料值時,a卻沒有發生改變,
這就是傳值與傳址的區別,因為a是陣列,屬于參考型別,所以它賦予給b的時候傳的是堆疊中的地址(相當于新建了一個不同名“指標”),而不是堆記憶體中的物件,而c僅僅是從a堆記憶體中獲取的一個資料值,并保存在堆疊中,所以b修改的時候,會根據地址回到a堆中修改,c則直接在堆疊中修改,并且不能指向a堆記憶體中,

最后: 總結基本資料型別和參考資料型別區別
1、宣告變數時記憶體分配不同
*原始型別:在堆疊中,因為占據空間是固定的,可以將他們存在較小的記憶體中-堆疊中,這樣便于迅速查詢變數的值
*參考型別:存在堆中,堆疊中存盤的變數,只是用來查找堆中的參考地址,
這是因為:參考值的大小會改變,所以不能把它放在堆疊中,否則會降低變數查尋的速度,相反,放在變數的堆疊空間中的值是該物件存盤在堆中的地址,地址的大小是固定的,所以把它存盤在堆疊中對變數性能無任何負面影響
2、不同的記憶體分配帶來不同的訪問機制
在javascript中是不允許直接訪問保存在堆記憶體中的物件的,所以在訪問一個物件時,首先得到的是這個物件在堆記憶體中的地址,然后再按照這個地址去獲得這個物件中的值,這就是傳說中的按參考訪問,
而原始型別的值則是可以直接訪問到的,
3、復制變數時的不同
1)原始值:在將一個保存著原始值的變數復制給另一個變數時,會將原始值的副本賦值給新變數,此后這兩個變數是完全獨立的,他們只是擁有相同的value而已,
2)參考值:在將一個保存著物件記憶體地址的變數復制給另一個變數時,會把這個記憶體地址賦值給新變數,
也就是說這兩個變數都指向了堆記憶體中的同一個物件,他們中任何一個作出的改變都會反映在另一個身上, (這里要理解的一點就是,復制物件時并不會在堆記憶體中新生成一個一模一樣的物件,只是多了一個保存在堆疊中指向這個物件指標的變數罷了),多了一個指標 4、引數傳遞的不同(把實參復制給形參的程序) 首先我們應該明確一點:ECMAScript中所有函式的引數都是按值來傳遞的, 但是為什么涉及到原始型別與參考型別的值時仍然有區別呢?還不就是因為記憶體分配時的差別, 1)原始值:只是把變數里的值傳遞給引數,之后引數和這個變數互不影響, 2)參考值:物件變數它里面的值是這個物件在堆記憶體中的記憶體地址,這一點你要時刻銘記在心! 因此它傳遞的值也就是這個記憶體地址,這也就是為什么函式內部對這個引數的修改會體現在外部的原因了,因為它們都指向同一個物件,轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/169948.html
標籤:JavaScript
上一篇:判斷變數的資料型別
