Jak sprawdzić, czy obiekt ma określoną właściwość w JavaScript?
Rozważać:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
Czy to najlepszy sposób, aby to zrobić?
javascript
płaszcze
źródło
źródło
in
ihasOwnProperty
wyszło mi znacznie wolniej niż inne (98% wolniej). Nie jestem zaskoczonyhasOwnProperty
wolnością, ale jestem zaskoczonyin
.Odpowiedzi:
Naprawdę jestem zdezorientowany otrzymanymi odpowiedziami - większość z nich jest po prostu błędna. Oczywiście możesz mieć właściwości obiektu, które mają niezdefiniowane, zerowe lub fałszywe wartości. Po prostu zmniejszenie kontroli własności do
typeof this[property]
, a nawet gorzej,x.key
da całkowicie mylące wyniki.To zależy od tego, czego szukasz. Jeśli chcesz wiedzieć, czy obiekt fizycznie zawiera właściwość (i nie pochodzi ona skądś z łańcucha prototypów), to
object.hasOwnProperty
jest to właściwa droga. Wszystkie nowoczesne przeglądarki obsługują to. (Brakowało go w starszych wersjach Safari - 2.0.1 i starszych - ale te wersje przeglądarki są już rzadko używane).Jeśli szukasz tego, czy obiekt ma właściwość iterowalną (pojawi się iteracja po właściwościach obiektu), wówczas wykonanie:
prop in object
da pożądany efekt.Ponieważ używanie
hasOwnProperty
jest prawdopodobnie tym, czego chcesz, a biorąc pod uwagę, że możesz chcieć metody rezerwowej, przedstawiam ci następujące rozwiązanie:Powyższe jest działającym rozwiązaniem dla różnych przeglądarek
hasOwnProperty
z jednym zastrzeżeniem: nie jest w stanie rozróżnić przypadków, w których identyczna właściwość znajduje się w prototypie i instancji - po prostu zakłada, że pochodzi ona z prototypu. Możesz zmienić to na łagodniejsze lub bardziej surowe, w zależności od twojej sytuacji, ale przynajmniej powinno to być bardziej pomocne.źródło
var w = opts.w || 100;
. Ale jeśli masz coś w rodzaju biblioteki, być może będziesz musiał zajrzeć trochę dalej.__proto__
na zero? Prosty impl:function hasOwnProperty(obj, prop) { var temp = obj.__proto__; obj.__proto__ = null; var ret = prop in obj; obj.__proto__ = temp; return ret; }
(Case withobj.constructor.prototype
należy dodać).__proto__
jest niestandardowy i nie działa w niektórych starszych przeglądarkach. I nawet po ostatnim dodaniuObject.getPrototypeOf
standardu mówi, że nadal nie można zmienić prototypu istniejącego obiektu.for(prop in object)
Pętli iteracje właściwości tylko przeliczalnego.prop in object
Sprawdza jednak, czyobject
ma właściwośćprop
gdzieś w łańcuchu prototypowym, niezależnie od tego, czy jest ona wyliczalna, czy nie.Z
Underscore.js
lub ( jeszcze lepiej )lodash
:Które wywołania
Object.prototype.hasOwnProperty
, ale (a) jest krótszy do wpisania, a (b) używa „bezpiecznego odniesienia dohasOwnProperty
” (tzn. Działa, nawet jeślihasOwnProperty
zostanie zastąpione).W szczególności lodash definiuje się
_.has
jako:źródło
npm install lodash.has
moduł npm zhas
funkcją, która kompiluje do 175 bajtów po zminimalizowaniu. Warto również przyjrzećlodash.has/index.js
się, jak działa bardzo popularna i zaufana biblioteka.lodash
wersje działają z tym:.has(undefined, 'someKey') => false
podczasunderscore
powrotuundefined
lodash
jako „kolejnej” zależności: jest to dość powszechna (jeśli nie najczęstsza) biblioteka do tego rodzaju rzeczy. Miłej zabawy wymyślanie koła na nowo.Co powiesz na?
źródło
in
operatora, czy nie. Należy również pamiętać, żein
operator ma doskonałą obsługę przeglądarkiIE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+
stackoverflow.com/questions/2920765/…in
sprawdza również właściwości prototypu, ahasOwnProperty
iteruje tylko właściwości zdefiniowane przez użytkownika. Odniesienie: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…'key' in x
zrobić pracę z tablicami. Dowód: stackoverflow.com/questions/33592385/…Uwaga : poniższe opcje są obecnie w dużej mierze przestarzałe dzięki trybowi ścisłemu i
hasOwnProperty
. Poprawnym rozwiązaniem jest użycie trybu ścisłego i sprawdzenie obecności właściwości za pomocąobj.hasOwnProperty
. Ta odpowiedź poprzedza obie te rzeczy, przynajmniej jako szeroko zaimplementowane (tak, to jest tak stare). Weź pod uwagę następujące uwagi historyczne.Należy pamiętać, że
undefined
jest (niestety) nie słowem zarezerwowanym w JavaScript, jeśli nie jesteś w trybie ścisłym. Dlatego ktoś (oczywiście ktoś inny) może mieć świetny pomysł na redefiniowanie go, złamanie kodu.Bardziej niezawodna metoda jest zatem następująca:
Z drugiej strony ta metoda jest bardziej szczegółowa, a także wolniejsza. : - /
Częstą alternatywą jest upewnienie się, że
undefined
jest faktycznie niezdefiniowana, np. Poprzez wstawienie kodu do funkcji, która akceptuje dodatkowy parametr, zwanyundefined
, który nie przekazuje wartości. Aby upewnić się, że nie przekroczyła wartości, możesz po prostu nazwać ją od razu, np .:źródło
void 0
zdefiniowano, aby zwrócić kanonikęundefined
, czy można to zrobićx.attribute !== void 0
?(function (undefined) { // undefined is actually undefined here })();
Wydaje się, że Armin Ronacher już mnie pobił , ale:
Bezpieczniejsze, ale wolniejsze rozwiązanie, jak wskazano przez Konrad Rudolph i Armin Ronacher będzie:
źródło
x.hasOwnProperty('toString') === true;
Object.prototype
już ma wbudowane, poprawnehasOwnProperty
. Zastąpienie go niepoprawną implementacją (1. Właściwości mogą mieć wartośćundefined
, 2. To da fałszywe alarmy dla odziedziczonych właściwości) to po prostu strasznie zły pomysł. Niepoprawne odpowiedzi można i należy usunąć. Nie wiem, czy mógłbyś to zrobić we wrześniu '08, kiedy zobaczyłeś odpowiedź Resiga , więc komentuj, by zasugerować, by zrobić to teraz.Za pomocą
in
operatora można sprawdzić, czy właściwość istnieje na obiekcie:Możesz również wykonać pętlę przez wszystkie właściwości obiektu za pomocą
for - in
pętli, a następnie sprawdzić określoną właściwość:Należy rozważyć, czy ta właściwość obiektu jest policzalna, czy nie, ponieważ właściwości niepoliczalne nie pojawią się w
for-in
pętli. Ponadto, jeśli właściwość wyliczalna przesłania właściwość prototypu, której nie można wyliczyć, nie pojawi się w programie Internet Explorer 8 i wcześniejszych wersjach.Jeśli chcesz wyświetlić listę wszystkich właściwości instancji, niezależnie od tego, czy są one wyliczalne, czy nie, możesz użyć
Zwróci tablicę nazw wszystkich właściwości istniejących na obiekcie.
Na koniec możesz użyć operatora typeof, aby bezpośrednio sprawdzić typ danych właściwości obiektu:
Jeśli właściwość nie istnieje na obiekcie, zwróci ciąg niezdefiniowany. W przeciwnym razie zwróci odpowiedni typ właściwości. Należy jednak pamiętać, że nie zawsze jest to prawidłowy sposób sprawdzania, czy obiekt ma właściwość, czy nie, ponieważ można mieć właściwość ustawioną na wartość niezdefiniowaną, w którym to przypadku użycie
typeof x.key
nadal zwróciłoby wartość true (nawet jeśli klucz jest nadal w obiekcie).Aktualizacja: możesz sprawdzić, czy właściwość istnieje, porównując ją z niezdefiniowaną właściwością javascript
Powinno to działać, chyba że klucz został specjalnie ustawiony
undefined
na obiekcie xźródło
Przejdźmy przez to zamieszanie. Po pierwsze, uprośćmy, zakładając, że
hasOwnProperty
już istnieje; dotyczy to zdecydowanej większości obecnie używanych przeglądarek.hasOwnProperty
zwraca true, jeśli przekazana do niego nazwa atrybutu została dodana do obiektu. Jest całkowicie niezależny od faktycznie przypisanej wartości, która może być dokładnieundefined
.W związku z tym:
Jednak:
Problem polega na tym, co dzieje się, gdy obiekt w łańcuchu prototypów ma atrybut o wartości niezdefiniowanej?
hasOwnProperty
będzie dla niego fałszywa i tak też będzie!== undefined
. Jednakfor..in
nadal będzie to wymieniać w wyliczeniu.Najważniejsze jest to, że nie ma sposobu na przeglądarkę (ponieważ Internet Explorer nie ujawnia
__prototype__
), aby ustalić, że określony identyfikator nie został dołączony do obiektu lub czegokolwiek w jego łańcuchu prototypów.źródło
Jeśli szukasz nieruchomości, wybierz „NIE”. Chcesz:
Zasadniczo nie należy się przejmować, czy właściwość pochodzi od prototypu czy obiektu.
Ponieważ jednak użyłeś „klucza” w przykładowym kodzie, wygląda na to, że traktujesz obiekt jako skrót, w którym to przypadku Twoja odpowiedź miałaby sens. Wszystkie klucze skrótu byłyby właściwościami w obiekcie, a unikasz dodatkowych właściwości prototypu.
Odpowiedź Johna Resiga była bardzo wyczerpująca, ale myślałem, że nie była jasna. Zwłaszcza kiedy należy użyć „prop” w obj.
źródło
in
operator ma doskonałą obsługę przeglądarkiIE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+
stackoverflow.com/questions/2920765/…in
operatora: „działa z„ obiektami ”w wąskim znaczeniu, tak zadeklarowanym jako {} lub utworzonym za pomocą konstruktora, nie akceptuje tablic ani prymitywów. niektóre inne odpowiedzi przedstawiają techniki, które są szersze (praca z tablicami, łańcuchami itp.) ”Do testowania prostych obiektów użyj:
if (obj[x] !== undefined)
Jeśli nie wiesz, jaki typ obiektu jest używany, użyj:
if (obj.hasOwnProperty(x))
Wszystkie inne opcje są wolniejsze ..
Detale
Ocena wydajności 100 000 000 cykli w ramach Nodejsa do 5 opcji sugerowanych przez innych tutaj:
Ocena mówi nam, że jeśli nie chcemy konkretnie sprawdzić łańcucha prototypowego obiektu, a także samego obiektu, nie powinniśmy używać wspólnej formy:
if (X in Obj)...
jest on od 2 do 6 razy wolniejszy w zależności od przypadku użyciaPodsumowując, jeśli Twój Obj niekoniecznie jest prostym obiektem i chcesz uniknąć sprawdzania łańcucha prototypowego obiektu i upewnić się, że x jest własnością Obj bezpośrednio, użyj „if (obj.hasOwnProperty (x)) ...”.
W przeciwnym razie, gdy używasz prostego obiektu i nie martwisz się łańcuchem prototypowym obiektu, używanie
if (typeof(obj[x]) !== 'undefined')...
jest najbezpieczniejszym i najszybszym sposobem.Jeśli użyjesz prostego obiektu jako tabeli mieszającej i nigdy nie zrobisz nic dziwnego, użyłbym tego,
if (obj[x])...
ponieważ uważam, że jest on dużo bardziej czytelny.Baw się dobrze.
źródło
Tak to jest :) Myślę, że możesz też zrobić,
Object.prototype.hasOwnProperty.call(x, 'key')
co powinno również działać, jeślix
ma właściwość o nazwiehasOwnProperty
:)Ale to sprawdza własne właściwości. Jeśli chcesz sprawdzić, czy ma właściwość, która może być powiązana, możesz użyć
typeof x.foo != 'undefined'
.źródło
Ponieważ
kończy się niepowodzeniem, jeśli
x.key
rozwiązujefalse
(na przykładx.key = ""
).źródło
const x = {key: undefined};
który zwróci false z tym rozwiązaniem, podczas gdyx.hasOwnProperty('key')); // true
iReflect.has(x, 'key')); // true
. Właściwość faktycznie istnieje, ale jej wartość toundefined
.Możesz także użyć obiektu ES6
Reflect
:Dokumentację dotyczącą MDN dla
Reflect.has
można znaleźć tutaj .źródło
OK, wygląda na to, że mam właściwą odpowiedź, chyba że nie chcesz dziedziczonych właściwości:
Oto kilka innych opcji dołączania odziedziczonych właściwości:
źródło
var x = { key: false };
tejx.key
metody byłoby błędne.Nie rób tego
object.hasOwnProperty(key))
, to naprawdę złe, ponieważ metody te mogą być zaciemnione przez właściwości obiektu, o którym mowa - rozważ{ hasOwnProperty: false }
- lub obiekt może być obiektem zerowym(Object.create(null))
.Najlepszym sposobem jest zrobienie
Object.prototype.hasOwnProperty.call(object, key)
lub:źródło
Innym stosunkowo prostym sposobem jest użycie
Object.keys
. Zwraca to,array
co oznacza, że masz wszystkie funkcje tablicy.Chociaż jesteśmy w świecie z doskonałą obsługą przeglądarki. Ponieważ to pytanie jest tak stare, pomyślałem, że dodam to: Można go bezpiecznie używać od wersji JS 1.8.5
źródło
Object.keys(info).indexOf('someotherthing') !== -1
hasOwnProperty "można wykorzystać do ustalenia, czy obiekt ma określoną właściwość jako bezpośrednią właściwość tego obiektu; w przeciwieństwie do operatora in , ta metoda nie sprawdza łańcucha prototypów obiektu."
Więc najprawdopodobniej za to, co wydaje się przez swoje pytanie, nie chcesz używać hasOwnProperty, który określa, czy właściwość istnieje jako przyłączone bezpośrednio do samego obiektu ,.
Jeśli chcesz ustalić, czy właściwość istnieje w łańcuchu prototypów, w którym chcesz używać, na przykład:
Mam nadzieję, że to pomoże.
źródło
Z ryzykiem masowego głosowania w dół, jest inna opcja dla konkretnego przypadku. :)
Jeśli chcesz przetestować członka na obiekcie i chcesz wiedzieć, czy został ustawiony na coś innego niż:
wtedy możesz użyć:
źródło
Rozwiązanie ECMA Script 6 z odbiciem. Utwórz opakowanie takie jak:
źródło
Istnieje metoda „hasOwnProperty” istnieje na obiekcie, ale nie zaleca się bezpośredniego wywoływania tej metody, ponieważ czasami obiekt może mieć wartość NULL lub niektóre właściwości istnieją na obiekcie, takie jak:
{ hasOwnProperty: false }
Lepszym sposobem byłoby:
źródło
Możesz użyć następujących metod:
Różnice między następującymi podejściami są następujące:
źródło
Musisz użyć tej metody
object.hasOwnProperty(property)
. Zwraca true, jeśli obiekt ma właściwość, i false, jeśli obiekt nie.źródło
Jeśli sprawdzany klucz jest przechowywany w zmiennej , możesz to sprawdzić w następujący sposób:
źródło
Po co nadmiernie komplikować rzeczy, kiedy możesz to zrobić:
Prosty i przejrzysty w większości przypadków ...
źródło
const objectName = { keyname: false };
, powinien zwrócić wartość true, ponieważkeyname
jest to właściwośćobjectname
. Ale ponieważ wartość jest fałszywa, przy tej logice zwróci wartość false.