2017-02-01 4 views
3

Я возился с JSFiddle для решения проблемы this в FreeCodeCamp. При использовании в качестве даты строки (то есть, нет "новой"):Почему (new Date() == new Date()) false, но (Date() == Date()) истинно?

Случай 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 возвращает истинную. Однако, когда я использую Дата в качестве конструктора (с "новой"):

Случай 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 возвращает ложные. Тем не менее, когда я добавить унарный оператор "+" (!):

Случай 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 возвращает истинную. Я понимаю, что случай 1 и случай 3 возвращают true, потому что они являются одними и теми же строками и теми же значениями миллисекунды.

Почему случай 2 возвращается false?

+6

два экземпляра одного и того же конструктора по-прежнему отличаются от друг друга, даже если они имеют те же свойства, так как они являются различными объектами. Если вы хотите сравнить даты, добавьте их в miliseconds и добавьте целое число. Кроме того, sicne new Date() возвращает текущую временную метку, может существовать разница в milisecond между двумя новыми вызовами Date(). – Shilly

+1

, потому что даже '({}) == ({})' ... но 'Date()' возвращает строку, поэтому она будет == большую часть времени ... за исключением того, что секундные метки превышают –

+1

' бросать их в miliseconds' ... но время от времени 'new Date(). getTime() == new Date(). getTime()' false ... потому что миллисекунда может переключаться между двумя вызовами на новый Date() ... менее вероятно с 'Date() == Date()' - потому что это строка с 1-секундным разрешением ... но все равно может быть неверно –

ответ

6

Использование Date(), дата объекты JavaScript может быть создана только с помощью вызова JavaScript Даты в качестве конструктора: вызов его в качестве регулярной функции (т.е. без нового оператора) возвращает строку, а не объект Date. MDN Reference.

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

вместо того, чтобы, используя конструктор как new Date(), каждый экземпляр уникален (два экземпляра одного и того же конструктора по-прежнему отличаются друг от друга,), это является причиной, почему они не равны при сравнении.

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

Уверен, что каждый экземпляр уникален, но вы не могли бы использовать тот же аргумент, чтобы сказать, что var a = 'a'; var b = 'a'; a == b; должен оцениваться как ложный? В конце концов, они разные. Также почему все другие сравнения, такие как <, > и т. Д., Работают с объектами даты, но == это исключение, которое не работает. Кажется, он запутался. – tobuslieven

+2

@tobuslieven извините, но 'var a = 'a'; var b = 'b'; a === b' равно false. – Radex

+1

@tobuslieven Это по дизайну в Алгоритме сравнения абстрактного равенства. См. Мой ответ ниже – gotomanners

3

Проще говоря, случай 2 возвращает ложь, потому что вы сравниваете два различных объектных ссылок (даже если оба объекта содержат точные те же свойства).

Принимая во внимание, что в других случаях вы сравниваете стоимость дат. toString().

Пожалуйста, смотрите примечание 3 в официальной документации для ==Abstract Equality Algorithm

Примечание 3

Оператор равенства не всегда транзитивно. Например, могут быть два различных объекта String, каждый из которых представляет одинаковое значение строки .

Каждый объект String будет считаться равным значению строки оператором ==, но два объекта String не будут быть равными друг другу.Например:

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

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

но

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

Зачем нужно, чтобы в равенстве учитывались только ссылки на объекты, когда другие сравнения <, > и т. Д., Похоже, работают должным образом в соответствии с соответствующими датами? – tobuslieven

+1

Его особенность оператора '=='. Равенство не выполняется по значению, а по ссылке в отличие от '>, <' и т. Д. – gotomanners

+0

Вау, это интересно. Надо сказать, что это кажется плохим выбором. Любая идея, почему они решили, что это исключение должно существовать? Я не вижу выгоды. – tobuslieven

Смежные вопросы