为什么将字符串附加到Date会调用toString()而不是valueOf()

Why does appending a string to a Date invoke toString() rather than valueOf()?

本文关键字:toString valueOf 调用 字符串 Date 为什么      更新时间:2023-09-26

我今天偶然发现了这一点,在规范中找不到这种行为的定义

在JavaScript中将字符串附加到对象(即new Object() + "whatever")通常会触发对对象上valueOf()的调用,但显然,Date对象是该规则的例外:new Date() + "..."在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对象有什么不同?

当您在对象上调用加法运算符,并且该对象被转换为基元时,会调用该对象的内部[[DefaultValue]]方法。该方法采用一个类型提示,该类型提示确定应该首先评估toString还是valueOf

如果提示是"字符串",则在valueOf之前查找toString。如果传递了"数字",则反之亦然。

然而(重点矿):

当在没有提示的情况下调用O[[DefaultValue]]内部方法时,它的行为就像提示是Number,,除非O是Date对象(请参见15.9.6),在这种情况下,它的操作就像提示是String

这也在添加操作员部分中注意到:

注1步骤5和6中对ToPrimitive的调用中未提供任何提示。除Date对象外的所有本机ECMAScript对象都处理没有提示的情况,就好像给出了提示编号一样;日期对象处理没有提示的情况,就好像给出了提示字符串一样。主机对象可以以某种其他方式处理没有提示的情况。