開始之前,先來回顧一下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.關(guān)系運算符:會把其他數(shù)據(jù)類型轉(zhuǎn)換成number之后再比較關(guān)系
'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)換與關(guān)系運算符隱式轉(zhuǎn)換搞混淆
[]==0 //true [].valueof()=[] => [].toString()='' =>Number('')=0
![]==0 //true 本質(zhì)是![]邏輯非與0比較;邏輯非優(yōu)先級高于關(guān)系運算符 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
{}=={} //地址不同