JavaScript類型轉換機制及各類型檢查方法

JavaScript類型轉換機制及各類型檢查方法

    在JavaScript中,我們通常會碰到有關於值比較的問題。由於JavaScript類型轉換機制的存在,往往會遇到一些尷尬的問題。比如我們會遇到這樣的問題 alert(true == 1); // 結果返回true 以及 alert([] == 0); // 結果依舊返回true 等等問題。在介紹JavaScript類型轉換機制之前,首先我們必須瞭解一下JavaScript的原始值及引用對象。

1 JavaScript的原始值及引用對象

    JavaScript的值分爲兩種類型:原始類型和引用類型(也稱做對象)。
        原始類型包括:字符串、數字、布爾值、null和undefined
        引用類型包括:數組和函數

1.1 原始類型與引用類型的區別

    1、原始類型的值是不可變的,引用類型的值是可變的。

        var str1 = "hello";    // 首先存在一個爲"hello"的字符串,我們使用變量str1接收
        var str2 = str1;    // 然後我們將str1賦值給str2
        str1 = str1.toUpperCase();    // 接着我們調用一下字符串的方法,將字符串中的字母全部大寫
        alert(str2);            // 最後我們輸出一下str2 結果依舊是 hello


        當然舉這樣一個例子,事實上是說明,字符串中所有的方法看上去返回一個修改後的字符串,實際上返回的是一個新的字符串。對於數字和布爾值就更加明顯了--改變數字的值本身就說不通。
        
    2、原始類型的比較,只有它們的值相等的時候它們才相等。對於字符串來說就不太好理解。
        JavaScript規定字符串,當前僅當它們的長度相等及每個索引的字符都相等時,JavaScript才認爲他們相等。而引用類型的比較:當且僅當它們引用同一個對象時,它們才相等。那麼,即使兩個對象包含同樣的屬性及相同的值,它們也不一定是相等的。
 

var a = {x:1};
var b = {x:1};
alert("比較1:" + (a === b)); // 結果返回false
			
var a = [];
var b = [];
alert("比較2:" + (a === b)); // 結果返回false
			
var a = [];
var b = a;
var c = b;
alert("比較3:" + (a === b)); // 結果返回true

2 JavaScript類型轉換機制

    瞭解了JavaScript的值的類型之後,我們再來看JavaScript類型轉換機制。JavaScript會根據需要自行轉換類型。這一點我們從以下示例就可以看出。

var str = "30";
str = str * 10;    // 因爲執行乘法運算,乘法的兩邊都應該是數字類型,JavaScript會根據需要將str轉換爲數字類型
alert(str);    // 結果返回300

var str2 = 30;
str2 = str2 + "10";    // 因爲執行+運算,因爲+的一遍包含字符串"10",因此我們可以將+看出連接符,JavaScript會根據需要將str轉換爲字符串
alert(str2);    // 結果返回3010


            
2.1 JavaScript各類型之間的轉換對應表 

根據《JavaScript權威指南》,以下表格說明了各類型之間的轉換。空單元格表示不必要也沒有執行轉換。

轉換爲
  字符串 數字 布爾值 對象
undefined "undefined" NaN false throws TypeError
null "null" 0 false throws TypeError
true "true" 1   new Boolean(true)
false "false" 0   new Boolean(false)
""(空字符串)   0 false new String("")
"1.2"(非空,數字)   1.2 true new String("1.2")
"one"(非空,非數字)   NaN true new String("one")
         
0 "0"   false new Number(0)
-0 "0"   false new Number(-0)
NaN "NaN"   false new Number(NaN)
Infinity "Infinity"   true new Number(Infinity)
-Infinity "-Infinity"   true new Number(-Infinity)
1(無窮大,非0) "1"   true new Number(1)
         
{}(任意對象) 具體見下文 具體見下文 true  
[](任意數組) "" 0 true  
[9](一個數字元素的數組) "9" 9 true  
['a'](其他數組) 使用join()方法 NaN true  
function(){}(任意函數) 具體見下文 NaN true  


    說明:
            (1)原始值到對象的轉換非常簡單。原始值通調用String(),Number(),或Boolean()構造函數,轉換成爲它們各自的包裝對象。
            (2)null和undefined屬於例外,當它們用在期望是一個對象的地方時,都會造成一個類型錯誤(TypeError)異常,而不會執行正常的轉換
            (3)對象到原始值的轉換比較複雜。具體請看後續分析。

2.2 顯示類型轉換

    通過調用Boolean()、Number()、String()或Object()函數顯示的將數據轉換爲期望的類型的方法。

Number("1") ==> 1
 String("true") ==> "true"
Boolean([]) ==> true
Object("3") ==> new Number("3") 

     需要注意的是:如果試圖將null或undefined轉換成爲對象,則會報類型錯誤(TypeError)具體如上表所示。 如果是Object()函數,則會返回一個新創建的空對象

2.3 隱式類型轉換

     JavaScript中的某些運算符會做隱式轉換, 例如var x = "30";  +x; ==> 等價於 x-0。像這種通過JavaScript中的某些運算符達到數據類型轉換目的的方法稱之爲隱式轉換。

x + ""; 	// 等價於String(x);
+x;			// 等價於Number(x);或 x - 0;
!!x;		// 等價於Boolean(x);需要注意的是雙感嘆號

2.4 對象轉換爲字符串

    1、 如果對象具有toString()方法,則調用這個方法,如果它的返回值是一個原始值,JavaScript將這個值轉換爲字符串(如果其本身不是字符串),並返回這個字符串結果。詳細的轉換對比上表。

    (1)數組轉換爲字符串

    數組轉換爲字符串時,調用toString()方法,該方法將數組轉換成一個字符串,並在元素間添加逗號後結合成結果字符串,例如:["1","2","3"].toString(); // ==> 1,2,3

var a = ["1","2","3"];
var b = "1,2,3";
alert(a == b);

    (2)函數類轉化爲字符串

     函數類轉換爲字符串時,通常toString()方法實際返回的是這個函數的實現定義表現方式。Eg:(function(x){f(x);}).toString; ==> // function(x){f(x);}

var a = "function(x){f(x);}";
var b = function(x){f(x);};
var c = function(x){
    f(x);
};
console.log("a == b:" + (a == b));
console.log("a == c:" + (a == c));
console.log(c.toString());


        

    2 、 如果對象沒有toString()方法,或者這個方法不返回一個原始值,那麼JavaScript會調用valueOf()方法。如果這個方法存在JavaScript則會調用它。如果返回值是原始值,JavaScript會將這個值轉換爲字符串(如果其本身不是字符串的話),並返回這個字符串結果。

var obj = {
    name:"",
    age:12,
    valueOf:function(){
        return "this is valueOf()"
    }
};
alert("查看調用的方法:" + obj);

    備註:根據《JavaScript權威指南》說明,理論上應該先調用toString(),如果沒有則調用valueOf()方法,而事實上則先調用valueOf()方法,然這一點我很費解。知道原因的朋友,麻煩留言一下。具體如下:

var obj = {
	name:"",
	age:12,
	toString:function(){
		return "this is toString()"
	},
	valueOf:function(){
		return "this is valueOf()"
	}
	
};
alert("查看調用的方法:" + obj);

 

    3、否則, 無法從toString()或valueOf()獲得一個原始值。因此這時將拋出一個類型錯誤異常。

var obj = {
	name:"",
	age:12,
	toString:function(){
		return new Object();
	},
	valueOf:function(){
		return new Object();
	}
	
};
alert("查看調用的方法:" + obj);

2.5 對象轉換爲數字

對象轉換爲數字的過程與到字符串類似,只是它會首先嚐試使用valueOf()方法。

   1、如果對象具有valueOf()方法,則調用這個方法,如果它的返回值是一個原始值,JavaScript將這個值轉換爲數字(如果其本身不是數字),並返回這個數字。詳細的轉換對比上表。

    2 、 如果對象沒有valueOf()方法,或者這個方法不返回一個原始值,那麼JavaScript會調用toString()方法。如果這個方法存在JavaScript則會調用它。如果返回值是原始值,JavaScript會將這個值轉換爲數字(如果其本身不是數字的話),並返回這個數字。

    3、否則, 無法從toString()或valueOf()獲得一個原始值。因此這時將拋出一個類型錯誤異常。

 

3 “==”與“===”

在講述各類型比較之前,我們先了解一下“==”(相等運算符)與“===”(恆等運算符)

3.1 “===”

嚴格相等運算符“===”,也稱做恆等運算符,它用來檢測兩個操作數是否嚴格相等。

恆等運算符“===”,首先比較兩個操作數數據類型是否相同,然後比較這兩個值,比較過程中沒有任何類型轉換:

(1) 如果兩個值類型不同,則它們不同。

(2)如果兩個值都是null或者都是undefined,則他們相等。

(3)如果兩個值都是布爾值true或者都是false,則他們相等。

(4)如果其中一個值是NaN,或者兩個值都是NaN,則他們不相等。NaN和其他任何值都不相等,包含它本身。通過x!==x判斷x是否爲NaN,只有當x爲NaN時,這個表達式才爲true。

(5)如果兩個值都爲數字且數值相等,則它們相等。如果一個值是0,另一個值是-0,它們同樣相等。

(6)如果兩個值爲字符串,且所含對應爲上的16位 數完全相等,則他們相等。如果他們的長度或內容不同,則它們不相等。兩個字符串可能完全意義上一樣且顯示出的字符也一樣,但是具有不同編碼的16位值,則他們不等。

(7)如果兩個引用值指向同一個對象、數組、函數,則他們相等。如果指向不同的對象,則他們不等,儘管兩個對象具有完全一樣的屬性。

3.2  “==”

相等運算符“==”,用來檢測兩個操作數是否相等,不同意恆等運算符“===”的是,相等運算符“==”,只比較兩個操作數的值是否相等,如果兩個操作數的數據類型不同,那麼相等運算符“==”會嘗試做做隱式類型轉換,然後進行比較。

(1)如果兩個數據類型相同,則和恆等運算符所述規則一樣。如果嚴格相等,那麼比較結果相等,如果不嚴格相等,則比較結果爲不相等。

(2)如果兩個操作數的數據類型不同,相等運算符“==”也可能認爲他們相等。檢查相等會遵循如下規則和類型轉換:

    ①如果一個值是null,另一個是undefined,則他們相等。

    ②如果一個值是數字,另一個值是字符串,則先將字符串轉換爲數字,然後使用轉換後的值進行比較

    ③如果其中一個值是true,則將其轉換成1再進行比較。如果其中一個值是false,則將其轉換成0再進行比較。

    ④如果一個值是對象,另一個值是數字或字符串,則現將對象轉換成原始值(轉換規則如上述),然後進行比較。

    ⑤其他不同類型之間的比較不相等。

3.3 總結

    恆等運算符“===”

        數據類型相同時:

             原始值直接比較值,值相等則他們相等,需要注意的是String類型必須具有相同編碼的16位值。

             引用類型,需要注意是否指向同一個對象、數組、函數。Eg: var a = [1,2,3];var b = [1,2,3]; a === b; 結果爲false。

var a = [1,2,3];
var b = [1,2,3];
alert("a === b:" + (a === b));

 

 

    數據類型不同時:直接返回false;

 

相等運算符“==”

     數據類型相同時,比較結果與恆等運算符比較結果相同。

     數據類型不同時

         (1)null與undefined除與自己相等外,他們彼此也相等,即 null == undefined,結果返回爲true。

         (2)如果都是原始值,會將其他類型轉換爲數字,然後進行比較。

         (3)如果其中一個類型是對象,則將對象轉換爲原始值,然後在進行比較。

 

....未完

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章