Bug #083
🪲 Znajdź buga
console.log(typeof NaN)
console.log(isNaN("foo"))
console.log(Number.isNaN("foo"))
console.log(isNaN(() => {}))
console.log(Number.isNaN(() => {}))
console.log(isNaN({}))
console.log(Number.isNaN({}))
console.log(isNaN([1, 2]))
console.log(Number.isNaN([1, 2]))
console.log(isNaN(undefined))
console.log(Number.isNaN(undefined))
console.log(isNaN(NaN))
console.log(isNaN("NaN"))
console.log(isNaN(123))
console.log(isNaN("123"))
console.log(isNaN([]))
console.log(isNaN(true))
console.log(isNaN(false))
console.log(isNaN(null))
Jakie wartości zostaną zalogowane do konsoli?
🧪 Rozwiązanie
console.log(typeof NaN) // number
console.log(isNaN("foo")) // true
console.log(Number.isNaN("foo")) // false
console.log(isNaN(() => {})) // true
console.log(Number.isNaN(() => {})) // false
console.log(isNaN({})) // true
console.log(Number.isNaN({})) // false
console.log(isNaN([1, 2])) // true
console.log(Number.isNaN([1, 2])) // false
console.log(isNaN(undefined)) // true
console.log(Number.isNaN(undefined)) // false
console.log(isNaN(NaN)) // true
console.log(isNaN("NaN")) // true
console.log(isNaN(123)) // false
console.log(isNaN("123")) // false (?)
console.log(isNaN([])) // false (?!)
console.log(isNaN(true)) // false (?!)
console.log(isNaN(false)) // false (?!)
console.log(isNaN(null)) // false (?!)
Po pierwsze isNaN()
i Number.isNaN()
nie są ze sobą zgodne 🤯.
Teoretycznie założeniem isNaN()
jest sprawdzenie czy wartość przekazana w argumencie nie jest wartością liczbową.
W praktyce isNaN()
sprawdza jednak czy wartość z argumentu jest ekwiwalentna wartości NaN
po konwersji do wartości liczbowej.
Co więcej, dokumentacja Mozilli zachęca do korzystania z Number.isNaN()
jako bardziej niezawodnego odpowiednika.
Tak, isNan()
i Number.isNaN()
potrafią zwracać różną wartość dla tego samego argumentu wejściowego.
Mimo deklarowanej większej niezawodności, Number.isNaN()
wciąż jest bardzo nieintuicyjną metodą w celu sprawdzania, czy wartość wejściowa nie jest wartością liczbową.
Dla uzyskania niezawodności i intuicyjności najlepiej skorzystać z porównania typeof x === "number"
.
Mamy wtedy pewność, że dostaniemy true
tylko wtedy, gdy x
będzie typu liczbowego.
Pułapką może okazać się wtedy typeof NaN === "number"
, który zwróci true
, ponieważ typ wartości NaN
to... number
.
Największe (moim zdaniem) pułapki w kwesti isNaN()
i Number.isNaN()
(gdy są ze sobą zgodne), to:
- Sprawdzanie ciągu znaków, który zawiera liczbę np.
"123"
- Pustej tablicy
[]
- Wartości logicznych
true
/false
null
Wszystkie z powyższych wartości ulegają konwersji do wartości liczbowych.
Ciąg znaków "123"
zostaje skonwertowany do wartości liczbowej 123
więc isNaN("123")
, tak samo jak Number.isNaN("123")
, zwraca false
.
Pusta tablica również jest konwertowana do wartości liczbowej, 0
.
Wartości logiczne true
/false
są konwertowane do 1
/0
.
null
również ulega konwersji do wartości 0
.
Z tego względu, powyższe wartości po konwersji do wartości liczbowej nie stają się wartością NaN
, więc isNaN()
dla nich zwraca false
.
🎢 Plac zabaw
Otwórz edytor w nowym oknie📑 Linki
❤️ Podobają Ci się bugi JS?
Podziel się linkiem ze znajomymi:
https://codisity.pl/100-bugow-js