JavaScript Możliwa iteracja ponad nieoczekiwaną


88

Mam następujący kod:

  for (i in awards) {
         if (awards[i] instanceof Array === false) {
               console.log(awards[i]);
                httpFactory.patch(awards[i], {"read": true}, false);
             }
       }

Moje IDE pokazuje ten błąd dotyczący powyższego kodu:

Możliwa iteracja w przypadku nieoczekiwanych (niestandardowych / dziedziczonych) elementów członkowskich, prawdopodobnie brak sprawdzenia właściwości hasOwnProperty

Sprawdza wszelkie wystąpienia niefiltrowanych pętli for-in w JavaScript. Użycie tej konstrukcji powoduje przetwarzanie odziedziczonych lub nieoczekiwanych właściwości. Musisz filtrować własne właściwości za pomocą metody hasOwnProperty (). Walidacja działa w plikach JavaScript, html lub jsp.

Czy mógłbyś bardziej szczegółowo wyjaśnić, co oznacza to stwierdzenie?


2
jQuery nie hasOwnPropertysprawdza - zastanawiam się, ile ostrzeżeń by wygenerowało ...
Alnitak

Odpowiedzi:


151

IDE zaleca dodanie testu:

if (awards.hasOwnProperty(i)) {
    ...
}

wewnątrz forpętli.

Osobiście radzę tego nie robić i wyłączać ostrzeżenie, jeśli to możliwe. Po prostu nie ma potrzeby w większości kodu, a jeszcze mniej w kodzie ES5, w którym można bezpiecznie dodawać niewliczalne właściwości do obiektu za pomocąObject.defineProperty

hasOwnPropertyWyboru jest konieczne tylko wtedy, gdy w sposób niebezpieczny (dodano nowe właściwości do przeliczalny) Object.prototype, więc najprostszym fix to nie rób tego .

jQuery nie wykonuje tego testu - wyraźnie dokumentują, że jQuery ulegnie Object.prototypeawarii, jeśli zostanie niezabezpieczona zmodyfikowana.


44
W IntelliJ 15, aby wyłączyć ostrzeżenie, wykonaj następujące czynności: Otwórz Preferencje -> Edytor -> Styl kodu -> Inspekcje. W polu wyszukiwania wpisz „hasOwnProperty”. Wyświetli się „Niefiltrowana pętla for..in”. Odznacz to pole. Kliknij przycisk OK, aby zaakceptować zmianę i zamknąć okno.
Machtyn

2
W IntelliJ: CTRL ALT S (chyba że używasz Ubuntu, który ma własny skrót CTRL ALT S) po prostu wyszukaj „hasOwnProperty”, a przejdziesz od razu do problemu, odznacz go i gotowe!
Olivier Pons,

2
W WebStorm przejdź do Plik ... Ustawienia, następnie Edytor -> Inspekcje -> „JavaScript i TypeScript” -> Ogólne i odznacz „Niefiltrowane pętle for..in”.
mightypile

@Machtyn Nie ma potrzeby przechodzenia do ustawień, aby wyłączyć to ostrzeżenie. W systemie Linux / Windows naciśnij Alt + Enter, gdy kursor znajduje się nad ostrzeżeniem, wybierz pierwszą opcję z menu kontekstowego, które się pojawi i wyłącz ustawienie w podmenu obok pierwszej opcji.
peterchaula

22

Każdy obiekt w javascript ma prototyp, który ma własne właściwości (metody / właściwości natywne / dziedziczone) oraz właściwości, które są bezpośrednio dołączone do samego obiektu.

Podczas iteracji po obiekcie, iteruje on właściwości samego obiektu i właściwości prototypu obiektu.

Dlatego, aby uniknąć iteracji po prototypie, zaleca się użycie metody hasOwnProperty , która zwraca wartość true tylko wtedy, gdy obiekt ma bezpośrednio wspomnianą właściwość. tj. nie wewnątrz prototypu

Przykład

for (var k in object) {
  if (object.hasOwnProperty(k)) {
     // do your computation here.
  }
}

Więcej szczegółów można znaleźć tutaj


15

Możesz także zmienić swoją pętlę na:

const keys = Object.keys(object);
for (const key of keys){
   // do something with object[key];
}

3

Możesz również pozbyć się ostrzeżenia, pisząc pętlę forEach, aby uzyskać bardziej czytelne i funkcjonalne podejście:

Object.keys(object).forEach(key => {
    // Do something with object[key]
});

-3

powinieneś dodać jeszcze jeden warunek na początku tej pętli

if (awards.hasOwnProperty(i)) 

15
Głosowałem na tę odpowiedź, więc myślę, że grzecznie jest, jeśli powiem dlaczego. Ta odpowiedź mówi, jak uniknąć ostrzeżenia, ale nie wyjaśnia, co oznacza ostrzeżenie, jak go unika ani co robi ten kod.
WoodenKitty,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.