衆所周知Javascript做爲一種動態類型,弱類型的腳本語言其數據類型在不少時候都會發生類型轉換。而這些類型轉換每每都是隱式的,這讓咱們在使用Js的時候會產生許多麻煩。而Js的基礎數據類型的轉換在此文中不過多闡述,主要記錄Js對象數據類型的轉換。筆者因爲比較菜,如有寫的不對的地方歡迎大佬在下方留言指正。面試
let a={name:123}; console.log(Number(a));
咱們先簡單的聲明一個對象,並用Number()對其進行強制類型轉換瀏覽器
運行結果以下:函數
那麼咱們來分析一下對象通過強制類型轉換爲何會變成NaN?spa
在這裏就不得不提到Js對象所帶有的兩個方法,valueOf以及toString。3d
咱們先說一下valueOf這個方法:code
JavaScript調用valueOf
方法將對象轉換爲原始值。你不多須要本身調用valueOf
方法;當遇到要預期的原始值的對象時,JavaScript會自動調用它。對象
默認狀況下,valueOf
方法由Object
後面的每一個對象繼承。 每一個內置的核心對象都會覆蓋此方法以返回適當的值。若是對象沒有原始值,則valueOf
將返回對象自己。blog
JavaScript的許多內置對象都重寫了該函數,以實現更適合自身的功能須要。所以,不一樣類型對象的valueOf()方法的返回值和返回值類型都可能不一樣。繼承
以上描述源自MDN對valueOf方法的描述,下方給出不一樣數據類型valueof的返回值:ip
注意以上返回值是在你沒有覆蓋原有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步
首先依舊先聲明一個簡單的對象
爲了與上面的區分此次咱們建立一個對象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轉換對象的原理
咱們知道在Js中用於能在判斷時爲false的只有5個值
1.undefined
2.null
3.‘’//空字符串
4.0
5.NaN
其餘值在判斷時都爲true,而if判斷時是使用了Boolean進行轉換的
因此對象通過Boolean轉換的值爲true
——————————————————————————————————————————————————————————————————
因此一些有趣的面試題的答案也就有了解釋:
{}+{}
{}+[]
[]+[]
[]+{}