Menu

null vs undefined w JavaScript: różnice, sprawdzanie i kiedy czego używać

Czym naprawdę różnią się null i undefined w JavaScript, jak sprawdzić jedno lub drugie i po które sięgać we własnym kodzie.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Dwa sposoby na powiedzenie "nic"

Większość języków ma jedną wartość oznaczającą brak. JavaScript ma dwie: null i undefined. Zachowują się na tyle podobnie, że mylą początkujących, i na tyle różnie, że potrafią zaskoczyć doświadczonych programistów. Zrozumienie tego podziału jest warte dziesięciu minut.

W skrócie:

  • undefined to to, co dostajesz od JavaScriptu, gdy czegoś brakuje.
  • null to to, co piszesz ty, gdy chcesz powiedzieć "celowo puste".

Zwróć uwagę na wzorzec: każde undefined powyżej pojawiło się, bo JavaScript nie znalazł wartości. null pojawiło się, bo ktoś je wpisał.

Skąd bierze się undefined

undefined pojawia się w kilku konkretnych sytuacjach, a wszystkie są odmianą "brak dostępnej wartości":

W każdym przypadku JavaScript sięgnął po wartość i nic tam nie znalazł. undefined to sposób silnika na powiedzenie "sprawdziłem, nie było wartości".

Możesz sam przypisać undefined (let x = undefined;), ale lepiej tego nie robić. Niech pozostanie sygnałem "JavaScript niczego nie znalazł". Używaj null, gdy to ty podejmujesz decyzję.

Skąd bierze się null

null pojawia się tylko wtedy, gdy ktoś je napisał. W tym cały sens: to celowy znacznik.

API DOM często używają null: document.getElementById("missing") zwraca null, a nie undefined, bo przeglądarka jawnie mówi "szukałam i odpowiedź brzmi: nie ma takiego elementu". JSON.parse("null") też daje null, bo JSON nie ma undefined.

Model myślowy: undefined to domyślny brak, null to wybrany brak.

Dziwactwo typeof

Oto słynny przypadek:

To, że typeof null zwraca "object", to błąd z 1995 roku, którego nie dało się naprawić bez psucia istniejących stron, więc został na zawsze. null nie jest obiektem: to typ prosty, tak jak undefined, liczby, stringi i wartości logiczne. Wynik typeof po prostu w tym przypadku kłamie.

Praktyczna konsekwencja: typeof nie nadaje się do wykrywania null. Użyj bezpośredniego porównania:

Albo, znacznie częściej, sprawdź obie wartości naraz. O tym w następnej sekcji.

Sprawdzanie obu naraz: idiom == null

Najczęściej nie obchodzi cię, którą z wartości oznaczających brak masz. Chcesz tylko wiedzieć, czy czegoś brakuje, zanim tego użyjesz. Idiomatyczne sprawdzenie to luźna równość z null:

value == null jest prawdą dokładnie dla null i undefined, a fałszem dla wszystkiego innego, także dla 0, "" i false, czyli zwykle tak, jak chcesz. To jedyna sytuacja, w której == jest lepsze od ===. Lintery o tym wiedzą i na to pozwalają.

Jeśli wolisz pisać jawnie, value === null || value === undefined znaczy to samo i czyta się to jasno.

Operatory nullish: ?? i ?.

Dwa operatory dodano specjalnie po to, żeby ułatwić pracę z null i undefined. Oba traktują te dwie wartości identycznie, a wszystko inne zostawiają w spokoju.

Operator nullish coalescing (??) podaje wartość zapasową tylko wtedy, gdy lewa strona to null lub undefined:

Porównaj to z ||, który zastąpiłby 0 wartością 3, bo 0 jest falsy. ?? jest bardziej rygorystyczny: działa tylko dla dwóch wartości nullish.

Optional chaining (?.) przerywa obliczanie łańcucha i zwraca undefined, gdy natrafi na null lub undefined:

Oba operatory istnieją, bo pytanie "czy ta wartość jest nullish?" pada bardzo często. Szczegółowo omawiamy je w dalszej części materiału.

Parametry domyślne działają tylko dla undefined

Subtelna, ale ważna zasada: domyślne wartości parametrów włączają się tylko dla undefined, a nie dla null.

Przekazanie null jest traktowane jak "jawnie wybieram brak wartości" i respektowane bez zmian. Jeśli chcesz, żeby null też uruchamiało wartość zapasową, użyj ?? wewnątrz funkcji:

To rozróżnienie regularnie sprawia ludziom kłopot. Wartości domyślne obsługują brakujące argumenty, a ?? obsługuje argumenty nullish.

JSON i brakujące undefined

JSON ma null, ale nie ma undefined. To prowadzi do cichych niespodzianek przy serializacji:

Pole age całkowicie zniknęło, bo JSON.stringify pomija właściwości z wartością undefined. null przetrwało, bo JSON je obsługuje. Przepuszczenie obiektu przez JSON w obie strony to częsty sposób, w jaki właściwości undefined po cichu znikają.

W tablicach undefined zamienia się w null:

Jeśli projektujesz dane dla API, dla pól "bez wartości" wybieraj null zamiast undefined. null przetrwa podróż.

Kiedy czego używać

Rozsądna konwencja dla własnego kodu:

  • Niech undefined znaczy "nie podano": brakujące argumenty, nieustawione zmienne, nieistniejące właściwości. Nie przypisuj undefined ręcznie.
  • Używaj null, gdy chcesz jawnie przekazać "to celowo puste": wylogowany użytkownik, niewybrana opcja, wyczyszczone pole formularza.
  • Na granicach API akceptuj obie wartości (użyj == null albo ??), ale zawsze zwracaj tę samą.

Niektóre przewodniki stylu (w tym TypeScriptu) całkiem pomijają null i używają tylko undefined. To da się obronić: jedna wartość jest prostsza niż dwie. Wybierz zasadę na projekt i stosuj ją wszędzie.

Dalej: konwersja typów

null i undefined zachowują się w określony sposób, gdy JavaScript zamienia je na liczby, stringi lub wartości logiczne: Number(null) to 0, ale Number(undefined) to NaN, a taka asymetria powoduje prawdziwe błędy. Następna w kolejce jest konwersja typów, a gdy poznasz pełne zasady, wiele dziwactw JavaScriptu przestanie być tajemnicą.

Najczęściej zadawane pytania

Jaka jest różnica między null a undefined w JavaScript?

undefined oznacza, że wartość nie została jeszcze przypisana: to właśnie dostajesz od JavaScriptu przy brakujących zmiennych, argumentach czy właściwościach obiektu. null to jawne 'tu nie ma wartości', które przypisujesz celowo. JavaScript nigdy sam nie tworzy null, musisz go wpisać.

Jak sprawdzić null i undefined jednocześnie?

Użyj value == null. Luźna równość traktuje null i undefined jako równe sobie nawzajem, ale niczemu innemu, więc x == null jest prawdą dokładnie dla tych dwóch wartości. To jedyne miejsce, gdzie == zamiast === jest idiomatyczne i bezpieczne.

Dlaczego typeof null zwraca 'object'?

To błąd z pierwszej wersji JavaScriptu, którego nie da się naprawić bez psucia internetu. typeof null zwraca 'object', choć null jest typem prostym. Żeby sprawdzić konkretnie null, porównaj wprost: value === null.

Używać we własnym kodzie null czy undefined?

Niech undefined znaczy 'nic nie podano', a null stosuj, gdy chcesz jawnie zasygnalizować 'to celowo puste'. Wiele projektów (i przewodnik stylu TypeScriptu) całkiem unika null i używa tylko undefined. Wybierz jedną konwencję na projekt i się jej trzymaj.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ