開始之前幅骄,先來回顧一下valueOf()的返回值
顯示轉(zhuǎn)換
顯式類型轉(zhuǎn)換主要是指通過String拆座、Number、Boolean等構(gòu)造方法轉(zhuǎn)換相應的字符串孕索、數(shù)字躏碳、布爾值
1.轉(zhuǎn)換成字符串
對象類型,先將對象類型轉(zhuǎn)換成基本類型
- 調(diào)用toString()方法镇眷,如果返回基本類型翎嫡,就調(diào)用String()構(gòu)造方法轉(zhuǎn)換該值
- 如果toString()方法返回的不是基本類型,則再調(diào)用valueOf()方法翁垂,如果返回基本類型的值硝桩,則用String()構(gòu)造方法轉(zhuǎn)換該值碗脊。
- 如果valueOf()方法返回的也不是基本類型橄妆,就拋出錯誤
2.轉(zhuǎn)換成數(shù)值
注意:
- 字符串轉(zhuǎn)換成基本類型害碾,是精確轉(zhuǎn)換
- console.log(Number(' \t\n 3.23322\t '));//Number可以自動去掉兩頭空白符,輸出3.23322
對象類型轉(zhuǎn)換為數(shù)字芬沉,和上面對象轉(zhuǎn)換為字符串類似阁猜,只是轉(zhuǎn)為數(shù)字時是先調(diào)用valueOf()方法,再調(diào)用tostring()方法:
- 首先調(diào)用對象自身的valueOf()方法黄刚,如果返回基本類型的值民效,則用Number構(gòu)造函數(shù)進行轉(zhuǎn)換。
- 如果valueOf()返回的不是基本類型的值业扒,則再調(diào)用toString()方法舒萎,如果返回基本類型的值,值用Number構(gòu)造函數(shù)進行轉(zhuǎn)換虱肄。
3.轉(zhuǎn)換成布爾值
除了一下幾種情況返回false,其他都返回true
null,0,-0,+0,NaN,undefined,空字符串
隱式轉(zhuǎn)換
自動類型轉(zhuǎn)換就是不需要人為強制的進行轉(zhuǎn)換斟或,js會自動將類型轉(zhuǎn)換為需要的類型萝挤,所以該轉(zhuǎn)換操作用戶是感覺不到的根欧,因此又稱為隱性類型轉(zhuǎn)換。自動類型轉(zhuǎn)換實際上和強制類型轉(zhuǎn)換一樣酥泛,也是通過String()嫌拣、Number()、Boolean()等構(gòu)造函數(shù)進行轉(zhuǎn)換异逐,只是該操作是JS自己自動完成的而已灰瞻。
坑點:
1.字符串連接符與算術(shù)運算符隱式轉(zhuǎn)換規(guī)則混淆
當一邊是字符串是,加號就是字符串連接符院崇,會將其他數(shù)據(jù)類型調(diào)用String()轉(zhuǎn)換成字符串然后拼接
1+'true'//1true String(1)+'true'='1true'
1+true //2 1+Number(true)=1+1=2
1+undefined //NaN 1+Number(undefined)=1+NaN=NaN
1+null //1 1+Number(null)=1+0=1
2.關系運算符:會把其他數(shù)據(jù)類型轉(zhuǎn)換成number之后再比較關系
'2'>10 //false 當有一邊是字符串時袍祖,會將它使用Number()轉(zhuǎn)換,再比較 Number('2')>10=2>10 false
'2'>'10'//true 當兩邊都是字符串時捐凭,同時轉(zhuǎn)換成number然后比較凳鬓,字符挨個進行unicode編碼的比較 '2'.charCodeAt()>'10'.charCodeAt()=50>49
'abc'>'b' //false 同理上面
NaN==NaN //false
undefined==null //true
3.復雜類型在進行隱式轉(zhuǎn)換時,會先轉(zhuǎn)成String垦梆,再轉(zhuǎn)換成Number類型進行比較
[1,2]=='1,2' //true [1,2].valueOf()=>[1,2] [1,2].toString()=>'1,2'
Var a=?
if(a==1&&a==2&&a==3){
console.log(1);
}
如何完善a,使其正確打印1
解答:
復雜數(shù)據(jù)類型會先調(diào)用valueOf()方法,然后轉(zhuǎn)換成number運算,可以重寫對象的valueOf()方法
var a={
i:1,
valueOf:function(){
return a.i++
}
}
4.邏輯非隱式轉(zhuǎn)換與關系運算符隱式轉(zhuǎn)換搞混淆
[]==0 //true [].valueof()=[] => [].toString()='' =>Number('')=0
![]==0 //true 本質(zhì)是![]邏輯非與0比較印蓖;邏輯非優(yōu)先級高于關系運算符 Boolean([])=1 => !1=0
[]==![] //true 本質(zhì)是空數(shù)組[]與![]這個邏輯非表達式結(jié)果進行比較 [].valueOf().toString()='' ![]=false Number('')==Number(false)
[]==[] //false 引用類型存儲在最終赦肃,棧中存儲的是地址公浪,地址不同
{}==!{} //false 本質(zhì)是對象{}與!{}的邏輯表達式結(jié)果進行比較 {}.valueOf().toString()='[object Object]' !{}=false Number('[object Object]')==Number('false') 結(jié)果是false
{}=={} //地址不同