Date object会按照您的意愿行事 - 为每个日期构建一个,然后使用
>
,<
,<=
或>=
进行比较。
我没有在引用页面上看到此功能。
>
,<
,{{1实现了Date对象的{}或<=
运算符?它的意思是,它是在>=
上定义的,它是否因为某些隐式转换被定义(例如从一个对象到一个数字或一个字符串)而发生,是否是添加到Javascript语言解释器的Date对象的特例/运行时,还是什么?答案 0 :(得分:2)
每当您想要一个Object为Number时,就会调用 valueOf 方法:
{valueOf:()=>2}.valueOf() //2
//or not explicitly called:
+{valueOf:()=>2} //2
//using the compare operator:
{valueOf:()=>2}<{valueOf:()=>3}//true as 2<3
因此,当您比较日期时,这也会发生。由于 Date.prototype.valueOf 方法返回自1970年以来的毫秒数,您可以使用它来比较两个日期......
new Date().valueOf();
//or
+new Date();
//or
new Date()<new Date();
答案 1 :(得分:2)
这是特定于浏览器的行为,还是语言的标准功能?
这是标准功能。
<块引用>如果 Date
是一个 javascript“对象”,并且 javascript 不支持运算符重载,那么 >
、<
、<=
或>=
运算符对 Date
对象实施了吗?
因为 Date
实现 valueOf
和 Symbol.toPrimitive
的方式(toString
是相关的,但与您提到的特定运算符无关)。这三个方法在规范中通过OrdinaryToPrimitive抽象操作将对象隐式转换为原始值的过程中使用,运算符在需要原始值(如字符串或数字)时使用它,但它们接收一个对象。
特别是,Date
通过返回其基础时间值(格林威治标准时间 1970 年 1 月 1 日午夜以来的毫秒数)来实现 valueOf
。所以 date1 >= date2
在每个日期上调用 valueOf
,暗示首选数字,它从日期中获取时间值(一个数字),然后比较它们。更多内容如下。
此问题的副本:
<块引用>我们可以为任何班级做吗?
是的,从 ES2015 开始,这一切都是标准的,Date
不再像以前那样特殊(它的特殊方式相对较小,更多内容见下文)。例如:
class MyThing {
constructor(value) {
this.value = value;
}
valueOf() {
return this.value;
}
toString() {
return String(this.value);
}
}
const a = new MyThing(27);
const b = new MyThing(42);
console.log(`a < b? ${a < b}`); // a < b? true
console.log(`b < a? ${b < a}`); // b < a? false
console.log(`b - a = ${b - a}`); // b - a = 15
console.log(`a + b = ${a + b}`); // a + b = 69
(上面遗漏了 Date
的一些东西,稍后会更多。)
当操作符或类似操作需要将对象转换为原始类型时,它会使用对象的“转换为原始类型”操作,可选择提供有关其偏好的“提示”(字符串、数字或无偏好)。关系运算符更喜欢数字,所有纯数学运算符(如 -
)也是如此。 +
运算符,既是加法又是字符串连接,不提供提示,因此使用对象的默认值。如果没有提示,几乎内置对象默认为数字; Date
和 Symbol
默认为字符串。这曾经只是内置到规范操作的逻辑中(对于 Date
; Symbol
当时不存在),但现在通过 Symbol.toPrimitive
方法处理,它是一个对象可以覆盖以提供其自己的转换为基元的处理。
如果我们希望 MyThing
默认为字符串而不是像 Date
那样的数字,我们会添加 Symbol.toPrimitive
方法(我还添加了 console.log
valueOf
和 toString
显示哪个用于操作):
class MyThing {
constructor(value) {
this.value = value;
}
valueOf() {
console.log("valueOf");
return this.value;
}
toString() {
console.log("toString");
return String(this.value);
}
[Symbol.toPrimitive](hint) {
if (hint === "number") {
return this.valueOf();
}
// "default" or "number"
return this.toString();
}
}
const a = new MyThing(27);
const b = new MyThing(42);
console.log(`a < b? ${a < b}`); // a < b? true
console.log(`b < a? ${b < a}`); // b < a? false
console.log(`b - a = ${b - a}`); // b - a = 15
console.log(`a + b = ${a + b}`); // a + a = "2742"
请注意 a + b
现在是如何进行字符串连接的,在第一个代码段中它进行的是加法。那是因为我们更改了默认行为,将字符串优先于数字。