一.不可改變的原始值(棧資料)(五個)
數字(number),字串(string),布林值(boolean),undefined,null
其中;undefined是未定義的意思,而null是空的意思,他們倆的區別在於,null有值,不過這個值是空值,而undefined是未定義,完全沒有值的意思。null一般用作佔位。
var a = 4; var b = a; a = 10; console.log(b);//4 //原始值是把一個值a放到另一個值b裡面,改了第一個值a,第二個之值b不變
二.引用值(堆資料)
陣列(array),物件(object),函式(function)
注意:只要對變數進行賦值就會進行記憶體的重新申請
1.
var arr = [1, 2]; var arr1=arr; arr.push(3); console.log(arr1); //[1, 2, 3] //引用值時把第一個值放到第二個值裡面,改變第一個值,第二個值也改變
//引用值是在棧記憶體裡面存放堆的地址,拷貝的是地址,所以改變了arr,實際上是改變了arr指向的地址記憶體放的內容,而arr和arr1指向同一個地址,故arr1也跟著變
地址 |
變數 |
儲存值 |
0x0001 |
arr |
[1,2] [1,2,3] <–arr.push(3) |
0x0002 |
arr1 |
0x0001 |
2.
var arr = [1,2]; var arr1 = arr; arr = [1,3]; console.log(arr1);//[1,2]; //arr = [1,3]實際上是在堆內另建了一個地址,arr指向了新的地址,而arr1還是指向原來的地址,故arr1值不變
地址 |
變數 |
儲存值 |
0x0001 |
arr |
[1,2] |
0x0002 |
arr1 |
0x0001 |
0x0003 |
arr |
[1,3] |
3.要避免使用連續賦值符號:下面舉兩個例子
var a = {n:1}; var b = a; a.n= a={m:1}; console.log(a);//{m:1} console.log(b);//{n:{m:1}}
1.var a = {n:1},在記憶體中申請兩個地址,分別存放a和n;
2.var b = a;申請一個地址存放b,值指向a的地址;
3.a.n= a={m:1};
(1)(這裡對變數進行了賦值,因此要重新申請記憶體)先申請了記憶體地址n(0x0004)和a(0x0005);由於n值佔用了新的記憶體,故0x0001處 儲存值由n:0x0002變為n:0x0004;
(2)賦值;a={m:1},申請m地址(0x0006),
因此:a : {m:0x0006}—>{m:1}
b: {0x0001}—>{n:0x0004}—->{ n:0x0005}—->{n:{m:0x0006}}—>{n:{m:1}}
地址 |
變數 |
儲存值 |
0x0001 |
a (1) |
n:0x0002 n:0x0004 —(1) |
0x0002 |
-n- (1) |
1 |
0x0003 |
b |
0x0001 |
0x0004 |
n (1) |
0x0005 |
0x0005 |
a (1) |
m:0x0006 (2) |
0x0006 |
m (2) |
1 (2) |
var a = {n:1}; var b = a; a={m:1};//a重新賦值,換了一個房間,b仍然指向原來的房間(地址) a.n =a; console.log(a);//{m:1,n:{m:1,n:{..}}}//一直迴圈 console.log(b);//{n:1}