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