2017-02-01 3 views
3

Ich habe mit JSFiddle rumgespielt, um this Problem in FreeCodeCamp zu lösen. Wenn ich das Datum als String (das heißt, keine "neuen"):Warum ist (new Date() == new Date()) falsch, aber (Date() == Date()) ist wahr?

Fall 1:

function isSameDay (dtFrom, dtTo) { 
    return dtFrom == dtTo 
    } 

    let today = Date() 
    let tomorrow = Date() 

    console.log(today) 
    console.log(tomorrow) 
    console.log(isSameDay(today, tomorrow)) 

isSameDay kehrt wahr. Jedoch, wenn ich Datum als Konstruktor (mit "neuen"):

Fall 2:

function isSameDay (dtFrom, dtTo) { 
    return dtFrom == dtTo 
    } 

    let today = new Date() 
    let tomorrow = new Date() 

    console.log(today) 
    console.log(tomorrow) 

    console.log(isSameDay(today, tomorrow)) 

isSameDay gibt falsche. Allerdings, wenn ich fügen Sie den unären Operator "+" (!):

Fall 3:

function isSameDay (dtFrom, dtTo) { 
    return dtFrom == dtTo 
    } 

    let today = + new Date() 
    let tomorrow = + new Date() 

    console.log(today) 
    console.log(tomorrow) 

    console.log(isSameDay(today, tomorrow)) 

isSameDay kehrt wahr. Ich verstehe, dass Fall 1 und Fall 3 wahr sind, weil sie nur die gleichen Strings und die gleichen Millisekundenwerte sind.

Warum gibt Fall 2 zurück false?

+6

Zwei Instanzen des gleichen Konstruktor sind sie noch andere, auch wenn sie exakt die gleichen Eigenschaften haben, da sie unterschiedliche Objekte sind. Wenn Sie Datumsangaben vergleichen möchten, wandeln Sie sie in Millisekunden um und berechnen Sie diese Ganzzahl. Außerdem gibt sicne new Date() den aktuellen Zeitstempel zurück, es könnte einen Millisekundenunterschied zwischen zwei neuen Date() Aufrufen geben. – Shilly

+1

weil nicht einmal '({}) == ({})' ... aber 'Date()' gibt einen String zurück, also wird es == die meiste Zeit ... außer wenn die Sekunden über –

+1

'tickt Wirf sie in Millisekunden "... aber ab und zu' new Date(). getTime() == new Date(). getTime() 'ist falsch ... weil eine Millisekunde zwischen den beiden Aufrufen von new umkehren kann Datum() ... weniger wahrscheinlich mit 'Date() == Date()' - weil es eine Zeichenkette mit 1 Sekunde Auflösung ist ... aber immer noch kann es falsch sein –

Antwort

6

Date() verwenden, können die JavaScript-Date-Objekte nur durch den Aufruf von JavaScript Date als Konstruktor instanziert werden: es als normale Funktion aufrufen (das heißt ohne den neuen Betreiber) wird eine Zeichenfolge anstatt ein Date-Objekt zurück. MDN Reference.

typeof Date() //"string" 
Date() == Date() //true 

verwenden stattdessen einen Konstruktor als new Date() jede Instanz ist einzigartig (die zwei Instanzen des gleichen Konstruktor jeder-andere noch verschieden sind), dies ist der Grund, warum sie nicht gleich sind, verglichen.

typeof new Date();  //"object" 
new Date() === new Date() //false 
+0

Sicher, jede Instanz ist einzigartig, aber Sie könnten nicht das gleiche Argument verwenden, um zu sagen, dass var a = 'a'; var b = 'a'; a == b; sollte zu falsch bewerten? Sie sind schließlich verschiedene Instanzen. Auch warum sollten alle anderen Vergleiche wie <, > usw. mit den date-Objekten arbeiten, aber == ist eine Ausnahme, die nicht funktioniert. Scheint entworfen zu verwirren. – tobuslieven

+2

@tobuslieven Sorry aber 'var a = 'a'; var b = 'b'; a === b' ist gleich falsch. – Radex

+1

@ tobuslieven Dies ist von Entwurf in The Abstract Equality Comparison-Algorithmus. Siehe meine Antwort unter – gotomanners

3

Einfach ausgedrückt, Fall 2 falsch zurückkehrt, weil Sie vergleichen zwei verschiedene Objektreferenzen (auch wenn beide Objekte die genau gleichen Eigenschaften enthalten).

In den anderen Fällen vergleichen Sie den toString() Wert der Daten.

siehe Anmerkung 3 in der offiziellen Dokumentation der ==Abstract Equality Algorithm

ANMERKUNG 3

Der Gleichheitsoperator nicht immer transitiv ist. Beispielsweise können zwei unterschiedliche String-Objekte sein, die jeweils den gleichen String-Wert darstellen.

Jedes String-Objekt würde dem Zeichenfolgenwert durch den Operator == gleichgesetzt, aber die beiden String-Objekte würden nicht gleich sein.Zum Beispiel:

new String("a") == "a" //true 

"a" == new String("a") //true 

aber

new String("a") == new String("a") //false. 
+0

Warum sollte sich die Gleichheit nur um Objektreferenzen kümmern, wenn die anderen Vergleiche <, > usw. nach den jeweiligen Daten korrekt zu funktionieren scheinen? – tobuslieven

+1

Es ist eine Besonderheit des '==' -Operators. Gleichheit wird nicht durch Wert, sondern durch Referenz im Gegensatz zu '>, <' usw. – gotomanners

+0

Wow, das ist interessant. Ich muss sagen, es scheint eine schlechte Wahl zu sein. Irgendeine Idee, warum sie diese Ausnahme entschied, sollte existieren? Ich sehe den Vorteil nicht. – tobuslieven