hasOwnProperty w JS – jak sprawdzić własność obiektu?

Diagram pokazuje, jak `hasownproperty` w JS pozwala na dostęp do właściwości obiektu. Górny przykład pokazuje przypisanie imienia, dolny - zmianę.

Napisano przez

Jacek Zając

Opublikowano

8 mar 2026

Spis treści

Sprawdzanie, czy obiekt ma konkretną właściwość, brzmi jak drobiazg, ale w JavaScript potrafi zmienić zachowanie walidacji, pętli i logiki konfiguracji. Najczęściej trzeba odróżnić pole własne od odziedziczonego, bo te dwie rzeczy nie zachowują się tak samo. W tym tekście pokazuję, jak działa hasOwnProperty, kiedy lepiej sięgnąć po Object.hasOwn i gdzie proste in albo sprawdzenie wartości prowadzi na manowce.

Najkrótsza droga to sprawdzanie własnych pól bez mylenia ich z prototypem

  • Object.hasOwn(obj, key) to dziś najczytelniejszy sposób sprawdzania własnej właściwości obiektu.
  • obj.hasOwnProperty(key) działa, ale bywa zawodne przy obiektach bez prototypu albo danych, które nadpisują tę metodę.
  • in sprawdza także właściwości odziedziczone, więc nie rozwiązuje tego samego problemu.
  • Samo obj[key] !== undefined nie odróżnia braku pola od pola z wartością undefined.
  • W starszym kodzie bezpiecznym fallbackiem jest Object.prototype.hasOwnProperty.call(obj, key).

Co naprawdę sprawdza metoda hasOwnProperty

Własna właściwość to taka, która należy bezpośrednio do obiektu, a nie przyszła do niego z prototypu. To ważne rozróżnienie, bo JavaScript bardzo chętnie dziedziczy zachowanie z łańcucha prototypów, czyli z kolejnych obiektów stojących „nad” bieżącym obiektem.

Ja myślę o tym tak: jeśli pole opisuje konkretny rekord, konfigurację albo odpowiedź z API, zwykle chcę, żeby było własne. Jeśli coś ma być współdzielone przez wiele obiektów, wtedy sensowniejszy jest prototyp. Z punktu widzenia kodu oznacza to jedno: istnienie pola i wartość pola to dwie różne rzeczy.

W praktyce własna właściwość nadal „istnieje”, nawet jeśli ma wartość null albo undefined. To właśnie dlatego sprawdzanie typu if (obj[key]) bywa mylące. Taki warunek testuje prawdziwość wartości, a nie sam fakt, czy pole zostało zapisane. Za chwilę pokażę to na prostych przykładach, bo tam różnica widać najlepiej.

Diagram pokazuje dziedziczenie klas w JS. Klasa CAR (rodzic) ma atrybut

Jak odróżnić własną właściwość od dziedziczonej

Łańcuch prototypów, czyli mechanizm dziedziczenia w JavaScript, sprawia, że obiekt może „widzieć” właściwości, których sam nie przechowuje. To dlatego jedna metoda zwraca true, a druga false, mimo że na pierwszy rzut oka patrzą na ten sam klucz.

const parent = { inherited: true };
const child = Object.create(parent);

child.own = 1;

Object.hasOwn(child, "own");        // true
Object.hasOwn(child, "inherited");  // false
"inherited" in child;               // true

W tym przykładzie own jest zapisana bezpośrednio w child, a inherited pochodzi z parent. To jest dokładnie ten moment, w którym hasOwnProperty i Object.hasOwn pokazują własność własną, a operator in patrzy szerzej i obejmuje także prototyp.

Warto też pamiętać o obiektach tworzonych przez Object.create(null). One nie mają prototypu, więc nie posiadają również metody hasOwnProperty. Jeśli ktoś próbował kiedyś wywołać ją bezpośrednio na takim obiekcie i dostał błąd, to właśnie stąd brał się problem. Stąd już tylko krok do pytania, której metody używać na co dzień.

Której metody używać dziś

Metoda Sprawdza własne pola Sprawdza prototyp Bezpieczna dla Object.create(null) Kiedy ma sens
Object.hasOwn(obj, key) Tak Nie Tak Domyślny wybór w nowym kodzie
obj.hasOwnProperty(key) Tak Nie Nie Gdy masz pełną kontrolę nad obiektem i środowiskiem
Object.prototype.hasOwnProperty.call(obj, key) Tak Nie Tak Bezpieczny fallback dla starszego kodu
key in obj Tak Tak Tak Gdy interesuje Cię także prototyp
obj[key] !== undefined Niepewnie Niepewnie Niepewnie Raczej nie jako test istnienia pola

Jeśli pisałbym jedną regułę do zapamiętania, byłaby prosta: w nowym kodzie używaj Object.hasOwn. To rozwiązanie jest krótsze, czytelne i nie wymaga opierania się o metodę istniejącą na samym obiekcie. Gdy muszę utrzymać starszy kod albo wspieram środowisko, w którym nie chcę zakładać dostępności nowszego API, sięgam po Object.prototype.hasOwnProperty.call. Operator in zostawiam na sytuacje, w których prototyp naprawdę ma znaczenie, a nie jako zamiennik dla sprawdzania własności.

Ta różnica może wyglądać kosmetycznie, ale w praktyce eliminuje sporo błędów w pracy z danymi i iteracją. Następna sekcja pokazuje, gdzie te wybory mają największy sens w realnym kodzie.

Przykłady z kodu, które przydają się w praktyce

Walidacja danych z API

Przy danych z backendu często interesuje mnie nie tylko to, czy pole ma jakąś wartość, ale czy w ogóle zostało wysłane. To ważne szczególnie wtedy, gdy API rozróżnia między „pole nie istnieje” a „pole istnieje, ale ma wartość pustą albo null”.

const user = response.user;

if (Object.hasOwn(user, "middleName")) {
  renderMiddleName(user.middleName);
}

To zachowanie ma znaczenie, gdy backend świadomie wysyła null jako informację typu „brak drugiego imienia”, zamiast po prostu pominąć pole. Wtedy sam test wartości nie wystarczy, bo zgubiłbyś intencję danych.

Wartości domyślne w konfiguracji

Konfiguracja to drugi klasyczny przypadek. Jeśli użytkownik ustawi 0, false albo pusty string, to nadal może być poprawna wartość. Warunek oparty wyłącznie na prawdzie logicznej łatwo zamieni taki wpis na domyślny fallback, choć nie powinien.

function getTimeout(config) {
  return Object.hasOwn(config, "timeout") ? config.timeout : 5000;
}

Tu różnica jest bardzo konkretna: timeout: 0 oznacza „nie czekaj”, a nie „użyj domyślnej wartości”. Dzięki sprawdzeniu własności nie mylisz ustawienia świadomego z brakiem ustawienia.

Przeczytaj również: Pętla while w JavaScript - Jak używać i unikać błędów?

Filtrowanie przy for...in

Pętla for...in przechodzi po właściwościach enumerowalnych, ale obejmuje również te odziedziczone. Jeśli obiekt nie jest „czysty” albo korzystasz z klas i prototypów, dobrze jest odfiltrować tylko własne klucze.

for (const key in settings) {
  if (!Object.hasOwn(settings, key)) continue;
  console.log(key, settings[key]);
}

Jeżeli zależy Ci wyłącznie na własnych, enumerowalnych kluczach, często jeszcze prościej działa Object.keys(settings). Wtedy filtr dostajesz za darmo, bez ręcznego warunku. Z takiego rozróżnienia płynnie wynika kolejna rzecz: najczęstsze błędy zwykle nie są spektakularne, tylko po cichu zniekształcają wynik.

Najczęstsze błędy, które dają fałszywy wynik

  • Sprawdzanie wartości zamiast obecności - if (obj[key]) odrzuci poprawne wartości takie jak 0, false albo "".
  • Zakładanie, że undefined oznacza brak pola - własność może istnieć i jednocześnie mieć wartość undefined.
  • Bezpośrednie wywołanie obj.hasOwnProperty - obiekt może nie mieć tej metody albo może ją nadpisywać własnym polem.
  • Mylenie in z testem własnego pola - in widzi też prototyp, więc odpowiada na inne pytanie.
  • Ręczna iteracja bez filtra - for...in bez sprawdzania własności łatwo przepuszcza dziedziczone, enumerowalne klucze.

Najbardziej zdradliwy przypadek widzę wtedy, gdy obiekt z danych wejściowych sam ma pole o nazwie hasOwnProperty. Wystarczy, że ktoś zapisze je jako zwykłą wartość i bezpośrednie wywołanie przestaje działać tak, jak zakładał autor kodu:

const payload = {
  hasOwnProperty: true,
  name: "Ala"
};

payload.hasOwnProperty("name"); // TypeError
Object.hasOwn(payload, "name");  // true

To dobry przykład, dlaczego bezpieczniej nie opierać się na metodzie pobranej z samego obiektu, gdy dane mogą przyjść z zewnątrz. W praktyce wystarczy jeden taki przypadek, żeby zaczęło być jasne, czemu nowsze API zostało przyjęte tak szybko. Z tego miejsca naturalnie przechodzę do wyboru, który naprawdę polecam w nowych projektach.

Co wybrać w nowym projekcie i kiedy potrzebujesz czegoś więcej

Jeśli piszę nowy kod, wybór jest prosty: Object.hasOwn do sprawdzania własnej właściwości, in tylko wtedy, gdy interesuje mnie także prototyp, a Object.prototype.hasOwnProperty.call jako bezpieczny wariant w starszych fragmentach projektu. Taki podział jest czytelny i od razu pokazuje intencję kodu.

Warto też pamiętać, że samo sprawdzenie własności nie zastępuje walidacji danych. Jeśli obiekt przychodzi z formularza, API albo pliku konfiguracyjnego, nadal trzeba sprawdzić typ, zakres i sens wartości. Gdy struktura jest bardziej złożona, lepiej działa walidacja schematu niż dokładanie kolejnych warunków w stylu „czy pole istnieje”. A jeśli tak naprawdę budujesz słownik klucz-wartość, a nie klasyczny obiekt, często wygodniejszy bywa Map z metodą has().

Jeżeli potrzebujesz nie tylko samej obecności pola, ale też informacji o jego cechach, sięgnij po Object.getOwnPropertyDescriptor. Dzięki temu zobaczysz nie tylko, że właściwość istnieje, ale też czy jest enumerowalna, zapisywalna albo konfigurowalna. Najlepszy nawyk jest prosty: najpierw sprawdzaj własność, dopiero potem interpretuj wartość. To zwykle wystarcza, żeby kod był odporny na undefined, null i odziedziczone właściwości.

FAQ - Najczęstsze pytania

Object.hasOwn() to nowsza, bezpieczniejsza metoda sprawdzania własnych właściwości obiektu. Działa poprawnie nawet na obiektach stworzonych przez Object.create(null) i gdy właściwość o nazwie "hasOwnProperty" została nadpisana. hasOwnProperty() to metoda instancji, która może zawieść w tych specyficznych przypadkach.

Operator in służy do sprawdzania, czy właściwość istnieje w obiekcie lub w jego łańcuchu prototypów. Używaj go, gdy interesuje Cię zarówno własna właściwość, jak i ta dziedziczona. Nie jest to zamiennik dla metod sprawdzających wyłącznie własne pola.

Sprawdzenie obj[key] !== undefined testuje wartość, a nie sam fakt istnienia pola. Właściwość może istnieć i mieć przypisaną wartość undefined (np. obj = { a: undefined }). Taki warunek nie odróżni braku pola od pola z wartością undefined, co może prowadzić do błędów logicznych.

W nowych projektach zdecydowanie rekomenduje się używanie Object.hasOwn(obj, key). Jest to najbardziej czytelne, bezpieczne i odporne na potencjalne problemy związane z nadpisywaniem metod prototypowych lub obiektami bez prototypu. Zapewnia precyzyjne sprawdzenie, czy właściwość należy bezpośrednio do obiektu.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0

Tagi:

hasownproperty js hasownproperty vs object.hasown sprawdzanie własności obiektu javascript

Udostępnij artykuł

Jacek Zając

Jacek Zając

Nazywam się Jacek Zając i od dziewięciu lat zajmuję się programowaniem webowym. Moja przygoda z tą dziedziną zaczęła się od fascynacji tworzeniem stron internetowych, co szybko przerodziło się w pasję do nauczania innych. Lubię dzielić się wiedzą i pomagać osobom, które stawiają pierwsze kroki w programowaniu. Skupiam się na wyjaśnianiu złożonych zagadnień w przystępny sposób, aby każdy mógł zrozumieć podstawy i rozwijać swoje umiejętności. W moich artykułach poruszam różnorodne tematy związane z programowaniem webowym, od HTML i CSS po JavaScript i frameworki. Dokładam wszelkich starań, aby informacje, które prezentuję, były rzetelne, aktualne i łatwe do przyswojenia. Regularnie śledzę nowinki w branży, co pozwala mi na dostarczanie czytelnikom treści zgodnych z najnowszymi trendami. Wierzę, że dobrze zorganizowana wiedza to klucz do sukcesu w karierze programisty.

Napisz komentarz