在javascript中存在著兩種類型的資料:基本型別和參考型別。
基本型別簡單的說就是簡單的資料段。
引用型別是由多個值所構成的物件。
當我們進行賦值運算時,解析器會先分析資料是值型別還是參考型別。
兩種訪問方式:
基本類型值:按值訪問,操作的是他們實際保存的值;
引用類型值:按引用訪問,當查詢時,我們需要先從棧中讀取內存地址,然後再順藤摸瓜地找到保存在堆內存中的值;
以下就分別介紹一下javascript的這兩種資料型態。
一.基本資料型態:
在javascript中存在著六種基本類型資料:string、number、boolean、symbol(ES6新增)、null、undefined。
這五種基本資料類型可以直接操作保存在變數中的實際值。
程式碼實例如下:
var a=10; var b=a; b=20; console.log(a);
上面的程式碼是個簡單的賦值操作,以下做個簡單介紹。
(1).首先數字是基本資料型態。
(2).var b=a,此賦值運算其實是將a的資料拷貝一份,然後賦值給變數b。
(3).a和b是完全獨立的。
(4).b=20,修改變數b的值不會影響變數a的值。
圖示如下:
堆疊記憶體
二.引用型別資料:
在javascript中,引用類型資料儲存在堆記憶體中,但是不可以直接存取堆記憶體空間中的位置和操作堆記憶體空間。
只能透過操作物件的在堆疊記憶體中的參考位址。所以引用型別的數據,在堆疊記憶體中保存的其實是物件在堆疊記憶體中的參考位址。透過這個引用位址可以快速查找到儲存在堆記憶體中的物件。
程式碼實例:
var obj1=new Object(); var obj2=obj1; obj2.name="脚本之家"; console.log(obj1.name);
下面對程式碼上面的程式碼做一下分下。
(1).var obj1=new Object(),這是建立一個對象,是一個引用型別數據,變數obj1儲存的是物件在堆記憶體中的位址。
(2).var obj2=obj1,這個賦值操作其實是將物件在堆記憶體中的儲存位址複製給變數obj2,也就是兩個變數儲存的都是指向實際物件的記憶體位址,指向的是同一個對象。
(3).obj2.name="腳本之家",為物件新增一個屬性。
(4).console.log(obj1.name),輸出"腳本之家,因為兩個變數指向同一個物件。
圖示如下:
String一個特殊的基本資料型別
在很多語言中,String是以物件的形式表示的,但在ECMAScript裡沒有沿用這種傳統,String是當作一種基本資料類型,但它是一個比較特殊的基本型別。
看起來好像String應該做為一個引用類型,但實際上它不是,因為它不是物件。那麼看起來它應該是基本資料類型,應該是通值傳遞的方式來操作。
看下面範例:
var stra = "这是一个字符串"; var strb = stra; stra = "这是另外一个字符串"; console.log(strb); // 这是一个字符串
上面例子我們看到,彷彿stra透過值傳遞的方式複製了一份給了strb。當stra改變的時候,strb並沒有改變,似乎我們已經可以下結論,String就是個基本資料型態。
可是,因為String是可以任意長度的,透過值傳遞,一個一個的複製位元組顯示效率依然很低,看起來String也可以當作引用型別。
看下面範例:
var a = "myobject"; a.name = "myname"; console.log(a.name); // undefined
顯示String無法當作一個物件來處理。實際上,javascript裡的String是不可以改變的,javascript也沒有提供任何一個改變字串的方法和語法。
var a = "myobject"; a = a.substring(3,5) console.log(a); // bj
記得這樣做,就沒有改變String字串"myobject",只a引用了另一個字串"bj","myobject"被回收了。
所以可以這樣講,String其實並不符合上面兩種資料型別分類。它是具有兩方面屬性介於兩都之間的特殊類型。