【问题标题】:Equality comparison between Date and number doesn't work日期和数字之间的相等比较不起作用
【发布时间】:2015-09-19 03:35:18
【问题描述】:

根据 ECMA 脚本标准,以下代码应该返回 true,但事实并非如此:

d = new Date() ;
d.setTime(1436497200000) ;
alert( d == 1436497200000 ) ;

11.9.3 部分说:

  1. 如果 Type(x) 是 String 或 Number 且 Type(y) 是 Object,则返回比较结果 x == ToPrimitive(y)。

然后,8.12.8 部分说ToPrimitive 返回valueOf 方法的结果。这意味着我上面示例中的最后一行应该相当于:

alert( d.valueOf() == 1436497200000 );

确实返回true

为什么第一种情况不返回true

【问题讨论】:

  • 第一个将对象与数字作为字符串进行比较。您可以使用alert( +d == 1436497200000) 强制进行数值比较。
  • 你引用的那段是关于 x 的类型,它是 left hand 操作数。在您的情况下,这不是字符串或数字。
  • @brso05:那个“文章”官方 EcmaScript标准的手动转换。
  • @dandavis,好的,但是为什么它不像规范所说的那样工作?还是我看错了?
  • "当 O 的 [[DefaultValue]] 内部方法在没有提示的情况下被调用时,它的行为就像提示是数字一样,除非 O 是一个 Date 对象 (见 15.9.6),在这种情况下,它的行为就像提示是字符串一样。” - 所以当我尝试alert(d == "Fri Jul 10 2015 13:00:00 GMT+1000 (AUS Eastern Standard Time)") 时,它会返回true

标签: javascript comparison date-comparison value-of type-coercion


【解决方案1】:

如果您查看 8.12.8 部分的规范,您会在该部分的末尾附近找到此文本:

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

(强调我的)

现在,在抽象等式比较算法 [11.9.3]的步骤8/9中,调用ToPrimitive(x)ToPrimitive(y)没有hint 参数。

缺少这个hint参数,连同上面的文字,意味着ToPrimitive方法返回toString()值,在日期对象上。

您可能已经知道,(new Date()).toString() 以美式英语返回日期的字符串表示形式[source]
"Wed Jul 01 2015 22:08:41 GMT+0200 (W. Europe Daylight Time)"

这样的字符串不等于1436497200000 不应该是一个大惊喜。 ;-)

【讨论】:

  • 所以toPrimitive 在这种情况下没有给出任何提示,即使它与一个数字进行了比较。
  • 是的,正如您在 11.9.3ToPrimitive(x)ToPrimitive(y) 部分的步骤 8 / 9 中看到的那样,在没有 hint 参数的情况下调用。 (与11.8.5 部分中的调用方式相反)
【解决方案2】:

ToPrimitive(A) 尝试将其对象参数转换为原始值,方法是尝试在 A 上调用不同的 A.toString 和 A.valueOf 方法序列。

所以如果toString()调用成功,它就不会调用valueOf()

【讨论】:

    猜你喜欢
    • 2020-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多