W tym dziale porozmawiamy o typach. Dowiemy się jakie podstawowe typy istnieją w JavaScript, a także o tym dlaczego wartość null to typ obcject.

Zmienna nie ma typu, tylko jej wartość

Można powiedzieć, że w języku JavaScript zadeklarowane zmienne nie mają typów. Dopiero wartości przypisane do tej zmiennej mają typ.

Mało tego JavaScript nie pilnuje w żaden sposób typu przypisanego do zmiennej, w jednej chwili może być to number a w drugiej string czy boolean. Z jednej strony jest to fajne, bo język jest bardzo elastyczny. Z drugiej strony nigdy nie wiadomo, jaki typ kryje się pod zmienną i może to doprowadzić do wielu pomyłek i błędów.

W poniższym przykładzie mamy zmienną value, która na początku zainicjalizowana jest typem string, potem przypisana jest liczba, czyli typ number i na końcu wartość true czyli typ boolean.

let value = 'some value';
value = 42;
value = true;

Warto jednak pilnować się z taką zmianą wartości dla pojedynczej zmiennej. Może to powodować nieoczekiwane i trudne do znalezienia błędy. Dobrze jest, jeśli stworzona zmienna ma wartość o jednym typie przez cały czas działania programu. Warto przestrzegać tej zasady.

Przyjrzyjmy się teraz dostępnym typom. W języku JavaScript mamy typy proste nazywane też prymitywne jak:

Primitives types:
null
undefined
boolean
number
string
symbol
bigint

oraz typ złożony (możemy nazwać typ obiektowy czy referencyjny) Object:

Object type:
object
subtypes from object:
function
array

Typ Object ma jeszcze podtypy, a najważniejsze z nich to Function i Array, które omówimy szczegółowo w oddzielnych działach.

Typ symbol sobie odpuścimy i nie będziemy się teraz nim zajmować ani przejmować. Typ bigint jest stosunkowo nowym typem, omówimy go na końcu.

Wypisywanie typu

Stworzymy teraz zmienne dla poszczególnych typów oraz użyjemy operatora typeof. Za pomocą tego operatora, możemy wypisać typy wartości do konsoli:

Na początek zdefiniuję zmienne dla każdego z podstawowych typów:

const nullValue = null;
const undefinedValue = undefined;
const booleanValue = true;
const numberValue = 42;
const stringValue = 'hello';
const objectValue = { a: 42 };
const bigIntValue = 1234567890123456789012345678901234567890n;

teraz za pomocą cosnole.log i typeof możemy wypisać typy wartości, które przypisane są do zmiennych:

console.log(typeof nullValue); //object
console.log(typeof undefinedValue); //undefined
console.log(typeof booleanValue); //boolean
console.log(typeof numberValue); //number
console.log(typeof stringValue); //string
console.log(typeof objectValue); //object
console.log(typeof bigIntValue); //bigint

Widzimy typy dla każdej wartości. Widzimy, że wartość undefined, true, liczba 42, tekst hello, stworzony obiekt i liczba bigint, mają prawidłowo wypisane typy za pomocą operatora typeof.

Natomiast wartość null nie ma swojego typu null, ale jest typu object. Jest to niestety błąd i problem od początku istnienia JavaScript i dzisiaj błąd ten jest już nienaprawialny. To, że jest to typ object nie oznacza, że null jest referencją do czegoś, null niczego nie reprezentuje i nie odnosi się do żadnej referencji. Reprezentuje brak wartości.

Typ dla funkcji

Będąc przy określaniu typów, warto wspomnieć jeszcze o typach dwóch ważnych elementów języka JavaScript, są to funkcje i tablice.

function test() {
}

console.log(typeof test); //function

Stworzyłem funkcję test i wypisałem jej typ do konsoli. Widzimy typ function. Tak naprawdę typ function jest podtypem object. Dlatego nie rozpatrujemy go jako oddzielnego typu najwyższego rzędu i o funkcjach nie wspomina się jako o oddzielnych typach.

Typ dla tablicy

Kolejnym elementem jest tablica, która wyświetla typ object. Również możemy powiedzieć, że jest to podtyp typu object.

const arr = [];
console.log(typeof arr); // object

Do tablic wrócimy jeszcze w oddzielnym dziale i będziemy je szczegółowo omawiać.

Typ bigint

Ostatnim typem, na który zwrócę uwagę jest bigint. Typ ten powstał po to aby operować na bardzo dużych liczbach, z którymi nie radzi sobie typ number. Mowa tu o liczbach większych niż 2^53. Wtedy typ number traci swoją precyzję i dlatego powstał typ bigint.

Sam nie miałem jeszcze okazji używać takich wartości. Jeżeli jednak będziemy pracować na takich liczbach, konieczne jest użycie bigint, a deklaruje się go używając litery n na końcu liczby:

const big = 1234567890123456789012345678901234567890n
console.log(typeof big) // bigint

Gdy sprawdzimy typ wartości w zmiennej o nazwie big, operator typeof zwróci nam typ bigint.

Podsumowanie

Tak wyglądają typy w języku JavaScript, o którym się mówi, że nie ma typów. O ile sama zadeklarowana zmienna nie ma typu, to wartość przypisana do zmiennej jest określona przez konkretny typ.

W następnych częściach przejdziemy przez poszczególne typy i zapoznamy się z nimi dokładniej. Dowiemy się jak z nimi pracować, jakie powodują problemy i pułapki. Choć mówi się, że JavaScript jest prostym językiem, to niestety posiada wiele niuansów, które warto zrozumieć.

Również dla funkcji, tablic i obiektów poświęcimy zupełnie oddzielne działy.

Co warto zapamiętać:

  • mamy 8 dostępnych typów jak: null, undefined, boolean, number, string, symbol, bigint, object oraz function i array jako podtyp.
  • zmienne nie posiadają typów, to wartości posiadają typ
  • operator typeof służy do sprawdzania typu wartości przypisanej do zmiennej
  • warto przestrzegać zasady i pilnować, aby przez cały program do zmiennej była przypisana wartość jednego typu, wyjątkiem może być wartość null, którą czasami specjalnie musimy przypisać.