JavaScript Posible iteración sobre inesperada

83

Tengo el siguiente código:

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

Mi IDE muestra este error relacionado con el código anterior:

Posible iteración sobre miembros inesperados (personalizados / heredados), probablemente falte la verificación hasOwnProperty

Comprueba si hay instancias de bucles for-in sin filtrar en JavaScript. El uso de esta construcción da como resultado el procesamiento de propiedades heredadas o inesperadas. Necesita filtrar sus propias propiedades con el método hasOwnProperty (). La validación funciona en archivos JavaScript, html o jsp.

¿Podría explicar con más detalle qué se entiende por esta afirmación?

Prometeo
fuente
2
jQuery no realiza hasOwnPropertycomprobaciones, me pregunto cuántas advertencias produciría ...
Alnitak

Respuestas:

145

El IDE recomienda que agregue una prueba:

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

dentro del forbucle.

Personalmente, recomiendo no hacer esto y deshabilitar la advertencia si es posible. Simplemente no hay necesidad en la mayoría del código, y aún menos en el código ES5, donde puede agregar de forma segura propiedades no enumerables a un objeto usandoObject.defineProperty

La hasOwnPropertyverificación solo es necesaria si ha agregado nuevas propiedades (enumerables) de Object.prototypemanera insegura , por lo que la solución más simple es no hacer eso .

jQuery no realiza esta prueba: documentan explícitamente que jQuery se romperá si Object.prototypese modifica de manera insegura.

Alnitak
fuente
41
En IntelliJ 15, para deshabilitar la advertencia, realice lo siguiente: Abra Preferencias -> Editor -> Estilo de código -> Inspecciones. En el cuadro de búsqueda, ingrese "hasOwnProperty". Aparecerá "Sin filtrar para ... en bucle". Desmarque esa casilla. Haga clic en el botón Aceptar para aceptar el cambio y cerrar la ventana.
Machtyn
2
En IntelliJ: CTRL ALT S (a menos que esté usando Ubuntu que tiene su propio atajo CTRL ALT S) simplemente busque "hasOwnProperty" y llegará directamente al problema, desmárquelo y listo.
Olivier Pons
1
En WebStorm, vaya a Archivo ... Configuración, luego Editor -> Inspecciones -> "JavaScript y TypeScript" -> General, y desmarque "Sin filtrar para ... en bucle".
mightypile
21

Cada objeto en javascript tiene un prototipo que tiene sus propias propiedades (métodos / propiedades nativos / heredados) y propiedades que están directamente asociadas al objeto en sí.

Cuando itera sobre un objeto, iterará las propiedades del propio objeto y las propiedades del prototipo del objeto.

Por lo tanto, para evitar iterar sobre el prototipo, se recomienda usar el método hasOwnProperty que devuelve verdadero solo cuando el objeto tiene la propiedad mencionada directamente. es decir, no dentro del prototipo

Ejemplo

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

Puede encontrar más detalles aquí

Selvaraj MA
fuente
13

También puede refactorizar su bucle en:

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

También puede deshacerse de la advertencia escribiendo un bucle forEach para un enfoque más legible y funcional:

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

deberías agregar una condición más al comienzo de este ciclo

if (awards.hasOwnProperty(i)) 
bmazurek
fuente
13
He votado en contra de esta respuesta, así que creo que es de buena educación si digo por qué. Esta respuesta dice cómo evitar la advertencia, pero no explica qué significa la advertencia, cómo la evita o qué hace este código.
WoodenKitty