根據我的理解,如果一個對象具有valueOf
函數,它將在需要將對象轉換爲原語時使用。如果一個對象具有toString
函數,那麼當對象需要轉換爲字符串時將使用它。因此,當您使用+
時,應首先使用valueOf
(如果存在),然後使用toString
。爲什麼Date會像其他算術運算符一樣使用+和相似數字來處理字符串?
這就是它似乎做的:
var obj1 = {
valueOf:() => 0
};
var obj2 = {
toString:() => 'a'
};
var obj3 = {
valueOf:() => 0,
toString:() => 'a'
};
obj1 + obj1; // -> 0
obj2 + obj2; // -> 'aa'
obj3 + obj3; // -> 0
現在日期正在實施兩個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)"
'valueOf' /'toString'首選項僅適用於標準對象,不幸的是日期是一個異常。當然,這對於'+'更令人困惑,它不知道它是否應該將它的參數轉換爲數字或字符串。 – Bergi
行爲可追溯到[* ToPrimitive *](http://ecma-international.org/ecma-262/8.0/#sec-toprimitive),默認提示是除日期和符號以外的所有內置函數的編號。主機對象也可能使用不同的提示。這將是限制性的,如果提示總是數字,字符串是有意義的日期,因爲你可能想寫'今天是'+新日期()'。 – RobG
從用戶的角度來看,字符串和數字都是有意義的。你也可以想'new Date()+ 1000'。但是對於數字來說應該有什麼保證是與其他算術運算符的一致性。這就是爲什麼我發現它贏得那場戰鬥的奇怪。 – Ghetolay