【问题标题】:Why is (new Date() == new Date()) false, but (Date() == Date()) is true? [duplicate]为什么 (new Date() == new Date()) 为假,但 (Date() == Date()) 为真? [复制]
【发布时间】:2017-06-18 05:21:51
【问题描述】:

我一直在用 JSFiddle 来解决 FreeCodeCamp 中的this 问题。当我使用 Date 作为字符串时(即没有“新”):

案例一:

function isSameDay (dtFrom, dtTo) {
    return dtFrom == dtTo
  }

  let today = Date()
  let tomorrow = Date()

  console.log(today)
  console.log(tomorrow)
  console.log(isSameDay(today, tomorrow))

isSameDay 返回 true。但是,当我使用 Date 作为构造函数时(使用“new”):

案例 2:

function isSameDay (dtFrom, dtTo) {
    return dtFrom == dtTo
  }

  let today = new Date()
  let tomorrow = new Date()

  console.log(today)
  console.log(tomorrow)

  console.log(isSameDay(today, tomorrow))

isSameDay 返回 false。但是(!),当我添加一元运算符“+”时:

案例 3:

function isSameDay (dtFrom, dtTo) {
    return dtFrom == dtTo
  }

  let today = + new Date()
  let tomorrow = + new Date()

  console.log(today)
  console.log(tomorrow)

  console.log(isSameDay(today, tomorrow))

isSameDay 返回 true。我理解案例 1 和案例 3 返回 true,因为它们只是相同的字符串和相同的毫秒值。

为什么案例 2 返回 false

【问题讨论】:

  • 同一个构造函数的两个实例仍然彼此不同,即使它们具有完全相同的属性,因为它们是不同的对象。如果要比较日期,请将它们转换为毫秒并计算该整数。此外,sicne new Date() 返回当前时间戳,两次 new Date() 调用之间可能存在毫秒差异。
  • 因为甚至没有({}) == ({}) ...但Date()返回一个字符串,所以它会==大部分时间...除非秒计时
  • cast them to miliseconds ... 但时不时地 new Date().getTime() == new Date().getTime() 是错误的 ... 因为在两次调用 new Date() 之间可能有一毫秒的时间间隔 ... @987654329 不太可能@ - 因为它是一个分辨率为 1 秒的字符串......但仍然很少是错误的
  • 您除以准确度,或者减去并计算它们之间的时间,具体取决于您是在比较小时、分钟还是秒或其他什么。与使用 Date 方法或生成的字符串相比,转换为毫秒的关键在于能够使用“简单”的数学运算而不用担心本地化。
  • 感谢您的回复,我不知道 ({}) != ({})。如果这是一个重复的问题,我们深表歉意。

标签: javascript date equality


【解决方案1】:

使用Date(),JavaScript Date 对象只能通过调用 JavaScript Date 作为构造函数来实例化:将其作为常规函数调用(即没有 new 运算符)将返回一个字符串,而不是一个日期对象。 MDN Reference.

typeof Date()    //"string"
Date() == Date() //true

使用构造函数作为new Date(),每个实例都是唯一的(同一个构造函数的两个实例仍然彼此不同),这就是它们在比较时不相等的原因。

typeof new Date();        //"object"
new Date() === new Date() //false

【讨论】:

  • 当然每个实例都是唯一的,但你不能用同样的论点说 var a = 'a';变量 b = 'a'; a == b;应该评估为假?毕竟它们是不同的实例。还有为什么像 等所有其他比较都应该与日期对象一起使用,但是 == 是一个不起作用的例外。似乎旨在混淆视听。
  • @tobuslieven 很抱歉,但 var a = 'a'; var b = 'b'; a === b 等于 false。
  • @tobuslieven 这是抽象相等比较算法中的设计。请参阅下面的答案
【解决方案2】:

简单地说,案例 2 返回 false,因为 您正在比较两个不同的对象引用(即使两个对象都包含 完全相同相同的属性)。

而在其他情况下,您正在比较日期的 toString() 值。

==Abstract Equality Algorithm请参见官方文档中的注3

注意 3

等式运算符并不总是可传递的。例如, 可能有两个不同的 String 对象,每个对象代表相同的 字符串值。

每个 String 对象都将被视为等于 == 运算符的字符串值,但两个 String 对象不会 彼此相等。例如:

new String("a") == "a" //true

"a" == new String("a") //true 

但是

new String("a") == new String("a") //false.

【讨论】:

  • 当其他比较 等似乎根据各自的日期正常工作时,为什么相等只关心对象引用?
  • 这是== 运算符的一个特性。与>, < 等不同,平等不是通过价值而是通过引用来实现的
  • 哇,这很有趣。不得不说这似乎是一个糟糕的选择。知道为什么他们决定应该存在这个例外吗?我没有看到好处。
  • 确实很有趣。感谢您的回复!
猜你喜欢
  • 2014-11-26
  • 2021-04-09
  • 2016-07-03
  • 2018-08-26
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多