为什么在JavaScript中可以将一个日期对象减去另一个日期对象?

3
请看下面的代码:

考虑以下代码:

var a = new Date(someDateString);
var b = new Date(someOtherDateString);

console.log(b - a); // Outputs for example 3572, number of millisecs between the dates

为什么这个代码能工作?因为它是对两个对象进行算术运算。它看起来很像C++和其他语言中的操作符重载,但据我所知,在ECMAScript 7之前,JavaScript不支持。

人们会认为JS引擎会将其转换为类似以下内容:

console.log(b.toString() - a.toString());

但是这会打印出 "NaN",因为在日期对象上调用toString方法返回的是一个格式化后的字符串。
Mon Mar 23 2015 13:21:33 GMT+0100 (CET)

那么,是什么魔力使得这种算法成为可能?它能在自定义对象上实现吗?

尝试实现并查看结果。JS引擎知道类型,并且JS充满了语法糖和自动转换 - 这没有任何不同。 - Dave Newton
ticks,日期通过一个数字来表示,基于一个起始点(1/1/1970?),当将两个日期相减时,隐式地相减了它们之间的 ticks,留下了两个日期之间的差异... - Icepickle
Date 的 valueOf 方法返回一个数字。当执行减法时,Date 对象会被转换为数字。 - ermouth
阅读 ECMAScript 5.1 规范,你就能得到答案。 - Mr. X
'2015-02-10' - '2014-10-12' 的结果会是什么样子? - RobG
3个回答

4
它们是通过 .valueOf() 而非 .toString() 进行转换的。在内部,日期被存储为一个数字。 toString() 方法仅使用日期格式化程序对其进行格式化。
请参见规范中的 减法运算符

1

valueOf 被调用以获取日期的数值原始数据:

function o(i) {
    this.valueOf = function() { return i; }
}

var a = new o(100);
var b = new o(42);

alert(a - b); // 58

0

JS的日期对象只是“毫秒数”。

“零时刻”始于1970年1月1日00:00:00 UTC。其他所有时间都可以简单地进行转换,加减操作也变得非常容易!


2
这是一个对象,不是一个数字。请不要过于简化。 - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接