Bug #064
🪲 Znajdź buga
console.log(Number(undefined))
console.log(Number(null))
console.log(Number(false))
console.log(Number(true))
console.log(Number({}))
console.log(Number([]))
console.log(Number("a"))
console.log(Number("\f"))
console.log(Number("\n"))
console.log(Number("\r"))
console.log(Number("\t"))
console.log(Number("\v"))
console.log(Number("\b"))
console.log(Number(["a"]))
console.log(Number([0]))
console.log(Number(["0"]))
console.log(Number([0, 0]))
console.log(Number([1]))
console.log(Number(["1"]))
console.log(Number([0, 1]))
console.log(Number(""))
console.log(Number(" "))
console.log(Number(" \n \t \f \v "))
console.log(Number(" \n \t \f \v 1 "))
console.log(Number("1e2"))
console.log(Number(1e2))
console.log(Number("0x64"))
console.log(Number(0x64))
console.log(Number("0b01100100"))
console.log(Number(0b01100100))
console.log(Number("\u0031\u0030\u0030"))
console.log(Number("\x31\x30\x30"))
Funkcja Number
konwertuje przekazany argument do wartości liczbowej.
Jakie wartości zostaną zalogowane do konsoli w powyższych przykładach?
🧪 Rozwiązanie
console.log(Number(undefined)) // NaN
console.log(Number(null)) // 0
console.log(Number(false)) // 0
console.log(Number(true)) // 1
console.log(Number({})) // NaN
console.log(Number([])) // 0
console.log(Number("a")) // NaN
console.log(Number("\f")) // 0
console.log(Number("\n")) // 0
console.log(Number("\r")) // 0
console.log(Number("\t")) // 0
console.log(Number("\v")) // 0
console.log(Number("\b")) // NaN
console.log(Number(["a"])) // NaN
console.log(Number([0])) // 0
console.log(Number(["0"])) // 0
console.log(Number([0, 0])) // NaN
console.log(Number([1])) // 1
console.log(Number(["1"])) // 1
console.log(Number([0, 1])) // NaN
console.log(Number("")) // 0
console.log(Number(" ")) // 0
console.log(Number(" \n \t \f \v ")) // 0
console.log(Number(" \n \t \f \v 1 ")) // 1
console.log(Number("1e2")) // 100
console.log(Number(1e2)) // 100
console.log(Number("0x64")) // 100
console.log(Number(0x64)) // 100
console.log(Number("0b01100100")) // 100
console.log(Number(0b01100100)) // 100
console.log(Number("\u0031\u0030\u0030")) // 100
console.log(Number("\x31\x30\x30")) // 100
Próba konwersji undefined
za pomocą funkcji Number
zwróci NaN
.
Dla wartości null
zostanie jednak zwrócona już wartość liczbowa 0
.
Jest to dość powszechnie niespójne zachowanie JavaScriptu, który w różnych sytuacjach różnie konwertuje wartości null
i undefined
.
Wartości logiczne false
/true
są konwertowane do liczbowych odpowiedników tj. 0
/1
.
Mimo, że tablice są również obiektami w języku JavaScript, pusty obiekt zostanie skonwertowany do wartości NaN
, a pusta tablica do wartości liczbowej 0
.
Ciągi znaków nie zawierających liczb, są konwertowane do wartości NaN
.
Poprzedzenie litery znakiem wstecznego ukośnika powoduje tzw. ucieczkę (escape) danego znaku.
Znaki f
, n
, r
, t
, v
, b
poprzedzone \
generują białe znaki (podobnie jak np. spacja).
W zależności od znaku może to być np. wstawienie tabulatora, przejście do nowej linii, itp..
Funkcja Number
konwertuje białe znaki (w tym standardowe spacje), do wartości liczbowej 0
.
Wyjątkiem jest \b
, który oznacza wstawienie wstecznej spacji (backspace) i jest konwertowane do wartości NaN
.
W przypadku tablic, jeśli składają się tylko z jednego elementu, Number
konwertuje je tak samo, jak gdyby wartości nie były elementem tablicy.
Gdy jednak tablica zawiera więcej niż jeden element, w efekcie konwersji zwracana jest wartość NaN
.
Białe znaki łączone w ciąg białych znaków zachowują się tak samo jak pojedyncze, tj. są w całości konwertowane do wartości 0
.
Jeśli jednak wśród białych znaków wystąpi wartość liczbowa, jest ona konwertowana do wartości liczbowej, ignorując wszystkie występujące sąsiadujące białe znaki.
Ostatnią grupą są wartości liczbowe zapisywane w innych notacjach lub systemach liczbowych.
1e2
to zapis liczby w notacji naukowej. Litera e
jest skrótem od exponential czyli notacji wykładniczej, czyli potęgowania liczby 10
. Wartość po literze e
to wielkość wykładnika potęgi.
1e2
to więc to samo co 1 * 10 ** 2
(gdzie **
to w JavaScript operator potęgowania).
Upraszczając do zapisu tekstowego, 1
razy 10
do potęgi 2
.
Liczba występująca po e
oznacza więc ilość zer, które należałoby zapisać stosując standardowy zapis liczby dziesiętnej.
1e2
daje nam więc w standardowym zapisie liczbę dziesiętną 100
.
W przypadku konwersji poprzez Number()
nie ma znaczenia czy przekażemy taką notację jako ciąg znaków, czyli z użyciem cudzysłowu, czy bez, jako wartość liczbową.
Podobnie sytuacja wygląda w przypadku innych typów oraz systemów zapisu liczb.
0x64
to zapis w systemie szesnastkowym (heksadecymalny) oznaczający liczbę dziesiętną 100
.
0x
to prefix mówiący o typie notacji, a 64
to faktyczna liczba w systemie szesnastkowym.
0b01100100
to podobna sytuacja. 0b
to prefix dla zapisu liczby w systemie binarnym (dwójkowym).
01100100
to faktyczna liczba w systemie dwójkowym, odpowiadająca liczbie 100
w systemie dziesiętnym.
\u0031\u0030\u0030
to ciąg znaków w standardzie kodowania unicode w zapisie szesnastkowym. Każda z liczb odpowiada znakowi z tablicy znaków.
0031
to liczba szesnastkowa, odpowiadająca liczbie dziesiętnej 49
, która z kolei jest przypisana do znaku liczby 1
z tablicy znaków.
0030
w zapisie szesnastkowym to 48
w zapisie dziesiętnym i odpowiada mu z tablicy znaków liczba 0
.
\u0031\u0030\u0030
to więc finalnie to samo co zapis liczby 100
.
Analogicznie wygląda sytuacja z zapisem liczb z prefiksem \x
.
Oznacza on również zapis szesnastkowy, jednak w skróconej dwu-znakowej wersji.
Zapis ten daje tym samym do dyspozycji mniejszy zakres z tablicy znaków (bazowe kodowanie, bez rozszerzonych znaków, jak chociażby polskie znaki alfabetu typu ą, ę, itp.).
🎢 Plac zabaw
Otwórz edytor w nowym oknie📑 Linki
- Number() constructor - JavaScript | MDN
- Exponentiation (**) - JavaScript | MDN
- List of Unicode characters - Wikipedia
❤️ Podobają Ci się bugi JS?
Podziel się linkiem ze znajomymi:
https://codisity.pl/100-bugow-js