2015-09-02 14 views
5

Die JS-Dokumentation für Date behauptet, dass es vier Möglichkeiten gibt, den Date-Konstruktor zu verwenden. Von https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date:Aufrufen des Date-Konstruktors mit einem Date-Objekt

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

Allerdings scheint es ein fünfte Weg, um den Konstruktor zu verwenden, indem sie in einem gültigen Datum-Objekt übergeben. sind

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) 

Sie verschiedene Objekte, so scheint es wie eine einfache Möglichkeit, eine Kopie eines Datums zu machen: Zum Beispiel das folgende funktioniert gut in der Chromkonsole

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) 

So sind meine Fragen :

  1. Warum ist das nicht in der offiziellen Dokumentation? Fehle ich etwas?
  2. Ist dies eine offiziell unterstützte Verwendung des Konstruktors? Wird es auf allen Plattformen/Browsern funktionieren?
  3. Ist dies eine sichere Möglichkeit, eine Kopie eines Date Objekts zu erstellen, wobei z. date2 = new Date().setTime(date.getTime())?
+0

Es funktioniert in Firefox, aber das Ergebnis ist nicht genau der gleiche Zeitstempel wie der ursprüngliche (Millisekunden sind abgeschnitten). Führen Sie das Beispiel einfach ein paar Mal aus: [jsfiddle] (https://jsfiddle.net/at51o4aw/) – lzydrmr

Antwort

2

Gerade aus dem entsprechenden Abschnitt der ECMAScript 6 spec:

Wenn Typ (Wert) ist Objekt und Wert hat einen [[DatWert]] internen Steckplatz, dann Let tv thisTimeValue (Wert) sein.

die im Grunde sagt, dass, wenn Sie das Datum Konstruktor ein Argument übergeben, und es ist ein Ziel, und es hat den [[DateValue]] internen Steckplatz, dann verwenden Sie das neue Objekt zu initialisieren.

Also, was Sie sehen, ist in der Spezifikation dokumentiert.

Hier genauer:

enter image description here

Aber die ES5 spec ist nicht das gleiche und eine Umwandlung in einen String tun, wenn Sie das tun, was Sie tun, die dann als analysiert werden eine Zeichenfolge vom Konstruktor. Während dies funktioniert, um alles auf die Sekunden zu beschränken, wird es keine Millisekunden erhalten, da diese in der Standard-String-Konvertierung nicht vorhanden sind. Also, wenn Sie eine perfekte Kopie wollen, dann sollten Sie dies in ES5 oder früher tun:

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

Sehr interessant ... danke! Ist das Problem, dass ich mir die falsche Dokumentation angesehen habe? Warum erklärt die andere Dokumentation dieses Verhalten nicht? – xph

+0

@xph - MDN ist kein Evangelium. Es ist ein Crowd-Sourced-Versuch, Entwicklern zu helfen (was es sehr erfolgreich macht) und ich benutze es sehr oft. Aber es ist keineswegs immer perfekt. Alle Verwirrung sollte gelöst werden, indem man die tatsächliche Spezifikation betrachtet. Ich weiß nicht, warum diese Verwendung des Konstruktors dort nicht dokumentiert ist. – jfriend00

+0

Wird dieses Verhalten von allen gängigen Browsern übernommen? Oder verwenden sie immer noch ES 5.1-Verhalten? – MinusFour

0

ich dagegen jetzt raten würde. Dies ist, was jetzt unter den Browsern unter verschiedenen Spezifikationen für das Objekt Date geht.

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>

Es es nicht vergleichen perfekt ABER .... Hier ist, wie ES5.1 wird handhaben, dass:

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>

Es wird im Grunde rids die Millisekunden des ersten Date Objekts (Assertion könnte funktionieren, wenn das erste Date-Objekt keine Millisekunden hat, das Snippet ein paar Mal laufen). Firefox scheint dem ES5.1-Verhalten im Moment zu folgen und Chrome ES6.0. Ich kann nicht wirklich sagen, wann sie angefangen haben es zu übernehmen.

Ich würde auf jeden Fall nicht raten, das Date Objekt als Konstruktor für ein neues Date Objekt zu übergeben, wenn der Zweck das erste Date Objekt zu klonen ist. Verwenden Sie stattdessen Data.prototype.getTime().

Verwandte Themen