JS強制型別轉換和隱式型別轉換

2020-07-16 10:05:29
JavaScript 是一種動態型別的語言,在執行運算操作的過程中,有時需要轉換運算元的型別。在 JavaScript 中,資料型別的轉換有:隱式型別轉換和強制型別轉換(也叫顯式型別轉換)兩種方式。

1.隱式型別轉換

隱式型別轉換會自動根據運算子進行型別轉換。隱式型別轉換的情況主要有以下幾種。

1) 如果表示式中同時存在字串型別和數位型別的運算元,而運算子使用加號+,此時 JavaScript 會自動將數位轉換成字串。例如:
alert("姑娘今年" + 18);   //結果:姑娘今年18
alert("15"+5);   //結果:155

2) 如果表示式運算子為-、*、/、%中的任意一個,此時 JavaScript 會自動將字串轉換成數位,對無法轉換為數位的則轉換為 NaN。例如:
alert("30"/5);   //除運算,結果為:6
alert("15"-5);   //減運算,結果為:10
alert("20"*"a"); //乘運算,結果為:NaN
alert("20"%"3"); //取模運算,結果為:2

3) 運算子為++--時,JavaScript 會自動將字串轉換成數位,對無法轉換為數位的則轉換為 NaN。例如:
var num1 = "6";
var num2 = "6";
var num3 = "a";
alert(++num1);  //將字串轉換為數位再進行++運算,結果為:7
alert(--num2);  //將字串轉換為數位再進行--運算,結果為:5
alert(++num3);  //字串無法轉換為數位,結果為:NaN

4) 運算子為><時,當兩個運算元一個為字串,一個為數位時,JavaScript 會自動將字串轉換成數位。例如:
alert('10'>9);  //將字串轉換為數位,按值進行比較,結果為:true
alert('10'<9);  //將字串轉換為數位,按值進行比較,結果為:false

5) !運算子將其運算元轉換為布林值並取反。例如:
alert(!0);    //對0取反,結果為:true
alert(!100); //對非0數位取反,結果為:false
alert(!"ok"); //對非空字串取反,結果為:false
alert(!"");  //對空字串取反,結果為:true

6) 運算子為==時,當表示式同時包含字串和數位時,JavaScript 會自動將字串轉換成數位。例如:
var a = '2';
var b = 2;
alert(a == b); //按值比較,結果為:true

2.強制型別轉換

從上面的介紹我們可以看到,JavaScript 可以自動根據運算的需要進行型別的轉換。強制型別轉換主要針對功能的需要或為了使程式碼變得清晰易讀,人為地進行型別的轉換。在 JavaScript 中,強制型別轉換主要是通過呼叫全域性函數 Number()、parseInt() 和 parseFloat() 來實現。

1) 使用Number()函數將引數轉換為一個數位

使用格式如下:

Number(value)

Number() 對引數 value 進行整體轉換,當引數值中任何地方包含了無法轉換為數位的符號時,轉換失敗,此時將返回 NaN,否則返回轉換後的數位。

Number() 對引數進行數位轉換時,遵循以下一些規則:
  • 如果引數中只包含數位時,將轉換為十進位制數位,忽略前導 0 以及前導空格;如果數位前面為--會保留在轉換結果中;如果數位前面為+,轉換後將刪掉+號;
  • 如果引數中包含有效浮點數位,將轉換為對應的浮點數位,忽略前導 0 以及前導空格;如果數位前面為--會保留在轉換結果中;如果數位前面為+,轉換後將刪掉+號;
  • 如果引數中包含有效的十六進位制數位,將轉換為對應大小的十進位制數位;
  • 如果引數為空字串,將轉換為 0;
  • 如果引數為布林值,則將 true 轉換為 1,將 false 轉換為 0;
  • 如果引數為 null,將轉換為 0;
  • 如果引數為 undefined,將轉換為 NaN;
  • 如果引數為 Date 物件,將轉換為從 1970 年 1 月 1 日到執行轉換時的毫秒數;
  • 如果引數為函數、包含兩個元素以上的陣列物件以及除 Date 物件以外的其他物件,將轉換為 NaN;
  • 如果在引數前麵包含了除空格、+-以外的其他特殊符號或非數位字元,或在引數中間包含了包括空格、+-的特殊符號或非數位字元,將轉換為 NaN。

轉換範例:
alert(Number("0010"));  //去掉兩個前導0,結果為:10
alert(Number("+010"));  //去掉前導0和+,結果為:10
alert(Number("-10"));  //轉換後保留“-”號,結果為:-10
alert(Number(''));      //空字串的轉換結果為:0
alert(Number(true));   //布林值true的轉換結果為:1
alert(Number(null));   //null值的轉換結果為:0
var d = new Date();      //建立一個Date物件
alert(Number(d));     //轉換Date物件,結果為1970.1.1至執行轉換時的毫秒數:1511351635179
alert(Number("100px"));   //引數中包含了不能轉換為數位的字元px,結果為:NaN
alert(Number("100 01"));  //引數中包含了空格,導致整個引數不能轉換,結果為:NaN
alert(Number("100-123")); //引數中包含了“-”,導致整個引數不能轉換,結果為:NaN
var a;                   //宣告變數
alert(Number(a));     //變數a沒有賦值,因而a的值為undefined,轉換undefined的結果為:NaN
var fn = function (){alert(1);}; //建立一個函數物件
alert(Number(fn));     //轉換函數,結果為:NaN
alert(Number(window)); //轉換window物件,結果為:NaN
從上述範例中,我們也可以看到,Number() 是從整體上進行轉換的,任何一個地方含有非法字元,都將導致轉換無法成功。接下來將介紹的兩個函數與 Number() 不同的是,轉換是從左到右逐位進行轉換,任何一位無法轉換時立即停止轉換,同時返回已成功轉換的值。

2) 使用parseInt()函數將引數轉換為一個整數

使用格式如下:

parseInt(stringNum,[radix])

stringNum 引數為需要轉換為整數的字串;radix 引數為 2~36 之間的數位,表示 stringNum 引數的進位制數,取值為 10 時可省略。

parseInt() 的作用是將以 radix 為基數的 stringNum 字串引數解析成十進位制數。若 stringNum 字串不是以合法的字元開頭,則返回 NaN;解析過程中如果遇到不合法的字元,將馬上停止解析,並返回已經解析的值。

parseInt() 在解析字串為整數時,遵循以下規則:
  • 解析字串時,會忽略字串前後的空格;如果字串前面為--會保留在轉換結果中;如果數位前面為+,轉換後將刪掉+號;
  • 如果字串前面為除空格、+-以外的特殊符號或除 a~f(或 A~F)之外的非數位字元,字串將不會被解析,返回結果為 NaN;
  • 在字串中包含了空格、+-和小數點“。”等特殊符號或非數位的字元時,解析將在遇到這些字元時停止,並返回已解析的結果;
  • 如果字串是空字串,返回結果為 NaN。

轉換範例:
alert(parseInt("1101",2));  //以2為基數的1101字串解析後的結果為:13
alert(parseInt("a37f",16)); //以16為基數的a37f字串解析後的結果為:41855
alert(parseInt("123"));     //以10為基數的123字串解析後的結果為:123
alert(parseInt("  123"));   //字串前面的空格會被忽略,結果為:123
alert(parseInt("12 3"));    //字串中包含了空格,解析到空格時停止,結果為12
alert(parseInt("12.345")); //字串中包含了小數點,解析到小數點時停止,結果為12
alert(parseInt("xy123"));  //字串前面包含了非數位字元“x”,無法解析,返回結果為:NaN
alert(parseInt("123xy4")); //字串中包含了非數位字元“xy”,解析到“x”時停止,結果為:123
從上述範例我們可以看到,parseInt() 解析浮點數時,小數部分資料會被截掉,此時需要使用下面將介紹的 parseFloat(),而不能使用 parseInt()。

3) 使用parseFloat()函數將引數轉換為一個浮點數

使用格式如下:

parseFloat(stringNum)

stringNum 引數為需要解析為浮點型的字串。

parseFloat() 的作用是將首位為數位的字串轉解析成浮點型數。若 stringNum 字串不是以合法的字元開頭,則返回 NaN;解析過程中如果遇到不合法的字元,將馬上停止解析,並返回已經解析的值。

parseFloat() 在解析字串為整數時,遵循以下規則:
  • 解析字串時,會忽略字串前後的空格;如果字串前面為--會保留在轉換結果中;如果數位前面為+,轉換後將刪掉+號;如果字串前面為小數點 . 轉換結果會在小數點前面新增 0;
  • 如果字串前面為除空格、+-以外的特殊符號,字串將不會被解析,返回結果為 NaN;
  • 在字串中包含了空格、+-等特殊符號或非數位的字元時,解析將在遇到這些字元時停止,並返回已解析的結果;
  • 在字串中包含兩個以上為小數點時,解析到第二個小數點時將停止解析,並返回已解析的結果;
  • 如果字串是空字串,返回結果為 NaN。

轉換範例:
alert(parseFloat("312.456"));//結果為:312.456
alert(parseFloat("-3.12"));//字串前面的“-”將保留,結果為:-3.12
alert(parseFloat("+3.12"));//字串前面的“-”將保留,結果為:3.12
alert(parseFloat(".12"));//在小數點前面新增0,結果為:0.12
alert(parseFloat("  3.12"));//截掉字串前面的空格,結果為:3.12
alert(parseFloat("312.4A56"));//字串中包含非數位字元A,解析到A時停止,結果為:312.4
alert(parseFloat("31 2.4A56"));//字串中包含空格,解析到空格時停止,結果為:31
alert(parseFloat("31.2.5"));//字串中包含兩個小數點,解析到第二個小數點時停止,結果為:31.2
alert(parseFloat("a312.456"));//字串前面為非數位字元a,解析無法進行,結果為:NaN