valueOf与toString方法研究2
我是出于一个“邪恶”的目的来研究它们的,因为目的过于邪恶,所以研究必须更为深入才能成功。但天机不可泄漏,大家跟着我享受过程即可。
我们先看两题:
-
var date = new Date(); var date_string = date.toString(); var date_value = date.valueOf(); alert(date == date_string); alert(date == date_value);
true, true
false, false
true, false
false, true
-
var now = new Date(2010,10,1); alert(now+1);
Mon Nov 1 00:00:00 UTC+0800 20101
1288540800001
[object Date]1
答案如下:
1:3,2:1
第一题非常难,如果不知道内部规则的话,那我们还是先看第二题吧,首先考察一下Date.toString方法,其返回值在不同还是有差异的。
- IE8:Mon Nov 1 00:00:00 UTC+0800 2010
- chrome5:Mon Nov 1 00:00:00 UTC+0800 2010(China Standard Time)
- safari5:Mon Nov 01 2010 00:00:00 GMT+0800 (Öйú±ê׼ʱ¼ä)
- opera 10.5:Mon Nov 01 2010 00:00:00 GMT+0800
- firefox 3.6:Mon Nov 01 2010 00:00:00 GMT+0800
接着我们再翻开ECMA262v5的11.6.1节,看有关对加号操作符的处理:
- 决定哪个是被加数
- 将被加数传入GetValue中进行运算
- 决定哪个是被加数
- 将加数传入GetValue中进行运算
- 将2的结果传入ToPrimitive中进行运算
- 将4的结果传入ToPrimitive中进行运算
- 如果5或6的结果随便一个为字符串,那么
- 将6直接置于5之后拼成新字符串返回
- 否则将它们都转换为数字(ToNumber)相加返回
这内部调用一个ToPrimitive方法,它定义在9.1节,基本上只对Object对象进行特殊处理
类型 | 结果 |
Undefined | 与输入时一致,无转换 |
Null | 与输入时一致,无转换 |
Boolean | 与输入时一致,无转换 |
Number | 与输入时一致,无转换 |
String | 与输入时一致,无转换 |
Object | Object 返回Object的默认值,它由内部一个名为[[DefaultValue]] 的方法决定的。 |
[[DefaultValue]] 会根据提示信息是调用valueOf方法或toString方法。此提示信息当然是前面提供的,我们再翻回11.6.1节,它解释道,除Date对象外,其他ECMA对象都应该转换为数字,Date则为字符串。看到这里,一切疑云应该清空吧。
在wtfjs中提到一道难题
[] == ![] //答案为true,注意非[] !== []
拥有了以上的知识,我们就轻而易举地解决它。
[] ==> [].valueOf() ==> ''; ![] ==> false '' == false ==> true!!
机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年