Javascript 为什么日期被视为带+;和其他算术运算符的数字一样?
根据我的理解,如果一个对象具有Javascript 为什么日期被视为带+;和其他算术运算符的数字一样?,javascript,date,Javascript,Date,根据我的理解,如果一个对象具有valueOf函数,那么当需要将该对象转换为原语时,将使用该函数。如果对象具有toString函数,则在需要将对象转换为字符串时将使用该函数。因此,当您使用+时,应首先使用valueOf(如果存在),然后使用toString 这似乎就是它从以下方面所做的: var obj1 = { valueOf: () => 0 }; var obj2 = { toString: () => 'a' }; var obj3 = { valueOf:
valueOf
函数,那么当需要将该对象转换为原语时,将使用该函数。如果对象具有toString
函数,则在需要将对象转换为字符串时将使用该函数。因此,当您使用+
时,应首先使用valueOf
(如果存在),然后使用toString
这似乎就是它从以下方面所做的:
var obj1 = {
valueOf: () => 0
};
var obj2 = {
toString: () => 'a'
};
var obj3 = {
valueOf: () => 0,
toString: () => 'a'
};
obj1 + obj1; // -> 0
obj2 + obj2; // -> 'aa'
obj3 + obj3; // -> 0
现在Date同时实现了valueOf
和toString
等obj3
,但是当您执行Date+Date
时,您会得到一个字符串使用任何其他算术运算符都会将日期视为一个数字进行运算并返回一个有效数字 下面是一些代码来说明我的困惑:
var date = new Date(2017,1,1);
date - date; // -> 0
date * date: // -> 2.20790950849296e+24
date / date; // -> 1
date % date; // -> 0
date + date; // -> "Wed Feb 01 2017 00:00:00 GMT+0100 (CET)Wed Feb 01 2017 00:00:00 GMT+0100 (CET)"
如果第一个操作数是字符串,则
+
运算符将在JS中充当串联器。由于date
生成一个字符串,因此在本例中它将充当串联器。如果第一个操作数是字符串,则+
运算符将充当JS中的串联器。由于date
生成一个字符串,因此在这种情况下它将充当串联器。这是因为date
有一个异域@@toPrimitive
更喜欢字符串而不是数字。看
日期对象在内置ECMAScript对象中是唯一的,因为它们
将“default”视为等同于“string”,所有其他内置
ECMAScript对象将“default”视为等同于“number”
这是因为
Date
有一个奇异的@@toPrimitive
,它更喜欢字符串而不是数字。看
日期对象在内置ECMAScript对象中是唯一的,因为它们
将“default”视为等同于“string”,所有其他内置
ECMAScript对象将“default”视为等同于“number”
借助于符号。toPrimitive属性(用作函数值),可以将对象转换为基本值 使用字符串参数hint调用函数,该参数指定结果原语值的首选类型。提示参数可以是“number”、“string”和“default”中的一个 日期对象的语法:
Date()[Symbol.toPrimitive](提示)代码>
如果提示为“字符串”或“默认值”,则。@@TopPrimitive将尝试调用toString方法。如果toString属性不存在,它将尝试调用valueOf方法,如果valueOf也不存在,则。@@TopPrimitive将抛出一个TypeError
如果提示是“number”,则。@@toPrimitive首先尝试调用valueOf,如果失败,则调用toString
var日期=新日期(2017,1,1);
console.log('提示为“数字”:,+date++date);//使用一元加号运算符
console.log('提示为“默认值”:',日期+日期);//无提示(落在提示=='string')
log('提示为“字符串”:',`${date+date}`);//使用模板文字
可以借助符号将对象转换为基元值。toPrimitive属性(用作函数值)
使用字符串参数hint调用函数,该参数指定结果原语值的首选类型。提示参数可以是“number”、“string”和“default”中的一个
日期对象的语法:Date()[Symbol.toPrimitive](提示)代码>
如果提示为“字符串”或“默认值”,则。@@TopPrimitive将尝试调用toString方法。如果toString属性不存在,它将尝试调用valueOf方法,如果valueOf也不存在,则。@@TopPrimitive将抛出一个TypeError
如果提示是“number”,则。@@toPrimitive首先尝试调用valueOf,如果失败,则调用toString
var日期=新日期(2017,1,1);
console.log('提示为“数字”:,+date++date);//使用一元加号运算符
console.log('提示为“默认值”:',日期+日期);//无提示(落在提示=='string')
log('提示为“字符串”:',`${date+date}`);//使用模板文字
首选项的值
/toString
仅适用于标准对象,但遗憾的是日期是一个例外。当然,这与+
更为混淆,后者不知道是否应该将其参数转换为数字或字符串。该行为可追溯到,默认提示是除日期和符号之外的所有内置项的数字。宿主对象也可能使用不同的提示。如果提示始终是数字,并且字符串对于您可能要编写的日期是有意义的“今天是”+new Date()
。从用户的角度来看,字符串和数字都是有意义的。您还可以执行新建日期()+1000
。但这个数字应该证明的是它与其他算术运算符的一致性。这就是为什么我觉得字符串赢得这场战斗很奇怪的原因。valueOf
/toString
首选项仅适用于标准对象,不幸的是日期是个例外。当然,这与+
更为混淆,后者不知道是否应该将其参数转换为数字或字符串。该行为可追溯到,默认提示是除日期和符号之外的所有内置项的数字。宿主对象也可能使用不同的提示。如果提示始终是数字,并且字符串对于您可能要编写的日期是有意义的“今天是”+new Date()
。从用户的角度来看,字符串和数字都是有意义的。您还可以执行新建日期()+1000
。但这个数字应该证明的是它与其他算术运算符的一致性。这就是为什么我觉得奇怪的是字符串赢得了那场战斗。“因为日期产生了字符串”-但为什么呢date.valueOf()
产生一个数字。“因为日期产生一个字符串”-但为什么呢date.valueOf()
产生一个数字。问题是为什么会是defau