眾所周知Javascript作為一種動態類型,弱類型的指令碼語言其資料類型在很多時候都會發生類型轉換。而這些類型轉換往往都是隱式的,這讓我們在使用Js的時候會產生許多麻煩。而Js的基礎資料類型的轉換在此文中不過多闡述,主要記錄Js對象資料類型的轉換。筆者由於比較菜,若有寫的不對的地方歡迎大佬在下方留言指正。
1.Number強制轉換對象
let a={name:123};console.log(Number(a));
我們先簡單的聲明一個對象,並用Number()對其進行強制類型轉換
運行結果如下:
那麼我們來分析一下對象經過強制類型轉換為什麼會變成NaN?
在這裡就不得不提到Js對象所帶有的兩個方法,valueOf以及toString。
我們先說一下valueOf這個方法:
JavaScript調用valueOf方法將對象轉換為原始值。你很少需要自己調用valueOf方法;當遇到要預期的原始值的對象時,JavaScript會自動調用它。
預設情況下,valueOf方法由Object後面的每個對象繼承。 每個內建的核心對象都會覆蓋此方法以返回適當的值。如果對象沒有原始值,則valueOf將返回對象本身。
JavaScript的許多內建對象都重寫了該函數,以實現更適合自身的功能需要。因此,不同類型對象的valueOf()方法的傳回值和傳回值類型均可能不同。
以上描述源自MDN對valueOf方法的描述,下方給出不同資料類型valueof的傳回值:
注意以上傳回值是在你沒有覆蓋原有valueof的函數的情況下的傳回值。
在上表中我們可以清楚的看到,對象返回的值是對象本身,結果如下:
接下來我們再說一下toString方法
一個對象在沒有覆蓋toString方法的情況下傳回值應該為:
那麼這兩種方式和對象的強制類型轉換有什麼關係呢?
實際上當Number()強制類型轉換Object對象時會進行如下操作:
1.先調用對象的valueOf方法
2.判斷該方法的傳回值是否為基礎資料類型(Number,String,Boolean,Undefined,Null)
3.若傳回值為基礎資料類型,則轉換規則按照相應資料類型的轉換規則對其進行轉換
4.若傳回值不為基礎資料類型,則在該傳回值的基礎上繼續調用toString方法
5.判斷toString的傳回值是否為基礎資料類型
6.判斷是否為基礎資料類型,若是基礎資料類型則進行操作3
7.若仍舊不為基礎資料類型則報錯
下面我們對這些步驟進行驗證:
這樣看起來似乎解釋的通,那麼我們看看如果toString的傳回值依舊是個對象看一下瀏覽器是否會報錯吧:
果然當toString傳回值仍舊為對象時Js報錯了
那麼我們在驗證一下如果第一次調用valueof的傳回值就是基礎資料類型會發生什嗎?
所以Number強制轉換對象的過程即為如上7步
2.String強制轉換對象
首先依舊先聲明一個簡單的對象
為了與上面的區分這次我們建立一個對象b{name:b}
從我們可以看到強制轉換的結果為"[object object]"
同樣的下面是解密時間:
事實上String強制轉換對象的步驟與Number類似,也分為類似的7個步驟:
1.先調用對象的toString方法
2.判斷該方法的傳回值是否為基礎資料類型(Number,String,Boolean,Undefined,Null)
3.若傳回值為基礎資料類型,則轉換規則按照相應資料類型的轉換規則對其進行轉換
4.若傳回值不為基礎資料類型,則在該傳回值的基礎上繼續調用valueOf方法
5.判斷valueOf的傳回值是否為基礎資料類型
6.判斷是否為基礎資料類型,若是基礎資料類型則進行操作3
7.若仍舊不為基礎資料類型則報錯
String與Number的區別則在於
Number是先調用valueOf再調用toString
而String是先調用toString再調用valueof
為了方便下面會以一張圖對此進行說明:
所以這就是String轉換對象的原理
3.Boolean強制轉換對象
我們知道在Js中用於能在判斷時為false的只有5個值
1.undefined
2.null
3.‘’//Null 字元串
4.0
5.NaN
其他值在判斷時都為true,而if判斷時是使用了Boolean進行轉換的
所以對象經過Boolean轉換的值為true
——————————————————————————————————————————————————————————————————
所以一些有趣的面試題的答案也就有瞭解釋:
{}+{}
{}+[]
[]+[]
[]+{}