Szczegółowe zdjęcie ekranu komputera wyświetlającego słowa w tle chmura słów inwestycyjnych pokazująca różne rodzaje inwestycji AI generowane

undefined i null w JavaScript – czym się różnią?

11 min. czytania

undefined i null w JavaScript oznaczają „brak wartości”, ale w różny sposób: undefined to brak przypisania (domyślna wartość nadawana przez silnik języka), a null to świadomie przypisana pusta wartość przez programistę.

Zrozumienie tej różnicy wpływa nie tylko na poprawność kodu, ale też na dostępność — decyduje, co trafi do DOM i do technologii asystujących.

Szybkie definicje

undefined — zmienna została zadeklarowana, ale nie przypisano jej żadnej wartości. To domyślna wartość nadawana przez silnik języka.

Najczęstsze przypadki, kiedy otrzymasz undefined to:

  • nowo zadeklarowane zmienne bez inicjalizacji,
  • parametry funkcji, które nie zostały przekazane,
  • nieistniejące właściwości obiektów.

null — świadomie przypisana „pusta” wartość, zwykle oznaczająca brak obiektu lub brak aktualnej wartości. JavaScript nigdy sam z siebie nie przypisze null — to zawsze decyzja programisty.

null reprezentuje celowo ustawioną „pustkę”, a undefined — całkowity brak przypisania.

Krótkie porównanie — tabela

Dla szybkiego zestawienia kluczowych różnic zobacz poniższą tabelę:

Cecha undefined null
Kto nadaje wartość Nadaje silnik JS automatycznie Programista przypisuje świadomie
Znaczenie „Nie zainicjalizowano”, „brak przypisania” „Celowy brak wartości/obiektu”
Typ wg typeof "undefined" "object"historyczny błąd
Występowanie Domyślna wartość zmiennych, argumentów, właściwości Tylko po ręcznym przypisaniu lub z API/bazy danych
Relacja luźna == undefined == nulltrue null == undefinedtrue
Relacja ścisła === undefined === undefinedtrue null === nulltrue
Dla Number(...) Number(undefined)NaN Number(null)0
W kontekście logicznym if Wartość falsy Wartość falsy
Rekomendowane użycie „Systemowy brak inicjalizacji” „Biznesowy brak wartości” — świadomy stan

Skąd bierze się undefined?

Niezainicjalizowana zmienna

Jeśli zadeklarujesz zmienną bez nadania jej wartości, otrzyma undefined:

let count;
console.log(count); // undefined

Dotyczy to wszystkich deklaracji: let, const i var.

Pominięty parametr funkcji

Parametr, którego nie przekażesz przy wywołaniu funkcji, będzie miał wartość undefined:

function greet(name) {
console.log('Cześć, ' + name);
}
greet(); // name === undefined

Nieistniejąca właściwość obiektu

Dostęp do właściwości, której nie ma w obiekcie, zwraca undefined:

const user = { name: 'Anna' };
console.log(user.age); // undefined

Element tablicy bez wartości / poza zakresem

Odwołanie do elementu tablicy, który nie istnieje, również zwróci undefined:

const arr = [];
console.log(arr[10]); // undefined

Funkcja bez return

Funkcja, która nie zwraca jawnie wartości, domyślnie zwraca undefined:

function logMessage(msg) {
console.log(msg);
}
const result = logMessage('Cześć');
console.log(result); // undefined

Co oznacza null i po co w ogóle istnieje?

Świadoma decyzja programisty

null to wartość, którą programista przypisuje ręcznie, aby zaznaczyć: „tu jest celowo pusto”.

let selectedUser = null; // na razie nic nie wybrano
// później w kodzie:
selectedUser = { id: 1, name: 'Anna' };

JavaScript nie przypisze null automatycznie; jeśli widzisz null w zmiennej, to znaczy, że ktoś w kodzie ustawił go celowo.

Typowe zastosowania null

Poniżej kilka częstych zastosowań null w aplikacjach:

  • „puste miejsce” na obiekt – np. bieżący użytkownik, aktywny element UI;

let activeModal = null; // żadne okno modalne nie jest otwarte

  • brak wyniku – np. wyszukiwanie nic nie znalazło;

function findUser(id) {
const user = users.find(u => u.id === id);
return user ?? null; // brak wyniku → null
}

  • wartość jeszcze niezaładowana (np. z API).

let profile = null; // jeszcze nie wiemy
let isLoading = true;
fetch('/api/profile')
.then(res => res.json())
.then(data => {
profile = data;
isLoading = false;
});

null często oznacza: wartość powinna istnieć, ale na razie jej nie ma lub nie została znaleziona.

undefined, null i „undeclared” — trzy różne sytuacje

Jest też trzeci przypadek: undeclared — zmienna w ogóle nie została zadeklarowana.

console.log(x); // ReferenceError: x is not defined

Różnice między trzema stanami są następujące:

  • undefined — zmienna istnieje (była zadeklarowana), ale nie ma przypisanej wartości,
  • null — zmienna istnieje i ma świadomie przypisaną pustą wartość,
  • undeclared — zmienna nie została zadeklarowana; próba użycia kończy się błędem czasu wykonania.

Przykład, który pokazuje wszystkie trzy stany w praktyce:

let a; // zadeklarowana, nie zainicjalizowana
let b = null; // zadeklarowana, celowo pusta
// c — w ogóle nie istnieje
console.log(a); // undefined
console.log(b); // null
console.log(c); // ReferenceError

Jak działają porównania undefined i null?

Luźne porównanie ==

Specyfikacja JavaScript definiuje, że tylko null i undefined są sobie nawzajem równe przy ==:

null == undefined; // true
null == 0; // false
undefined == 0; // false

Stąd idiom:

if (value == null) {
// wejdziemy tu, gdy value jest null LUB undefined
}

To świadomy, skrócony sposób na sprawdzenie, czy wartość jest null lub undefined.

Ścisłe porównanie ===

Przy ścisłym porównaniu musi zgadzać się również typ:

null === undefined; // false
null === null; // true
undefined === undefined; // true

Używając ===, nigdy nie pomylisz null z undefined.

Zachowanie w instrukcji if (wartości „falsy”)

Zarówno null, jak i undefined są wartościami falsy (traktowane jak fałsz w kontekście logicznym):

if (!value) {
// wykona się dla: null, undefined, 0, '', false, NaN
}

To wygodne, ale bywa źródłem błędów — jeśli chcesz odróżnić pusty string ('') od null/undefined, sama negacja !value nie wystarczy.

Konwersja do liczb

Przy rzutowaniu na liczbę różnice są istotne:

Number(null); // 0
Number(undefined); // NaN

null konwertuje się do 0, a undefined do NaN (Not-a-Number). W obliczeniach może to prowadzić do subtelnych błędów:

const a = null;
const b = undefined;
console.log(a + 5); // 5 (0 + 5)
console.log(b + 5); // NaN

typeof null — słynna „wada” JavaScript

Sprawdzenie typów pokazuje pewną niespójność:

typeof undefined; // "undefined"
typeof null; // "object"

undefined ma swój własny typ prymitywny undefined. Z kolei null zwraca "object" — to historyczny błąd, którego nie naprawiono ze względu na kompatybilność.

W praktyce, aby sprawdzić undefined, użyj:

typeof value === 'undefined'

Natomiast, aby sprawdzić null, stosuj:

value === null

Dobre praktyki: kiedy używać undefined, a kiedy null?

Rekomendowany podział ról

undefined — zostaw je silnikowi JavaScript. Nie przypisuj undefined ręcznie (poza bardzo specyficznymi przypadkami). Traktuj je jako sygnał: „ta rzecz nie została jeszcze zainicjalizowana/przekazana/znaleziona”.

null — używaj świadomie w logice biznesowej, gdy chcesz zaznaczyć celowy brak wartości lub kiedy wartość powinna istnieć, ale „jeszcze nie” (np. przed załadowaniem danych) czy gdy czegoś nie znaleziono.

Przykładowy wzorzec w aplikacji webowej

Poniższy fragment pokazuje rozdzielenie stanów: brak danych, ładowanie, błąd:

// Stan widoku profilu użytkownika
let profile = null; // brak danych (jeszcze nie pobrane lub nie znaleziono)
let isLoading = false;
let error = null;

// Ładowanie danych
function loadProfile() {
isLoading = true;
error = null;
fetch('/api/profile')
.then(res => res.json())
.then(data => {
profile = data; // konkretny obiekt
})
.catch(err => {
error = err; // obiekt błędu
})
.finally(() => {
isLoading = false;
});
}

null oznacza: „na razie brak wartości/błędu, ale jest na nie miejsce”. undefined może pojawić się np. gdy backend nie przekaże jakiegoś pola w JSON — to sygnał, że w ogóle go nie określono.

Jak poprawnie sprawdzać null i undefined?

Sprawdzenie obu na raz

Gdy chcesz uznać null i undefined za równoważne „brak wartości”, możesz użyć luźnego porównania:

if (value == null) {
// value jest null LUB undefined
}

Alternatywnie skorzystaj z operatora „koalescencji nullish” ??:

const label = value ?? 'Domyślna wartość';

W tym wypadku label przyjmie domyślną wartość tylko wtedy, gdy value jest null lub undefined, ale nie wtedy, gdy jest np. pustym stringiem.

Sprawdzenie wyłącznie null

Gdy potrzebujesz wykryć dokładnie null (a nie undefined):

if (value === null) {
// dokładnie null, nie undefined
}

To przydatne, gdy undefined oznacza „systemowo: brak danych”, a null — „biznesowo: nie znaleziono, brak, usunięto”.

Sprawdzenie wyłącznie undefined

Gdy chcesz upewnić się, że wartość nie została w ogóle przekazana/zainicjalizowana:

if (typeof value === 'undefined') {
// wartość nie została zainicjalizowana lub argument nie został przekazany
}

To podejście jest odporne na ewentualne cienie zmiennych o nazwie undefined.

Typowe błędy z undefined i null (szczególnie w UI)

Wyświetlanie „undefined” lub „null” w interfejsie

Bez obróbki danych łatwo wstawić do DOM literalny tekst „undefined”/„null”:

const user = {};
const name = user.name; // undefined
document.querySelector('#name').textContent = `Użytkownik: ${name}`;
// W UI: "Użytkownik: undefined"

To częsty błąd. Zamiast tego użyj wartości zastępczej:

const name = user.name ?? 'Nieznany użytkownik';

W kontekście dostępności czytnik ekranu odczyta „undefined/null” dosłownie — lepiej dostarczyć sensowny tekst („Nieznany użytkownik”, „Brak danych”).

Operacje na undefined w obliczeniach

undefined w wyrażeniach arytmetycznych prowadzi do NaN, co może skutkować mylącymi wynikami w UI (np. „NaN zł”):

const price = undefined;
const tax = 0.23;
const total = price * (1 + tax); // NaN

Bezpieczniej ustalić domyślną liczbę:

const price = data.price ?? 0;

Destrukturyzacja z niepewnych źródeł

Destrukturyzacja z null/undefined kończy się błędem:

const user = null;
// const { name } = user;
// TypeError: Cannot destructure property 'name' of 'user' as it is null.

Dodaj zabezpieczenie lub domyślne wartości:

const user = null;
const { name = 'Anonim' } = user ?? {};

undefined i null a dostępność (a11y)

Różnica między tymi wartościami wpływa na to, co finalnie trafi do DOM i czytników ekranu.

Atrybuty ARIA i tekst alternatywny

Poniższy kod może wstawić do atrybutu literalne „undefined/null” — zależnie od środowiska:

const label = product.name; // może być undefined, null albo string
button.setAttribute('aria-label', label);

Bezpieczniejszym wzorcem jest ustawienie wartości zastępczej i ewentualne usunięcie atrybutu:

const label = product.name ?? 'Zobacz szczegóły produktu';
if (label) {
button.setAttribute('aria-label', label);
} else {
button.removeAttribute('aria-label');
}

Operator ?? chroni przed null/undefined, a dodatkowa walidacja zapobiega pustym atrybutom.

Renderowanie warunkowe treści

W nowoczesnych frameworkach (React, Vue, Svelte) często renderujesz warunkowo elementy UI:

{profile && }

null i undefined są „falsy”, więc powyższy fragment nie wyrenderuje się, jeśli profile ma którąś z tych wartości. Często jest to pożądane: null — profil nie istnieje (nie pokazujemy go); undefined — profil jeszcze się ładuje (pokazujemy loader).

Świadome modelowanie tych stanów pozwala unikać pustych sekcji i generować właściwe komunikaty dostępności (np. „Dane profilu są w trakcie ładowania”).

Formularze i komunikaty błędów

Stan pola formularza może przyjmować m.in. takie wartości:

  • undefined — jeszcze nie dotknięte przez użytkownika (nie wypełnione, nie odwiedzone),
  • null — świadomie wyczyszczone lub ustawione na „brak wyboru”,
  • '' — użytkownik wpisał i usunął wartość.

Dla dostępności tylko w niektórych stanach chcesz pokazywać błędy, a w innych — neutralne podpowiedzi. Jasne rozróżnienie undefined vs null ułatwia kontrolę tego, kiedy komunikaty mają być widoczne i anonsowane przez czytniki.

Praktyczne wskazówki do codziennej pracy

  1. Nie przypisuj ręcznie undefined, jeśli nie musisz. Pozwól, by undefined oznaczało „brak inicjalizacji” nadawany przez silnik JS.

  2. Używaj null, gdy chcesz mieć jawny, „biznesowy” brak wartości. Np. currentUser: null, error: null, selectedItem: null — intencja jest czytelna.

  3. Do wspólnego sprawdzenia „brak wartości” używaj value == null lub operatora ??. Traktują null i undefined jako „brak”, ale nie mieszają ich z pustym stringiem, 0 czy false.

  4. W UI filtruj dane, zanim trafią do DOM. Nie pozwalaj, by „undefined”, „null” czy NaN pojawiały się w treści elementów lub w atrybutach dostępności.

  5. Świadomie modeluj stany komponentów. Np. w SPA:

    • undefined — dane jeszcze nie pobrane,
    • null — dane pobrane, ale ich brak (np. nie znaleziono),
    • obiekt/wartość — dane dostępne.

Ćwiczenia dla ciebie

Aby utrwalić różnicę między undefined a null, wykonaj poniższe zadania:

  1. Napisz funkcję getUser(id), która:

    • zwraca obiekt użytkownika, jeśli go znajdzie,
    • zwraca null, jeśli użytkownik nie istnieje,
    • korzysta z undefined tylko tam, gdzie JavaScript robi to automatycznie (np. brak parametru).
  2. Zaimplementuj komponent (nawet w czystym JS), który:

    • pokazuje loader, gdy stan danych jest undefined,
    • pokazuje komunikat „Nie znaleziono danych”, gdy stan jest null,
    • pokazuje dane, gdy stanem jest obiekt.
  3. Dla strony z danymi z API przygotuj kontrolę jakości:

    — upewnij się, że żaden tekst w DOM nie zawiera dosłownie „undefined”, „null” ani NaN;

    — zadbaj, by atrybuty takie jak alt, aria-label, title miały sensowne wartości zastępcze, gdy dane z API są null lub undefined.

W praktyce undefined i null to dwa różne narzędzia — właściwie użyte, poprawiają czytelność kodu i dostępność twojej aplikacji.