今天發現一個神奇的現象,效果如下:
date
是一個對象,但是把這個對象和一個字符串相加的時候,卻能得到日期字符串;把這個對象和數字相減,卻能得到時間戳(毫秒數);也就是date
與字符串、數字進行運算時,會轉成對應的類型。
其實造成以上現象的本質原因是:js
爲了讓兩種不同類型的值進行運算或比較,會在運算前對他們進行轉換,其實就是通過調用他們的toString()
或者是valueOf()
來得到轉換後的值,然後再對轉換後的值進行運算或者比較。
我們可以看一下,常用的幾種數據類型的valueOf()
的返回值是什麼。
1.數組
數組的
valueOf
返回的是一個對象,也是原對象本身。
2.Date
Date
的valueOf
的返回值是時間的毫秒數。
3.Number
Number
的valueOf
返回的是對應的number
類型的值。
4.Boolean
Boolean
的valueOf
返回的是一個boolean
類型的值。
5.Object
Object
的valueOf
返回的是一個Object
對象。也是原對象本身。
6.Function
Function
的valueOf
返回的是一個Function
對象。也是原對象本身。
總結如下:
- 包裝類型的
valueOf()
會返回對應的基本類型的值;比如:Number
; -
Date
對象的valueOf()
返回對應的時間戳,也就是數字; - 其他類型的
valueOf()
,返回的是對象本身;
但是我們也可以通過自定義valueOf
方法來覆蓋默認的行爲,如下:
在未自定義
valueOf
之前,obj+"--name"
。返回的是[object object]--name
,自定義以後,obj+"--name"
返回'gby--name',這證明了,我們成功覆蓋了原來的valueOf()
。
此時想到之前有遇到過,js 會在某些時候調用toString()
方法,那什麼時候調用valueOf()
,什麼時候調用toString()
,我們可以測試一下:
當valueOf()
和toString()
同時存在時,會優先調用valueOf()
;那如果valueOf
返回一個非基本類型時,會是什麼結果,測試如下:
當自定義
valueOf
返回一個非基本類型 的數據時,會先調用valueOf()
,之後再調toString()
。
如果valueOf()
和toString
都返回對象,則會報錯:
總結
js
爲了讓兩種不同類型的值進行運算或比較,會在運算前對他們進行轉換,其實就是通過調用他們的toString()
或者是valueOf()
來得到轉換後的值,然後再對轉換後的值進行運算或者比較。
valueOf()
和toString()
具體的調用機制如下:
- 調用
valueOf()
獲得返回值,如果該返回值是基本類型,則會把該返回值作爲最終值,並參與運算; - 如果上一步中
vulueOf()
返回的是非基本類型的值,則會進一步調用toString()
方法,獲得toString()
的返回值,如果該返回值是基本類型,則會把該返回值作爲最終值,並參與運算; - 如果上一步中
toString()
返回的是非基本類型的值,則會報如下錯誤: