今天发现一个神奇的现象,效果如下:
Date转换
date
是一个对象,但是把这个对象和一个字符串相加的时候,却能得到日期字符串;把这个对象和数字相减,却能得到时间戳(毫秒数);也就是date
与字符串、数字进行运算时,会转成对应的类型。
其实造成以上现象的本质原因是:js
为了让两种不同类型的值进行运算或比较,会在运算前对他们进行转换,其实就是通过调用他们的toString()
或者是valueOf()
来得到转换后的值,然后再对转换后的值进行运算或者比较。
我们可以看一下,常用的几种数据类型的valueOf()
的返回值是什么。
1.数组
数组数组的
valueOf
返回的是一个对象,也是原对象本身。
2.Date
日期对象
Date
的valueOf
的返回值是时间的毫秒数。
3.Number
number对象
Number
的valueOf
返回的是对应的number
类型的值。
4.Boolean
布尔对象
Boolean
的valueOf
返回的是一个boolean
类型的值。
5.Object
Object
Object
的valueOf
返回的是一个Object
对象。也是原对象本身。
6.Function
Function
Function
的valueOf
返回的是一个Function
对象。也是原对象本身。
总结如下:
- 包装类型的
valueOf()
会返回对应的基本类型的值;比如:Number
; -
Date
对象的valueOf()
返回对应的时间戳,也就是数字; - 其他类型的
valueOf()
,返回的是对象本身;
但是我们也可以通过自定义valueOf
方法来覆盖默认的行为,如下:
调用toString在未自定义
调用valueOfvalueOf
之前,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()
返回的是非基本类型的值,则会报如下错误:
错误提示
网友评论