2

什么 Javascript 语言规则导致以下转换怪异?

new Date() - 2 => number
new Date() * 2 => number
new Date() / 2 => number

new Date() + 2 => string

我原以为 + 运算符会使用对象的valueOf()方法Date将其转换为数字。就像下面的例子:

{valueOf: function() {return 1;}} + 2 => number

a 的情况有什么不同Date

4

3 回答 3

3

当你尝试做

new Date() + 2  

你正在做一个字符串连接(所以new Date()是返回一个Date对象的字符串表示等效于(new Date()).toString()),

在其他情况下,您使用算术运算符(在这种情况下new Date(),从“Epoch”返回毫秒)

要有一个“一致的”行为,只需使用一个类型强制,+(new Date())这样

+(new Date()) - 2 => number
+(new Date()) * 2 => number
+(new Date()) / 2 => number
+(new Date()) + 2 => number
于 2012-09-26T10:31:55.550 回答
1

这并不矛盾:只需尝试上面代码中隐式调用d = new Date(); console.log(d);toString方法,默认返回一个字符串。由于 JS 是松散类型的,并且+是一个重载的运算符(连接字符串并进行算术运算),因此 date 对象和 int (2) 都被强制:

我猜这背后的逻辑是这样的:如果两个操作数都不是直接兼容的,那么两者都被强制为第三种类型:有点像"Meeting each other half-way"。默认情况下,日期会转换为字符串,数字也可以这样做,因此 JS 假定这是您想要的(这是最符合逻辑的解释)。
其他示例使用不同的操作数,没有解释的余地​​,因此使用日期对象的数值

不过,这很容易解决:

+(new Date()) + 2;//+ coerces new Date() to int

这里有更多信息

于 2012-09-26T10:35:35.877 回答
0

在研究了 Javascript 规范之后,在加法运算符的上下文中,确实存在 Date 对象的特殊情况:

http://ecma-international.org/ecma-262/5.1/#sec-11.6.1

Date 对象的转换处理方式与其他对象不同:

在第 5 步和第 6 步中对 ToPrimitive 的调用中没有提供任何提示。除 Date 对象外,所有本机 ECMAScript 对象都处理没有提示的情况,就好像给出了提示 Number 一样;日期对象处理提示的缺失,就像给出了提示字符串一样。

我想我理解动机,但作为语言规则,这感觉很丑陋。

于 2012-09-26T13:03:04.347 回答