今天偶然发现了这一点,我无法找到规范中定义此行为的位置。
在JavaScript中将字符串附加到对象(即new Object() + "whatever"
)通常会触发对该对象的valueOf()
的调用,但显然,Date对象是此规则的例外:new Date() + "..."
而是在日期上调用toString()
。
function test(constructor)
{
var name = constructor.name || /^\s*function ([\w\$]+)/.exec(constructor.toString())[1];
var obj = new constructor();
obj.toString = function () { return name + ' : toString()'; }
obj.valueOf = function () { return name + ' : valueOf()'; }
document.body.appendChild(document.createElement('DIV')).textContent = obj + '';
}
test(Array);
test(Boolean);
test(Date);
test(Function);
test(Number);
test(Object);
test(RegExp);
test(String);

问题:这里的Date对象有什么不同?
答案 0 :(得分:4)
当您在对象上调用addition operator并且对象已转换为to a primitive时,将调用该对象的内部[[DefaultValue]]
method。该方法采用类型提示来确定是首先评估toString
还是valueOf
。
如果提示是“字符串”,则在toString
之前查找valueOf
。如果传递“数字”,则反之亦然。
然而(强调我的):
中也提到了这一点如果在没有提示的情况下调用 O 的
[[DefaultValue]]
内部方法,则其行为就像提示是数字,除非 O 是一个Date对象(参见15.9.6),在这种情况下,它的行为就好像提示是字符串。
注1:在步骤5和6中对
ToPrimitive
的调用中没有提供提示。除Date对象之外的所有本机ECMAScript对象都处理没有提示,就像提供了提示号一样;日期对象处理缺少提示,就像提供了提示字符串一样。主机对象可以通过其他方式处理缺少提示。