Полезный NaN

в 8:26, , рубрики: datetime, javascript

О NaN больше всего известно то, что он не равен самому себе.

NaN === NaN // false

И что операции, невозможные арифметически, вернут NaN.

'BlaBlaBla'/0 // NaN

Но у NaN есть одно мало известное(?), и, как мне кажется, весьма полезное применение.

TL;DR Все дело в Date

В двух словах:

 new Date(NaN) // Invalid Date 

Чем полезно? Invalid Date все равно Date. И все операции с Date все ещё на месте.
Любые операции с Date, кроме прямой установки timestamp вернут NaN, оставив Date как Invalid Date.

 
const x =  new Date(NaN) // Invalid Date 
x.setTime(12345) // 12345
x.toString() // "Thu Jan 01 1970 00:00:12 GMT+0000 (+00)"

При этом, проверка на валидность даты становится проще некуда

 
const x = new Date(NaN) // Invalid Date 
isNaN(x) // true
x.setTime(0)
isNaN(x) // false

Заметьте, преобразование в timestamp здесь не требуется, valueOf() делает это под капотом.

Все операции с Date — мутабельные. Тем не менее, клонирование через конструктор прекрасно работает и с Invalid Date.

 
const x =  new Date(NaN) // Invalid Date 
const y = new Date(x) // Invalid Date

Сравнение двух дат напрямую в Date не реализовано и сравнивать даты можно только через timestamp. NaN гарантирует что Invalid Date точно не будет равно никакой другой дате. Думаю, это весьма полезное свойство.

 
const x =  new Date(NaN) // Invalid Date 
const y = new Date(NaN) // Invalid Date
x.getTime() === y.getTime() // false

К моему сожалению, конструктор Date ведёт себя несколько странно по отношению к входному параметру.

 new Date(null) // Thu Jan 01 1970 00:00:00 GMT+0000 (+00) 

Было бы намного логичнее конструировать Invalid Date, ведь null — это не совсем ноль. Оставим это на совести Javascript-а.
Однако, если насильственно передать в конструктор undefined, то результат выглядит ожидаемым. Так что будьте осторожны.

 new Date(undefined) // Invalid Date 

Статья получилась больше о Date чем о NaN, но, в целом, именно об этой связке я хотел рассказать.

Автор: ua9msn

Источник

Поделиться

* - обязательные к заполнению поля