gpt4 book ai didi

javascript - 日期对象与原始值等于存储的时间值的比较返回 false

转载 作者:行者123 更新时间:2023-12-04 07:14:25 25 4
gpt4 key购买 nike

如果使用 == 比较基元与对象,则比较使用对象的 valueOf 函数,该函数在大多数情况下返回一个基元 bool、字符串或数字。
如果您想将对象与以下对象进行比较,这会很有用:if (customObject == "unique-object-id")这类似于字符串实例比较的工作原理以及原因 new String("foo") == "foo"结果为真,但 new String("foo") == new String("foo")结果为假。
示例

class Person {
constructor(name) { this.name = name }
valueOf() { return this.name }
}
new Person("John Doe") == "John Doe"; // -> true
正则表达式:
// object with primitive string comparision
new RegExp() == new RegExp().toString(); // -> true
奇怪的是,如何比较 Date 对象:
// object with primitive comparision fails here
let now = Date.now(),
// using the number Date.now() returns to
// generate a date object with an value
date = new Date(now);
date == now; // -> false

// it is larger or equal and smaller or equal
// at the sime time, this only means it is equal...

date >= now && // -> true
date <= now && // -> true
!(date > now) && // -> !false -> true
!(date < now) // -> !false -> true
; // -> true

// forced comparision works as expected and converting the
// object to its representing valueOf using number conversion
+date == now; // -> true
Number(date) == now; // -> true
new Number(date) == now; // -> true
date.valueOf() == now; // -> true
但这按预期工作......
const now = Date.now();
new Date() == now; // -> false
// wait for 1ms, no need for async...
while(now == Date.now()); // bad practice but helps on the example
new Date() > now; // -> true
结果如预期,如果我使用 Date 对象并将其与更小或更大的数字进行比较。如果用于比较的数字等于 Date 对象中存储的时间值,则相等比较始终返回 false。 Date.now()规范说明或 Date.prototype.valueOf()没有解释这种行为, the Section about the equality operator 也没有解释帮助。
The section about "What a time value is"将其描述如下:

An ECMAScript time value is a Number, either a finite integer representing an instant in time to millisecond precision or NaN representing no specific instant.


如果值相等,为什么对具有基元的 Date 对象进行相等比较会失败?

最佳答案

这在 isLooselyEqual 中有描述规范的部分。

x == y

  1. If Type(x) is Object and Type(y) is either String, Number, BigInt, or Symbol, return IsLooselyEqual(? ToPrimitive(x), y).

ToPrimitive has :
2. If Type(input) is Object, then
a. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
b. If exoticToPrim is not undefined, then
i. If preferredType is not present, let hint be "default".
...
iv. Let result be ? Call(exoticToPrim, input, « hint »).
看看当 toPrimitive 时会发生什么在日期对象上调用 'default'暗示:

const date = new Date();
console.log(date[Symbol.toPrimitive]('default'));

它给出的不是数字,而是字符串,类似于以下格式:
Sat Aug 21 2021 09:05:47 GMT-0500 (Central Daylight Time)
因此,最初的比较
let now = Date.now(),
date = new Date(now);
date == now; // -> false
失败,因为当 date由于 == 被转换为字符串, 你得到:
let now = Date.now(),
date = new Date(now);
someFormattedDateString == now; // -> false
someFormattedDateString == now显然失败了,因为 now是一个数字,而不是(甚至松散地)等于格式化日期字符串的东西。
相比之下,当你做
+date == now; // -> true
Number(date) == now; // -> true
new Number(date) == now; // -> true
date.valueOf() == now; // -> true
这些都产生 true因为您将日期转换为数字,绕过了 [Symbol.toPrimitive]('default') (结果产生一个字符串) - 数字结果确实成功地与另一个数字进行了比较。
  • 一元+Number将值强制为数字。
  • new Number将值强制转换为 Number 对象,当与具有 == 的数字原语进行比较时, 获取从 Number 对象中提取的原始值,并导致比较成功。
  • Date.prototype.valueOf从日期 as the specification says 中提取数值:

    1. Return ? thisTimeValue(this value).


    console.log((new Date()).valueOf());

    关于javascript - 日期对象与原始值等于存储的时间值的比较返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68873627/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com