Czy istnieje operator „nie w” w JavaScript do sprawdzania właściwości obiektu?

183

Czy w JavaScript istnieje operator „nie w”, który sprawdza, czy właściwość nie istnieje w obiekcie? Nie mogłem znaleźć nic na ten temat w Google ani w Stack Overflow. Oto mały fragment kodu, nad którym pracuję, w przypadku gdy potrzebuję tego rodzaju funkcji:

var tutorTimes = {};

$(checked).each(function(idx){
  id = $(this).attr('class');

  if(id in tutorTimes){}
  else{
    //Rest of my logic will go here
  }
});

Jak widać, zawarłbym wszystko w elseoświadczeniu. Wydaje mi się niewłaściwe tworzenie instrukcji if- elsetylko po to, aby użyć tej elseczęści.

Aaron
źródło
4
Myślę, że możesz chcieć var id = ...w swojej funkcji.
Cobby

Odpowiedzi:

338

Wydaje mi się, że niewłaściwe jest konfigurowanie instrukcji if / else tylko po to, aby użyć części else ...

Po prostu zaneguj swój stan, a otrzymasz elselogikę wewnątrz if:

if (!(id in tutorTimes)) { ... }
Jordão
źródło
11
Styl ten rozwiązuje również JSHint „kłopotliwe użycie«!»” Ostrzeżenie można dostać jeśli nie, jeśli( ! somekey in someobj )
mikemaccana
3
Zwróć uwagę, że podczas wyszukiwania nazwy właściwości w dowolnym miejscu łańcucha prototypów. Zobacz moją odpowiedź, aby uzyskać więcej informacji.
około
25
Rozumiem, że to obecnie najlepsze rozwiązanie, ale czy ktoś inny zgadza się, że to trochę brzydkie?
Jonah
3
Jeśli jest brzydki, po prostu zawiń go w funkcję i nadaj mu piękną nazwę 🙃let keyExists = (key, obj) => key in obj
Kamafeather
W pełni się zgadzam. Rzeczywiście, moje umiejętności nazywania też mogłyby się poprawić 😁. let hasProperty„wygląda” lepiej
Kamafeather
37

Jak już powiedział Jordão, po prostu zaneguj to:

if (!(id in tutorTimes)) { ... }

Uwaga: powyższy test, jeśli tutorTimes ma właściwość o nazwie określonej w id, w dowolnym miejscu łańcucha prototypów. Na przykład "valueOf" in tutorTimeszwraca wartość true, ponieważ jest zdefiniowana w Object.prototype .

Jeśli chcesz sprawdzić, czy właściwość nie istnieje w bieżącym obiekcie, użyj hasOwnProperty:

if (!tutorTimes.hasOwnProperty(id)) { ... }

Lub jeśli masz klucz, który maOwnPropery , możesz użyć tego:

if (!Object.prototype.hasOwnProperty.call(tutorTimes,id)) { ... }
trochę
źródło
Czy bezpieczniej jest zawinąć klucz w cudzysłów i używać go if(!tutorTimes.hasOwnProperty('id')) ...?
Majid Fouladpour
@MajidFouladpour idto zmienna, która może mieć dowolną wartość, 'id'jest łańcuchem z dwiema literami i i d , więc hasOwnProperty(id)sprawdza, czy właściwość określona w zmiennej id istnieje, i hasOwnProperty('id')sprawdza, czy istnieje właściwość o nazwie id.
jakiś
17

Osobiście uważam

if (id in tutorTimes === false) { ... }

łatwiejsze do odczytania niż

if (!(id in tutorTimes)) { ... }

ale oba będą działać.

Pasza
źródło
14

Dwie szybkie możliwości:

if(!('foo' in myObj)) { ... }

lub

if(myObj['foo'] === undefined) { ... }
reedlauber
źródło
5
Użyj 'undefined' === typeof xxxzamiast tego. undefinednie jest słowem zastrzeżonym i jest w rzeczywistości zmienną globalną, którą można nadpisać (co prowadzi do trudnych do znalezienia błędów)
hugomg
9
@hippietrail nie działa ... parens są wymagane po znaku „!” i wokół'foo' in myObj)
Phil Cooper
4
myObj['foo']może istnieć jako właściwość i po prostu zostać ustawiona na undefined(tj. za pomocą instrukcji myObj.foo = undefined). Jeśli naprawdę chcesz zobaczyć, czy właściwość sama w sobie nie istnieje, potrzebujesz !('foo' in myObj)notacji.
Richard Connamacher
Dla świadomych wydajności wśród nas, wyszukiwanie myObj.foo === undefinedjest znacznie szybsze (aczkolwiek potencjalnie niebezpieczne): jsperf.com/not-in-vs-is-undefined .
etpinard
@hugomg Nie sądzę, żeby to był dobry argument za nieużywaniem === undefined. Wiele rzeczy może się zepsuć, jeśli ludzie nadużywają języka programowania, robiąc takie rzeczy, jak na przykład nadpisywanie undefinedw JavaScript. Zobacz też: stackoverflow.com/questions/8783510/…
Zero3