javascript - 为什么我可以用 Date 对象做数学运算?
问题描述
当我像这样减去两个日期对象时:
const startTime = new Date();
await someAsyncStuff();
const endTime = new Date();
const elapsedTime = endTime - startTime;
console.log(`The async stuff took ${elapsedTime} ms`);
为什么 Date 对象最终被转换为毫秒,然后减去?我知道他们这样做,但我无法弄清楚导致这种情况的实际事件顺序是什么。
解决方案
一般来说,JavaScript 对象可以定义方法来将对象转换为字符串或数字(您可以通过定义toString
和valueOf
方法来自定义)。JavaScript 将在数值上下文(如2 * a
)或字符串上下文(如'' + a
)中使用这些方法将对象转换为适当的原语。
在不确定是使用数字还是字符串转换(如a + b
)的上下文中,存在默认行为,具体取决于对象的类型。有趣Date
的是,在默认的 ECMAScript 对象中被挑选出来以转换为字符串,而不是数字。通过规范:
日期对象在 ECMAScript 内置对象中是唯一的,因为它们将“
default
”视为等同于“string
”,所有其他内置 ECMAScript 对象将“default
”视为等同于“number
”。
在Date
对象的特定情况下,数值转换(valueOf
方法)将时间转换为纪元毫秒,而字符串转换(toString
方法)将对象转换为人类可读的字符串。正如@baao 在他的回答中提到的那样,由于类型的自动转换,这可能会在对对象进行“算术”时导致一些问题。
总之,Date
(与大多数其他对象不同)默认为字符串转换,但由于减法需要两个数字才能有意义,因此它将日期转换为数字。
明确定义行为通常是一个好主意,在这种情况下使用valueOf
,getTime
或toString
使代码不那么模棱两可。
有关 JavaScript 是否选择使用toString
vs的更多信息valueOf
,请参阅此问题、加法(和减法)的总体规范以及日期的具体规范(mdn 链接),以及@baao 的答案以获得更深入的了解。
也可以看看:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/valueOf
推荐阅读
- c# - 如何在 C# 中执行以下代码行而不需要在 cmd 提示符下按回车?
- python - 无法使用 pytesseract 从 .jpg 图像中提取全文,仅提取了部分文本,存在拼写错误
- cpanel - cPanel 备份在进行中过多,然后超时
- reactjs - 在 React 上将 props 从一个组件传递到另一个组件
- java - 仅在 Chrome 浏览器中基于页面上的少量操作重置多级下拉导航栏
- javascript - JavaScript 正则表达式 - 替换所有匹配项?
- java - 如何使用 Java (openjdk 11) 专门锁定 Windows 10 中的文件?
- snakemake - 使用 snakemake 移动集群作业的元数据存储
- bash - 搜索字符串的列,如果找到/没有将另一个字符串添加到单独的列
- sql - 通过 CASE 条件控制 ASC / DESC 排序