2016-03-15 74 views
5

我試圖理解這種行爲:爲什麼Date添加結果是字符串?

var d = new Date(); 

console.log(+d); // 1458049171381 
console.log(1 + d); // '1Tue Mar 15 2016 09:39:31 GMT-0400 (EDT)' 

與此相反:

var obj = { 
    valueOf: function() { 
    return 123; 
    } 
}; 

console.log(+obj); // 123 
console.log(1 + obj); // 124 

爲什麼Date相加結果以stringDate.prototype.valueOf返回number

這裏是Addition Operator's spec爲JavaScript的天真翻譯

function ToPrimitive(x) { 
    return x.valueOf(); 
} 

function IsString(x) { 
    return typeof x === 'string'; 
} 

function ToString(x) { 
    return x.toString(); 
} 

function ToNumber(x) { 
    try { 
    return parseFloat(x); 
    } catch (e) { 
    return NaN; 
    } 
} 

function AdditionOperator(lval, rval) { 

    let lprim = ToPrimitive(lval); 
    let rprim = ToPrimitive(rval); 

    if (IsString(lprim) || IsString(rprim)) { 
    return ToString(lprim) + ToString(rprim); 
    } else { 
    return ToNumber(lprim) + ToNumber(rprim); 
    } 
} 

但是,如果我調用這個有Date對象,它返回一個數值:

AdditionOperator(new Date(), 1) // 1458049347088 

有人可以闡明一些輕這個?

+0

你讀過注1嗎? – Hacketo

+0

@Hacketo/facepalm ...我會接受你的答案,如果你發佈一個。 –

+0

@iliacholy你我錯了,這是一種誤解。感謝這個例子。 –

回答

4

步指導:

  • 添加之前發生,無論是左和右值二進制運算的 被轉換爲基元(或stringnumber)。

  • 根據值的上下文,可能會提供一個'提示',表明它應該成爲哪種基本類型。

  • 如果未提供任何提示,它將默認爲其首選類型。所有Object都有number的首選類型,但Date,它傾向於string(並混淆了所有人)。

作爲每spec

除日期對象中的所有標準對象處理沒有一個提示 的彷彿暗示編號給予;日期對象處理缺少 提示,就像提供了提示字符串一樣。異國情調的物體可能會以其他方式處理提示缺失。

而且在時間的情況下,他們做出exception

本規範中定義的對象中,只有Date對象(見 20.3.4.45)和Symbol對象(見19.4.3.4)超馳默認的ToPrimitive行爲。日期對象不會將提示視爲提示爲 字符串。

此外,檢查this

這個功能是通過ECMAScript語言運營商被叫去 Date對象轉換爲原始值。提示的允許值爲 「default」,「number」和「string」。日期對象在 內置ECMAScript對象中是唯一的,因爲它們將「default」視爲 等效於「string」,所有其他內置ECMAScript對象將 「default」視爲等同於「number」。

因此,日期僅作爲字符串使用。

相關問題