W formularzu wartość z pola input o typie number została zapisana do zmiennej a, a następnie przetworzona w skrypcie JavaScript w następujący sposób
var x = Math.floor(a);Jaka wartość zostanie zapisana w zmiennej x, jeżeli użytkownik wpisał w pole liczbę 7.9?
A. 7
B. NaN
C. 8
D. "7.9" (napis)
Wynik 7 wynika z działania funkcji Math.floor(), która zawsze zwraca największą liczbę całkowitą mniejszą lub równą podanej wartości. Dla liczby 7.9 taką liczbą jest właśnie 7, a nie 8. To ważna różnica, bo Math.floor() nie zaokrągla klasycznie do najbliższej liczby całkowitej, tylko obcina wartość w dół, czyli w stronę mniejszych liczb. W praktyce Math.floor(7.9) daje 7, Math.floor(7.1) też daje 7, a Math.floor(8.0) daje 8. W JavaScripcie warto też pamiętać, że wartość pobrana z pola formularza przez właściwość value jest zwykle tekstem, nawet gdy input ma typ number. Jednak Math.floor() próbuje automatycznie przekonwertować taki tekst na liczbę, więc Math.floor('7.9') również zwróci 7. Moim zdaniem w realnym projekcie lepiej jawnie używać valueAsNumber albo parseFloat(), a potem sprawdzić Number.isNaN(), bo wtedy kod jest czytelniejszy i mniej podatny na dziwne błędy z formularza. To jest dobra praktyka branżowa: nie liczyć ślepo na automatyczną konwersję typów, tylko jasno pokazać, jakie dane przetwarzamy.
W tym zadaniu łatwo pomylić kilka mechanizmów JavaScriptu, szczególnie jeśli kojarzy się pole input type number z tym, że od razu dostajemy typ liczbowy. W DOM wartość pobierana przez value z formularza jest zazwyczaj napisem, ale funkcja Math.floor() wykonuje konwersję na liczbę, jeśli przekazana wartość wygląda jak poprawna liczba. Dlatego wpisanie 7.9 nie prowadzi automatycznie do NaN. NaN pojawiłoby się raczej wtedy, gdyby w zmiennej a znalazł się tekst, którego nie da się sensownie przeliczyć na liczbę, na przykład abc albo pusty ciąg w niektórych kontekstach walidacji. Odpowiedź traktująca wynik jako napis 7.9 też nie pasuje, bo Math.floor() nie zwraca oryginalnej wartości z formularza, tylko wynik operacji matematycznej typu number. Częsty błąd myślowy polega tu na zatrzymaniu się na etapie pobrania danych z inputa i zapomnieniu, że dalej działa funkcja z obiektu Math. Wynik 8 byłby poprawny przy Math.round(7.9), ponieważ round zaokrągla do najbliższej liczby całkowitej. Math.floor() działa inaczej: zawsze bierze podłogę liczby, czyli wartość całkowitą nie większą od argumentu. Przy liczbach dodatnich wygląda to jak odcięcie części po przecinku. Z mojego doświadczenia warto zapamiętać sobie parę: floor to podłoga, ceil to sufit, round to zwykłe zaokrąglenie. W kodzie produkcyjnym najlepiej jeszcze jawnie konwertować dane z formularza, np. przez valueAsNumber albo parseFloat(), i dopiero potem wykonywać obliczenia.