2015-09-02 131 views
5

的JS文檔Date聲稱有使用Date構造四種方式。從https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date調用Date構造函數Date對象

new Date(); 
new Date(value); // integer 
new Date(dateString); // string 
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]); 

然而,似乎是使用構造函數,通過傳遞一個有效的Date對象的第五種方式。例如,下面的鉻控制檯正常工作:

date = new Date() // Wed Sep 02 2015 16:30:21 GMT-0700 (PDT) 
date2 = new Date(date) // Wed Sep 02 2015 16:30:21 GMT-0700 (PDT) 

它們是不同的對象,因此它似乎是一個簡單的方法,使一個日期的一個副本:

date2 === date // false 
date.setMonth(1) // 1422923421090 
date // Mon Feb 02 2015 16:30:21 GMT-0800 (PST) 
date2 // Wed Sep 02 2015 16:30:21 GMT-0700 (PDT) 

所以我的問題是:

  1. 爲什麼這不是正式文件?我錯過了什麼嗎?
  2. 這是一個正式支持使用構造的?它可以在所有平臺/瀏覽器上運行嗎?
  3. 這是使Date對象的副本一個安全的方式,例如更換date2 = new Date().setTime(date.getTime())
+0

它在Firefox中工作,但結果與原始的時間戳不完全相同(毫秒被截斷)。只需運行該示例幾次:[jsfiddle](https://jsfiddle.net/at51o4aw/) – lzydrmr

回答

2

直從ECMAScript 6 spec的相關部分:

如果Type(值)是Object和值具有[[則DateValue]]內部插槽, 則令TV是thisTimeValue(值)。

基本上說,如果您通過Date構造函數一個參數,它是一個對象,它有[[DateValue]]內部插槽,然後使用它來初始化新的對象。

所以,你所看到的在說明書中記載。

這裏的更多詳細信息:

enter image description here

但是,在ES5規範是不一樣的當你這樣做,你在做什麼,然後將被解析爲會做一個轉換爲字符串一個由構造函數構造的字符串。儘管這樣做可以將所有內容保存到秒,但它不會保留毫秒,因爲這些內容在默認字符串轉換中不存在。所以,如果你想要一個完美的副本,那麼你應該這樣做的ES5或更早版本:

var date = new Date(); 
var date2 = new Date(date.getTime()); 
+0

非常有趣...謝謝!那麼,我一直在尋找錯誤的文檔?其他文檔爲什麼不解釋這種行爲? – xph

+0

@xph - MDN不是福音。這是一個衆包的嘗試來幫助開發人員(它經常成功完成),我使用它很多。但是,這並不總是完美的。所有的困惑都應該通過查看實際的規格來解決。我不知道爲什麼這個構造函數的使用沒有記錄在那裏。 – jfriend00

+0

所有主流瀏覽器都採用這種行爲嗎?還是他們仍在使用ES 5.1行爲? – MinusFour

0

我建議不要,就目前而言。這就是現在瀏覽器下的Date對象的不同規格。

ES 6.0:

var d1 = new Date(); 
 
var d2 = new Date(d1.getTime()); 
 
//ES6.0 basically gets the property that holds the timestamp straight from the object. 
 

 
document.getElementById('results').innerHTML = 'Assert: ' + d1.valueOf() + ' === ' + d2.valueOf() + ' ' + (d1.valueOf() === d2.valueOf());
<pre id="results"></pre>

它比較完美,但....下面是如何ES5。1將處理的是:

var d1 = new Date(); 
 
var d2 = new Date(Date.parse(d1.toString())); 
 
//ES5.1 will attempt to parse the string representation of the Date object. 
 

 
document.getElementById('results').innerHTML = 'Assert: ' + d1.valueOf() + ' === ' + d2.valueOf() + ' ' + (d1.valueOf() === d2.valueOf());
<pre id="results"></pre>

它基本上得到第一Date對象的毫秒(如果第一次約會的對象沒有毫秒斷言可能會奏效,運行片斷幾次的的RID )。 Firefox目前似乎在跟隨ES5.1行爲以及Chrome ES6.0。當他們開始採用它時,他們無法確定。

我肯定會不建議傳遞Date對象作爲一個構造一個新的Date對象,如果目的是克隆第一Date對象。改爲使用Data.prototype.getTime()