學校js感覺好漫長,斷斷續續,要堅持每天都能學到點,總結了下資料型別的轉換。

Javascript的變數是鬆散型別的,它可以儲存Javascript支援的任何資料型別,其變數的型別可以在執行時被動態改變。請看示例:

var n = 10;
n = "hello CSSer!";
n = {};

上面的示例中,首先宣告n變數並初始化其值為10(整數型別),接著將字串“hello CSSer!”賦值給n,接著再賦一個物件給它,最後n的型別是物件型別。可以看出變數n的型別具有動態性,實際程式設計中,我們建議不要頻繁改變變數的型別,因為這對除錯沒有好處。

正因為Javascript中變數型別具有動態性,在程式實際執行的過程中就需要用到型別轉換的概念。

型別轉換可以分為隱式轉換和顯式轉換,所謂隱 式轉換即程式在執行時進行的自動轉換,顯式轉換則是人為的對型別進行強制轉換。

本文將對Javascript的型別轉換進行總結。

顯式轉換

通過手動進行型別轉換,Javascript提供了以下轉型函式:

轉換為數值型別:Number(mix)、parseInt(string,radix)、parseFloat(string)
轉換為字串型別:toString(radix)、String(mix)
轉換為布林型別:Boolean(mix)

1、Number(mix)函式,可以將任意型別的引數mix轉換為數值型別。其規則為:

  1. 如果是布林值,true和false分別被轉換為1和0
  2. 如果是數字值,返回本身。
  3. 如果是null,返回0.
  4. 如果是undefined,返回NaN。
  5. 如果是字串,遵循以下規則:
    1. 如果字串中只包含數字,則將其轉換為十進位制(忽略前導0)
    2. 如果字串中包含有效的浮點格式,將其轉換為浮點數值(忽略前導0)
    3. 如果是空字串,將其轉換為0
    4. 如果字串中包含非以上格式,則將其轉換為NaN
  6. 如果是物件,則呼叫物件的valueOf()方法,然後依據前面的規則轉換返回的值。如果轉換的結果是NaN,則呼叫物件的toString()方法,再次依照前面的規則轉換返回的字串值。

下表列出了物件的valueOf()的返回值:

物件 返回值
Array 陣列的元素被轉換為字串,這些字串由逗號分隔,連線在一起。其操作與 Array.toString 和 Array.join 方法相同。
Boolean Boolean 值。
Date 儲存的時間是從 1970 年 1 月 1 日午夜開始計的毫秒數 UTC。
Function 函式本身。
Number 數字值。
Object 物件本身。這是預設情況。
String 字串值。

下面提供幾個例子,你能寫出它的正確結果嗎:

<script>
document.write("result1:"+Number(true)+"<br>");
document.write("result2:"+Number(null)+"<br>");
document.write("result3:"+Number("001122")+"<br>");
document.write("result4:"+Number("hello CSSer!")+"<br>");
document.write("result5:"+Number("0×8")+"<br>");
document.write("result6:"+Number(0*8)+"<br>");
document.write("result7:"+Number("")+"<br>");
document.write("result8:"+Number("020dd")+"<br>");
document.write("result9:"+Number("hello CSSer!")+"<br>");
</script>

結果:

result1:1
result2:0
result3:1122
result4:NaN
result5:NaN
result6:0
result7:0
result8:NaN
result9:NaN

2、parseInt(string, radix)函式,將字串轉換為整數型別的數值。它也有一定的規則

  1. 忽略字串前面的空格,直至找到第一個非空字元
  2. 如果第一個字元不是數字符號或者負號,返回NaN
  3. 如果第一個字元是數字,則繼續解析直至字串解析完畢或者遇到一個非數字符號為止
  4. 如果上步解析的結果以0開頭,則將其當作八進位制來解析;如果以0x開頭,則將其當作十六進位制來解析
  5. 如果指定radix引數,則以radix為基數進行解析

小測驗:

<script>
document.write("result1:"+parseInt(" 001122")+"<br>");
document.write("result2:"+parseInt("-1122")+"<br>");
document.write("result3:"+parseInt("0123")+"<br>");
document.write("result4:"+parseInt("hello CSSer!")+"<br>");
document.write("result5:"+parseInt("0x12")+"<br>");
document.write("result6:"+parseInt(0*8)+"<br>");
document.write("result7:"+parseInt("")+"<br>");
document.write("result8:"+parseInt("020dd")+"<br>");
document.write("result9:"+parseInt("1f",16)+"<br>"); //返回 31 (16+15)
document.write("result10:"+parseInt("22.5")+"<br>");
</script>

結果:

result1:1122
result2:-1122
result3:123
result4:NaN
result5:18
result6:0
result7:NaN
result8:20
result9:31
result10:22

3、parseFloat(string)函式,將字串轉換為浮點數型別的數值

它的規則與parseInt基本相同,但也有點區別:字串中第一個小數點符號是有效的,另外parseFloat會忽略所有前導0,如果字串包含一個可解析為整數的數,則返回整數值而不是浮點數值。

4、toString(radix)方法。除undefined和null之外的所有型別的值都具有toString()方法,其作用是返回物件的字串表示

物件 操作
Array 將 Array 的元素轉換為字串。結果字串由逗號分隔,且連線起來。
Boolean 如果 Boolean 值是 true,則返回 “true”。否則,返回 “false”。
Date 返回日期的文字表示法。
Error 返回一個包含相關錯誤資訊的字串。
Function 返回如下格式的字串,其中 functionname 是被呼叫 toString 方法函式的名稱:

function functionname( ) { [native code] }

Number 返回數字的文字表示。
String 返回 String 物件的值。
預設 返回 “[object objectname]”,其中 objectname 是物件型別的名稱。

5、String(mix)函式,將任何型別的值轉換為字串,其規則為

  1. 如果有toString()方法,則呼叫該方法(不傳遞radix引數)並返回結果
  2. 如果是null,返回”null”
  3. 如果是undefined,返回”undefined”

6、Boolean(mix)函式,將任何型別的值轉換為布林值

以下值會被轉換為false:false、”"、0、NaN、null、undefined,其餘任何值都會被轉換為true。

目錄:
1 : 偽物件  
2 : 轉換為字串  
3 : 數字轉字串  
4 : 轉換為數字  
5 : 轉換為Boolean  
6 : Number()和parseInt()的區別  
7 : String()和toString()的區別

1 : 偽物件
偽物件:javascript是一門很有意思的語言,即便是基本型別,也是偽物件,所以他們都有屬性和方法。
變數a的型別是字串,通過呼叫其為偽物件的屬性length獲取其長度 。

<script>
var a="hello javascript";
document.write("變數a的型別是:"+(typeof a));
document.write("<br>");
document.write("變數a的長度是:"+a.length);
</script>

執行效果:
變數a的型別是:string
變數a的長度是:16

2 : 轉換為字串
無論是Number,Boolean還是String都有一個toString方法,用於轉換為字串

<script>
var a=10;
document.write("數字 "+a+" 轉換為字串"+a.toString());
document.write("<br>"); var b=true;
document.write("布林 "+b+" 轉換為字串"+b.toString());
document.write("<br>"); var c="hello javascript";
document.write("字串 "+c+" 轉換為字串 "+c.toString());
document.write("<br>"); </script>

執行效果:
數字 10 轉換為字串10
布林 true 轉換為字串true
字串 hello javascript 轉換為字串 hello javascript

3 : 數字轉字串
Number轉換為字串的時候有預設模式和基模式兩種

<script>
var a=10;
document.write('預設模式下,數字10轉換為十進位制的'+a.toString()); //預設模式,即十進位制
document.write("<br>"); document.write('基模式下,數字10轉換為二進位制的'+a.toString(2)); //基模式,二進位制
document.write("<br>"); document.write('基模式下,數字10轉換為八進位制的'+a.toString(8)); //基模式,八進位制
document.write("<br>"); document.write('基模式下,數字10轉換為十六進位制的'+a.toString(16)); //基模式,十六進位制
document.write("<br>"); </script>

執行效果:
預設模式下,數字10轉換為十進位制的10
基模式下,數字10轉換為二進位制的1010
基模式下,數字10轉換為八進位制的12
基模式下,數字10轉換為十六進位制的a

4 : 轉換為數字
javascript分別提供內建函式 parseInt()和parseFloat(),轉換為數字
注:如果被轉換的字串,同時又數字和字元構成,那麼parseInt會一直定位數字,直到出現非字元。 所以"10abc" 會被轉換為 10
思考題: 字串"10abc8" 又會被轉換為多少呢?

<script>
document.write("字串的\"10\"轉換為數字的:"+parseInt("10")); //轉換整數
document.write("<br>");
document.write("字串的\"3.14\"轉換為數字的:"+parseFloat("444 3.14"));//轉換浮點數
document.write("<br>");
document.write("字串的\"10abc\"轉換為數字的:"+parseInt("10abc")); //判斷每一位,直到發現不是數字的那一位
document.write("<br>"); document.write("字串的\"hello javascript\"轉換為數字的:"+parseInt("h5555ello javascript")); //如果完全不包含數字,則返回NaN - Not a Number
document.write("<br>"); </script>

執行效果:
字串的"10"轉換為數字的:10
字串的"3.14"轉換為數字的:444
字串的"10abc"轉換為數字的:10
字串的"hello javascript"轉換為數字的:NaN

5 : 轉換為Boolean  
使用內建函式Boolean() 轉換為Boolean值
當轉換字串時:
非空即為true
當轉換數字時:
非0即為true
當轉換物件時:
非null即為true

<script>
document.write("空字串''轉換為布林後的值:"+Boolean("")); //空字串
document.write("<br>");
document.write("非空字元'hello javascript '串轉換為布林後的值:"+Boolean("hello javascript")); //非空字串
document.write("<br>");
document.write("數字 0 轉換為布林後的值:"+Boolean(0)); //0
document.write("<br>");
document.write("數字 3.14 轉換為布林後的值:"+Boolean(3.14)); //非0
document.write("<br>");
document.write("空物件 null 轉換為布林後的值:"+Boolean(null)); //null
document.write("<br>");
document.write("非物件 new Object() 轉換為布林後的值:"+Boolean(new Object())); //物件存在
document.write("<br>");
</script>

執行效果:
空字串''轉換為布林後的值:false
非空字元'hello javascript '串轉換為布林後的值:true
數字 0 轉換為布林後的值:false
數字 3.14 轉換為布林後的值:true
空物件 null 轉換為布林後的值:false
非物件 new Object() 轉換為布林後的值:true

6 : Number()和parseInt()的區別  
Number()和parseInt()一樣,都可以用來進行數字的轉換
區別在於,當轉換的內容包含非數字的時候,Number() 會返回NaN(Not a Number)
parseInt() 要看情況,如果以數字開頭,就會返回開頭的合法數字部分,如果以非數字開頭,則返回NaN

<script>
document.write("通過Number() 函式轉換字串'123' 後得到的數字:"+Number("123")); //正常的
document.write("<br>");
document.write("通過Number() 函式轉換字串'123abc' 後得到的數字:"+Number("123abc")); //包含非數字
document.write("<br>");
document.write("通過Number() 函式轉換字串'abc123' 後得到的數字:"+Number("abc123")); //包含非數字
document.write("<br>"); document.write("通過parseInt() 函式轉換字串'123' 後得到的數字:"+parseInt("123")); //正常的
document.write("<br>");
document.write("通過parseInt() 函式轉換字串'123abc' 後得到的數字:"+parseInt("123abc")); //包含非數字,返回開頭的合法數字部分
document.write("<br>");
document.write("通過parseInt() 函式轉換字串'abc123' 後得到的數字:"+parseInt("abc123")); //包含非數字,以非數字開頭,返回NaN
document.write("<br>"); </script>

執行效果:
通過Number() 函式轉換字串'123' 後得到的數字:123
通過Number() 函式轉換字串'123abc' 後得到的數字:NaN
通過Number() 函式轉換字串'abc123' 後得到的數字:NaN
通過parseInt() 函式轉換字串'123' 後得到的數字:123
通過parseInt() 函式轉換字串'123abc' 後得到的數字:123
通過parseInt() 函式轉換字串'abc123' 後得到的數字:NaN

7 : String()和toString()的區別
String()和toString()一樣都會返回字串,區別在於對null的處理
String()會返回字串"null"
toString() 就會報錯,無法執行

<script>
var a = null;
document.write('String(null) 把空物件轉換為字串:'+String(a));
document.write("<br>");
document.write('null.toString() 就會報錯,所以後面的程式碼不能執行');
document.write(a.toString());
document.write("因為第5行報錯,所以這一段文字不會顯示");
</script>

執行效果:
String(null) 把空物件轉換為字串:null
null.toString() 就會報錯,所以後面的程式碼不能執行

隱式轉換

在某些情況下,即使我們不提供顯示轉換,Javascript也會進行自動型別轉換,主要情況有:

1. 用於檢測是否為非數值的函式:isNaN(mix)

isNaN()函式,經測試發現,該函式會嘗試將引數值用Number()進行轉換,如果結果為“非數值”則返回true,否則返回false。

2. 遞增遞減操作符(包括前置和後置)、一元正負符號操作符

這些操作符適用於任何資料型別的值,針對不同型別的值,該操作符遵循以下規則(經過對比發現,其規則與Number()規則基本相同):

  1. 如果是包含有效數字字元的字串,先將其轉換為數字值(轉換規則同Number()),在執行加減1的操作,字串變數變為數值變數。
  2. 如果是不包含有效數字字元的字串,將變數的值設定為NaN,字串變數變成數值變數。
  3. 如果是布林值false,先將其轉換為0再執行加減1的操作,布林值變數程式設計數值變數。
  4. 如果是布林值true,先將其轉換為1再執行加減1的操作,布林值變數變成數值變數。
  5. 如果是浮點數值,執行加減1的操作。
  6. 如果是物件,先呼叫物件的valueOf()方法,然後對該返回值應用前面的規則。如果結果是NaN,則呼叫toString()方法後再應用前面的規則。物件變數變成數值變數。

小測驗:

分別對以下型別的值執行後置遞增操作,結果是什麼?

“2″, ”02dd”, ”", false, 22.5, +”", -false, +new Date()

3. 加法運算操作符

加號運算操作符在Javascript也用於字串連線符,所以加號操作符的規則分兩種情況:

  • 如果兩個操作值都是數值,其規則為:
  1. 如果一個運算元為NaN,則結果為NaN
  2. 如果是Infinity+Infinity,結果是Infinity
  3. 如果是-Infinity+(-Infinity),結果是-Infinity
  4. 如果是Infinity+(-Infinity),結果是NaN
  5. 如果是+0+(+0),結果為+0
  6. 如果是(-0)+(-0),結果為-0
  7. 如果是(+0)+(-0),結果為+0
  • 如果有一個操作值為字串,則:
  1. 如果兩個操作值都是字串,則將它們拼接起來
  2. 如果只有一個操作值為字串,則將另外操作值轉換為字串,然後拼接起來
  3. 如果一個運算元是物件、數值或者布林值,則呼叫toString()方法取得字串值,然後再應用前面的字串規則。對於undefined和null,分別呼叫String()顯式轉換為字串。

可以看出,加法運算中,如果有一個操作值為字串型別,則將另一個操作值轉換為字串,最後連線起來。

4. 乘除、減號運算子、取模運算子

這些操作符針對的是運算,所以他們具有共同性:如果操作值之一不是數值,則被隱式呼叫Number()函式進行轉換。具體每一種運算的詳細規則請參考ECMAScript中的定義。

5. 邏輯操作符(!、&&、||)

邏輯非(!)操作符首先通過Boolean()函式將它的操作值轉換為布林值,然後求反。

邏輯與(&&)操作符,如果一個操作值不是布林值時,遵循以下規則進行轉換:

  1. 如果第一個運算元經Boolean()轉換後為true,則返回第二個操作值,否則返回第一個值(不是Boolean()轉換後的值)
  2. 如果有一個操作值為null,返回null
  3. 如果有一個操作值為NaN,返回NaN
  4. 如果有一個操作值為undefined,返回undefined

邏輯或(||)操作符,如果一個操作值不是布林值,遵循以下規則:

  1. 如果第一個操作值經Boolean()轉換後為false,則返回第二個操作值,否則返回第一個操作值(不是Boolean()轉換後的值)
  2. 對於undefined、null和NaN的處理規則與邏輯與(&&)相同

6. 關係操作符(<, >, <=, >=)

與上述操作符一樣,關係操作符的操作值也可以是任意型別的,所以使用非數值型別參與比較時也需要系統進行隱式型別轉換:

  1. 如果兩個操作值都是數值,則進行數值比較
  2. 如果兩個操作值都是字串,則比較字串對應的字元編碼值
  3. 如果只有一個操作值是數值,則將另一個操作值轉換為數值,進行數值比較
  4. 如果一個運算元是物件,則呼叫valueOf()方法(如果物件沒有valueOf()方法則呼叫toString()方法),得到的結果按照前面的規則執行比較
  5. 如果一個操作值是布林值,則將其轉換為數值,再進行比較

注:NaN是非常特殊的值,它不和任何型別的值相等,包括它自己,同時它與任何型別的值比較大小時都返回false。

7. 相等操作符(==)

相等操作符會對操作值進行隱式轉換後進行比較:

  1. 如果一個操作值為布林值,則在比較之前先將其轉換為數值
  2. 如果一個操作值為字串,另一個操作值為數值,則通過Number()函式將字串轉換為數值
  3. 如果一個操作值是物件,另一個不是,則呼叫物件的valueOf()方法,得到的結果按照前面的規則進行比較
  4. null與undefined是相等的
  5. 如果一個操作值為NaN,則相等比較返回false
  6. 如果兩個操作值都是物件,則比較它們是不是指向同一個物件