輕鬆學習JavaScript十一:JavaScript基本類型(包含類型轉換)和參考型別
一值的類型
早在介紹JS的資料類型的時候就提到過基本類型和參考型別,不過在說兩種類型之前,我們先來瞭解一下變數的
值的類型。在ECMAScript中,變數可以存在兩種類型的值,即原始值和引用值。
(1)原始值
儲存在棧中的簡單資料區段,也就是說,它們的值直接儲存在變數訪問的位置。
(2)引用值
儲存在堆中的對象,也就是說,儲存在變數處的值是一個指標,指向儲存物件的記憶體處。
為變數賦值時,ECMAScript的解釋程式必須判斷該值是原始類型,還是參考型別。要實現這一點,解釋程式則需
嘗試判斷該值是否為ECMAScript的基本類型之一,即Undefined類型、Null類型、Boolean類型、Number類型和
String類型。由於這些基本類型佔據的空間是固定的,所以可將他們儲存在較小的記憶體地區 - 棧中。這樣儲存便於迅
速查尋變數的值。
在許多語言中,字串都被看作參考型別,而非基本類型,因為字串的長度是可變的。ECMAScript打破了這一
傳統。
如果一個值是參考型別的,那麼它的儲存空間將從堆中分配。由於引用值的大小會改變,所以不能把它放在棧
中,否則會降低變數查尋的速度。相反,放在變數的棧空間中的值是該Object Storage Service在堆中的地址。地址的大小是固定
的,所以把它儲存在棧中對變數效能無任何負面影響。如所示:
二基本類型
ECMAScript有5種基本類型,即Undefined類型、Null類型、Boolean類型、Number類型和String類型。ECMA-
262把術語類型定義為值的一個集合,每種基本類型定義了它包含的值的範圍及其字面量表示形式。
ECMAScript提供了typeof運算子來判斷一個值是否在某種類型的範圍內。可以用這種運算子判斷一個值是否表示
一種基本類型:如果它是基本類型,還可以判斷它表示哪種基本類型。
基礎資料型別 (Elementary Data Type)和操作符typeof我們在前面的博文中也經常使用到。詳細瞭解的話可以參考我的博文:輕鬆學習
JavaScript五:JavaScript的變數和資料類型。
三類型轉換
所有程式設計語言最重要的特徵之一是具有進行類型轉換的能力。ECMAScript給開發人員提供了大量簡單的類型轉
換方法。大部分類型具有進行簡單轉換的方法,還有幾個全域方法可以用於更複雜的轉換。無論哪種情況,在
ECMAScript中,類型轉換都是簡短的一步操作。
(1)轉換成字串
ECMAScript的Boolean值、數字和字串的原始值的有趣之處在於它們是偽對象,這意味著它們實際上具有屬性
和方法。
例如,要獲得字串的長度,可以採用下面的代碼:
var sbox = "red";document.write(sbox.length);//輸出3
儘管 "red" 是基本類型的字串,它仍然具有屬性length,用於存放字串的大小。總而言之,3 種主要的原始類
型 Boolean 值、數字和字串都有 toString() 方法,可以把它們的值轉換成字串。您也許會問,“字串還有
toString()方法嗎,這不是多餘嗎?”是的,的確如此,不過ECMAScript定義所有對象都有toString()方法,無論它是偽
對象,還是真對象。因為String類型屬於偽對象,所以它一定有toString()方法。
1)Boolean 類型的toString()方法只是輸出 "true" 或 "false",結果由變數的值決定:
var bage=false;document.write(bage.toString());//輸出"false"
2)Number類型的toString()方法比較特殊,它有兩種模式,即預設模式和基模式。採用預設模式,toString()方法
只是用相應的字串輸出數字值(無論是整數、浮點數還是科學計數法),
在預設模式中,無論最初採用什麼標記法聲明數字,Number 類型的 toString() 方法返回的都是數位十進位表
示。因此,以八進位或十六進位字面量形式聲明的數字輸出的都是十進位形式的。如下所示:
var iNum1 = 10;var iNum2 = 10.0;document.write(iNum1.toString());//輸出 "10"document.write(iNum2.toString());//輸出 "10"
採用Number類型的 toString()方法的基模式,可以用不同的基輸出數字,例如二進位的基是2,八進位的基是8,
十六進位的基是16。
基只是要轉換成的基數的另一種加法而已,它是 toString() 方法的參數:
var iNum = 10;document.write(iNum.toString(2));//輸出 "1010"document.write(iNum.toString(8));//輸出 "12"document.write(iNum.toString(16));//輸出 "a"
(2)轉換成數字
ECMAScript提供了兩種把非數位原始值轉換成數位方法,即parseInt()和parseFloat()。前者把值轉換成整
數,後者把值轉換成浮點數。只有對String類型調用這些方法,它們才能正確運行;對其他類型返回的都是NaN。
1)parseInt()
在判斷字串是否是數字值前,parseInt()和 parseFloat()都會仔細分析該字串。parseInt()方法首先查看位置0
處的字元,判斷它是否是個有效數字;如果不是,該方法將返回NaN,不再繼續執行其他動作。但如果該字元是有效
數字,該方法將查看位置1處的字元,進行同樣的測試。這一過程將持續到發現非有效數位字元為止,此時
parseInt()將把該字元之前的字串轉換成數字。
例如,如果要把字串 "12345red" 轉換成整數,那麼parseInt()將返回12345,因為當它檢查到字元r 時,就會停
止檢測過程。
字串中包含的數字字面量會被正確轉換為數字,比如 "0xA" 會被正確轉換為數字10。不過,字串 "22.5" 將被
轉換成22,因為對於整數來說,小數點是無效字元。
var iNum1 = parseInt("12345red"); var iNum2 = parseInt("0xA"); var iNum3 = parseInt("56.9"); var iNum4 = parseInt("red"); document.write("iNum1="+iNum1);//返回12345 document.write("iNum2="+iNum2);//返回10 document.write("iNum3="+iNum3);//返回56 document.write("iNum3="+iNum4);//返回NaN
parseInt()方法還有基模式,可以把二進位、八進位、十六進位或其他任何進位的字串轉換成整數。基是由
parseInt()方法的第二個參數指定的。
var iNum1 = parseInt("AF", 16);var iNum2 = parseInt("10", 2);var iNum3 = parseInt("10", 8);var iNum4 = parseInt("10", 10);document.write("iNum1="+iNum1);//返回175document.write("iNum2="+iNum2);//返回2document.write("iNum3="+iNum3);//返回8document.write("iNum4="+iNum4);//返回10
2)parseFloat()方法
parseFloat()方法與parseInt()方法的處理方式相似,從位置0開始查看每個字元,直到找到第一個非有效字元為
止,然後把該字元之前的字串轉換成整數。不過,對於這個方法來說,第一個出現的小數點是有效字元。如果有兩
個小數點,第二個小數點將被看作無效的。parseFloat()會把這個小數點之前的字元轉換成數字。這意味著字元
串"11.22.33"將被解析成11.22。
使用parseFloat()方法的另一不同之處在於,字串必須以十進位形式表示浮點數,而不是用八進位或十六進位。
該方法會忽略前置0,所以八位元0102 將被解析為102。對於十六進位數0xA,該方法將返回 NaN,因為在浮點數
中,x不是有效字元。此外,parseFloat() 方法也沒有基模式。
下面是使用 parseFloat() 方法的一些樣本:
var fNum1 = parseFloat("12345red");var fNum2 = parseFloat("0xA");var fNum3 = parseFloat("11.2");var fNum4 = parseFloat("11.22.33");var fNum5 = parseFloat("0102");var fNum6 = parseFloat("red");document.write("iNum1="+iNum1);//返回12345document.write("iNum2="+iNum2);//返回NaNdocument.write("iNum3="+iNum3);//返回11.2document.write("iNum4="+iNum4);//返回11.22document.write("iNum5="+iNum5);//返回102document.write("iNum6="+iNum6);//返回NaN
(3)強制類型轉換
使用強制類型轉換來處理轉換值的類型。使用強制類型轉換可以訪問特定的值,即使它是另一種類型的。
ECMAScript 中可用的3種強制類型轉換如下:
1)Boolean(value) - 把給定的值轉換成 Boolean 型;
2)Number(value) - 把給定的值轉換成數字(可以是整數或浮點數);
3)String(value) - 把給定的值轉換成字串;
這些應該很好理解,在學習那些進階程式設計語言的時候經常會能使用到這些。
四參考型別
參考型別通常叫做類,也就是說,遇到引用值,所處理的就是對象。從傳統意義上來說,ECMAScript並不真正具
有類。事實上,除了說明不存在類,在ECMA-262中根本沒有出現“類”這個詞。ECMAScript定義了“對象定義”,邏輯
上等價於其他程式設計語言中的類。
對於JS對象的詳細解釋在前面的博文中也有,參考:輕鬆學習JavaScript九:JavaScript對象和數組。
我們再來瞭解一個判斷參考型別的操作符instanceof
在使用typeof運算子時採用參考型別儲存值會出現一個問題,無論引用的是什麼類型的對象,它都返回 "object"。
ECMAScript引入了另一個Java運算子 instanceof 來解決這個問題。
instanceof運算子與typeof運算子相似,用於識別正在處理的對象的類型。與typeof方法不同的是,instanceof方
法要求開發人員明確地確認對象為某特定類型。
例如:
var oStringObject = new String("hello world");document.write(oStringObject instanceof String);//輸出 "true"這段代碼問的是“變數oStringObject是否為 String 對象的執行個體?”oStringObject的確是 String對象的執行個體,因此結
果是 "true"。儘管不像typeof方法那樣靈活,但是在typeof方法返回 "object" 的情況下,instanceof方法還是很有用
的。
此外,ECMAScript還有偽對象一說,也就是其他的基本類型,使用new建立時也是可以作為對象的,比如:
String對象,Boolean對象和Number對象。它們是基本類型的參考型別。詳細瞭解參考:ECMAScript參考型別。
ECMAScript還包含了許多個物件,本機物件,內建對象和宿主對象。這些我們會在後面的物件導向的時候具體瞭解。
五複製變數值
在變數複製方面,基本類型和參考型別有所不同,基本類型是複製的是值本身,而參考型別複製的是地址。
我們來看具體的執行個體:
var box="Lee"; var box2=box; box2="Amy";//重新賦值後,兩個基本類型變數操作時互不影響,還是保持各自的獨立性 document.write("box2="+box2+""); document.write("box="+box);
輸出的結果為:Amy
Lee
var box=new Object();box.name="Lee";var box2=box;//把引用地址值複製給box2box2.name="Amy";//重新賦值後,兩個參考型別都指向同一個對象。name屬性只要發生改變都會更改原值。document.write(" box2.name="+box2.name+"");document.write("box.name="+box.name);輸出的結果為:Amy
Amy