1. 程式人生 > >JS顯性資料型別轉換和隱性資料型別轉換

JS顯性資料型別轉換和隱性資料型別轉換

一、JS需要型別轉換的原因

JS是一種弱型別語言,變數沒有型別限制,可以隨意賦值。如:

var a=5;
console.log(typeof a);//number
a='我是字串';
console.log(typeof a);//string
如上所示,當把數字5賦值給a變數時,a變數的型別是number,當把字串“我是字串”賦值給變數a時,a變數的型別是string。

雖然變數沒有型別限制,但運算子要求進行運算的變數的型別和運算子期望的型別一致,所以,當不同型別的變數進行加減運算時,就會進行型別轉換(如,1+'a'、'3'-'1')。型別轉換主要分為兩種:強制(顯性)型別轉換和自動(隱性)型別轉換

。每種轉換又可分為原始型別轉換和物件型別轉換,原始型別主要包括數字、字串、布林值、null、undefined等。



二、強制(顯性)型別轉換

強制型別轉換主要是指通過String、Number和Boolean等構造方法手動轉換成對應的字串、數字和布林值。

2.1、將其他型別轉為字串

字串是JS的基本資料型別之一,使用String物件的構造方法可以將任意型別的資料轉換為字串,其中,這裡的任意型別主要分為兩大類:原始(基本)型別和物件型別。基本型別的轉換相對簡單,轉換方法如下:

基本資料型別 String型別
數字 對應的數字字串
true 字串true
false 字串false
null 字串null
undefined 字串undefined
如下,均輸出對應的字串值:
console.log(String(123));//"123"
console.log(String(true));//"true"
console.log(String(false));//"false"
console.log(String(null));//"null"
console.log(String(undefined));//"undefined"

物件型別的轉換稍微複雜些,物件參與基本型別資料運算時,首先是要將物件轉換為基本型別。轉換方法如下:

1、呼叫toString()方法,如果返回基本型別的值,則用String()構造方法轉換該值。

2、如果toString()方法返回的不是基本型別,則再呼叫valueOf()方法,如果返回基本型別的值,則用String()構造方法轉換該值。

3、如果valueOf()方法返回的也不是基本型別,就丟擲錯誤,如谷歌丟擲:Uncaught TypeError: Cannot convert object to primitive value

如下,為了方便檢視,重寫了String的toString()和valueOf()方法:

例1、當String物件的toString()方法返回基本型別時

//重寫Date物件的toString()
Date.prototype.toString=function(){
console.log('執行了toString(),這裡返回數字1');
return 1;
};
//重寫Date物件的valueOf()方法
Date.prototype.valueOf=function(){
console.log('執行了valueOf()方法,這裡返回數字2');
return 2;
};
var date=new Date();
var str=String(date);
輸出結果:
執行了toString(),這裡返回數字1

列2、當toString()方法返回非基本型別時,再次呼叫valueOf()方法
//重寫Date物件的toString()
Date.prototype.toString=function(){
console.log('執行了toString(),這裡返回數字1');
return {};
};
//重寫Date物件的valueOf()方法
Date.prototype.valueOf=function(){
console.log('執行了valueOf()方法,這裡返回數字2');
return 2;
};
var date=new Date();
var str=String(date);//先呼叫toString()方法,由於返回的不是基本資料型別,再次呼叫valueOf()方法
輸出結果:
執行了toString(),這裡返回數字1
執行了valueOf()方法,這裡返回數字2

例3、toString()和valueOf()都返回的不是基本資料型別,則丟擲異常
//重寫Date物件的toString()
Date.prototype.toString=function(){
console.log('執行了toString(),這裡返回數字1');
return {};
};
//重寫Date物件的valueOf()方法
Date.prototype.valueOf=function(){
console.log('執行了valueOf()方法,這裡返回數字2');
return {};
};
var date=new Date();
var str=String(date);//先呼叫toString()方法,由於返回的不是基本資料型別,再次呼叫valueOf()方法,但還是返回非基本資料型別,所以丟擲異常
輸出結果:
執行了toString(),這裡返回數字1
執行了valueOf()方法,這裡返回數字2
Uncaught TypeError: Cannot convert object to primitive value

也可以採用如下方式驗證:

var obj={
	valueOf:function(){
		console.log('執行了valueOf()方法,這裡返回數字2');
		return 2;
	},
	toString:function(){
		console.log('執行了toString(),這裡返回物件');
		return 1;
	}
};
String(obj);

2.2、將其他型別轉換成數字

使用Number建構函式轉化任意型別的值時,也分為兩種:一種是將基本型別的值轉換成數字,一種是將物件型的值轉換為數字。基本型別的資料轉換數字的規則如下:

基本資料型別 數字型別
數字字串 對應的數字
true 1
false 0
null 0
undefined NaN
空字串 0
不可完全被解析為數值的字串 NaN

如下:

console.log(Number(123));//123
console.log(Number('123'));//123
console.log(Number('123a'));//NaN
console.log(Number(''));//0
console.log(Number(true));//1
console.log(Number(false));//0
console.log(Number(undefined));//NaN
console.log(Number(null));//0
console.log(Number(' \t\n 3.23322\t '));//Number可以自動去掉兩頭空白符,輸出3.23322
注:Number建構函式將字串轉換為數字時,字串必須完全被為數字,即只要有一個字元無法轉為數值,則整個字串都會被轉為NaN。如果想不精確轉換,可以使用parseInt()函式,parseInt()函式將最大限度的將字串轉換為數字。如:
console.log(parseInt('123abc456'));//123
console.log(Number('123abc456'));//NaN

物件型別轉換為數字,和上面物件轉換為字串類似,只是轉為數字時是先呼叫valueOf()方法,再呼叫tostring()方法:

1、首先呼叫物件自身的valueOf()方法,如果返回基本型別的值,則用Number建構函式進行轉換。

2、如果valueOf()返回的不是基本型別的值,則再呼叫toString()方法,如果返回基本型別的值,值用Number建構函式進行轉換。

3、如果toString()返回的不是基本型別的值,則丟擲異常。

驗證方法與上面轉為字串的類似,如:

 var obj={
	valueOf:function(){
		console.log('執行了valueOf()方法,這裡返回數字2');
		return 2;
	},
	toString:function(){
		console.log('執行了toString(),這裡返回物件');
		return 1;
	}
};
Number(obj); 
輸出結果:
執行了valueOf()方法,這裡返回數字2

2.3、將其他型別轉換為布林值

使用Boolean建構函式轉換其他型別的數值時,除了下面幾種情況返回false外,其他的值都返回true。

1、null

2、0、-0或者+0

3、NaN

4、''  空字串

5、undefined

如:

console.log(Boolean(null));//false
console.log(Boolean(0));//false
console.log(Boolean(-0));//false
console.log(Boolean(+0));//false
console.log(Boolean(''));//false
console.log(Boolean(NaN));//false
console.log(Boolean(undefined));//false
console.log(Boolean({}));//true
console.log(Boolean([]));//true
console.log(Boolean("蟈蟈"));//true
console.log(Boolean(new Boolean(false)));//true

三、自動(隱性)型別轉換

自動型別轉換就是不需要人為強制的進行轉換,js會自動將型別轉換為需要的型別,所以該轉換操作使用者是感覺不到的,因此又稱為隱性型別轉換。自動型別轉換實際上和強制型別轉換一樣,也是通過String()、Number()、Boolean()等建構函式進行轉換,只是該操作是JS自己自動完成的而已。自動型別轉換的規則和強制型別轉換的規則一致,所以這裡不再進行描述。下面列舉幾個例子:

3.1、轉換為數字

在所有加減乘除等需要數字型別的地方,JS會自動使用Number建構函式對變數進行轉換。

console.log('1'-'2');//-1
console.log(1+'2');//12 加號+比較特殊,其他型別和字串相加都會轉換成字串
console.log('1'-true);//0
console.log('1'*{});//NaN
console.log('1'-'a');//NaN

3.2、轉換為字串

字串自動轉換主要表現為字串的拼接,字串和其他型別用加號(+)拼接時,其他型別都自動轉換為字串。
console.log('1'+'2');//12
console.log('1'+'a');//1a
console.log('1'+1);//11
console.log('a'+null);//anull
console.log('1'+undefined);//1undefined
console.log('a'+{});//a[object Object]
console.log('a'+true);//atrue

3.3、轉換為布林值

當在任意需要布林型別的地方(如,if條件出、三元運算子條件等),系統都會自動呼叫Boolean()建構函式將值轉換為Boolean型別。null、0、-0、+0、'' 空字串、undefined、NaN這些都會轉換為false,其他的值都會轉換為true。