Zdradliwa funkcja isNaN()

Użycie funkcji isNaN() w JavaScripcie wydaje się proste i logiczne. Przekazujemy jako parametr jakąś wartość, a funkcja mówi nam, czy ta wartość to NaN, czy coś innego. Ale jest coś, o czym bezwzględnie trzeba pamiętać. Ja zapomniałem i straciłem godzinę na debugowanie.

Opis funkcji znajduje się tutaj. Dla potomnych i na wypadek, gdyby na stronach MDN zmieniono treść dostępną w momencie popełniania niniejszego wpisu:

isNaN jest funkcją najwyższego rzędu i nie jest przypisana do żadnego obiektu.

Funkcje parseFloat i parseInt zwracają NaN, kiedy wyliczą wartość, która nie jest liczbą. isNaN zwraca true, jeśli przekazano jej NaN, a false w przeciwnym wypadku.

Niby wszystko jasne: funkcja zwróci prawdę, jeśli jako argument przekażemy jej NaN, a w przeciwnym razie otrzymamy fałsz. Ale to nie do końca tak działa (i moim skromnym zdaniem, opis na MDN powinien zostać uściślony). Oto parę linijek, które wpisałem w Node.js:

​> isNaN(NaN)
true
> isNaN(1)
false
> isNaN("a")
true
> isNaN("1")
false
> isNaN(null)
false
> isNaN(false)
false
> isNaN(true)
false
> isNaN([])
false
> isNaN(undefined)
true
> isNaN(/^$/)
true
> isNaN({})
true

A więc pokrótce:

  • prawdę otrzymamy po przekazaniu wartości NaN, undefined, obiektu, wyrażenia regularnego lub stringa, którego wartość zostałaby zewaluowana jako NaN przez funkcję parseInt lub parseFloat.
  • fałsz otrzymamy po przekazaniu wartości liczbowej, tablicy, null, wartości logicznej lub stringa, którego wartość parseInt lub parseFloat zewaluują jako liczbę.

Rada na przyszłość przy testowaniu wartości NaN: nie zapominajmy o sprawdzeniu również typu wartości. I nie zapominajmy też, jakiego typu jest sama wartość NaN:

​> typeof NaN
'number'

Logiczne wszak jest, że liczba nie jest nie-liczbą, ale nie-liczba jest liczbą!1


  1. Ale żeby nie było nieścisłości (i na wypadek, gdyby ktoś dociekliwy/złośliwy chciał się czepiać): to jest zgodne ze standardem IEEE 754, a definicja wartości NaN jest jak najbardziej określona jako wartość numeryczna. Ma ona reprezentację bitową jako liczba zmiennoprzecinkowa, wszystkie bity wykładnika ma ustawione na 1, a mantysa jest niezerowa. ↩︎


Napisz komentarz


Szukaj wpisów


Chmura tagów