JavaScript Object 上的 valueOf() 方法,是不是看上去很冷门的样子?貌似都不怎么用的。但是,真的没有用到吗?
可能从命名上,你可以了解到它可以返回当前对象的原始值(primitive value)。Number, Date, Boolean 对象会返回其原始值。比如:
new Number(10).valueOf() === 10 // true
作为 Object prototype 上的方法,它够低调的了。低调到用了都不知道。因为实际上,你几乎用不着去调用它,在需要的时候,会被自动调用。比如,进行比较操作,看下面的代码。
var obj = { v: 10, valueOf: function() { return this.v++; } }; if (obj > 9) { // yes, compare obj with number 9 alert(obj.valueOf()); // 11 }
拿对象与数字进行比较,结果竟然是 true,如果去掉 valueOf 的定义,什么事情都不会发生。
了解到这个之后,再看上面第一个代码,就会觉得有点画蛇添足了呢?
new Number(10) === 10 // false new Number(10) > 9 // true
但是是不行的。在 === 的情况下,valueOf 是不会被隐含调用的。那么,现在来看下面这样的代码就很好理解了。是隐含调用 valueOf 在作怪 😛
var now = new Date(); alert( now < new Date(now.getTime() + 30) ); // true
在了解了 valueOf 低调的作风之后,心里有底了,也许有派得上用场的地方,不过,就算派上场了,也看不见。
好的,最后留一个奇怪的问题让大家伤伤脑筋吧
var now = new Date(); alert( now == new Date(now.getTime()) ); // false alert( now.valueOf() == new Date(now.getTime()) ); // ?
后一个结果,现象是 chrome,safari 里面是 true, firefox,opera 和 IE 里都是 false。究竟是为什么呢?
PS: 在网络上可以搜索到的 valueOf 的中文文档,都是说对于Array来说,“数组的元素被转换为字符串,这些字符串由逗号分隔,连接在一起。其操作与 Array.toString 和 Array.join 方法相同。”,估计这是对于 JScript 的吧。如这里所说,所有浏览器测试下来都是返回数组对象本身。