¿Cómo excluir los métodos agregados a la matriz del procesamiento en el bucle “for..in”? (javascript)

StackOverflow https://stackoverflow.com/questions/1809505

  •  05-07-2019
  •  | 
  •  

Pregunta

He agregado algunos ayudantes útiles a Array (como toSource () para Opera). Y ahora for..in devuelve las funciones con propiedades normales.

Estoy usando for..in ahora, porque el código es más fácil de leer con él. Y es un funcional nativo de js, por lo que debe ser más rápido.

Pero agregar controles de tipo en bucle facilita el uso del clásico para (;;) .

¿Hay algún método para evitar for..in enumerar funciones?

El trabajo entre navegadores no es muy necesario (debe funcionar en Opera), pero la velocidad es importante.

Gracias.


Editar:
¿Existe alguna capacidad para evitar for..in enumerar funciones o propiedades personalizadas de cualquier objeto?

¿Fue útil?

Solución

Debería nunca usar para ... en bucles para iterar sobre elementos de matriz. for..in está diseñado para iterar sobre propiedades , y solo debe usarse para eso, exactamente por la razón que acaba de describir. Muchas bibliotecas modifican los prototipos de matriz, fecha, etc., por lo que no debe confiar en for ... in iterar solo los elementos de la matriz. Utilice el método for (;;), está garantizado para hacer lo que quiera. Y no es más rápido que un for ... in loop, porque también es nativo de JavaScript.

Para obtener más información, lea sobre esto en la biblioteca prototype.js

.

Otros consejos

Sí, pero es JavaScript 1.7+, solo. Opera solo tiene un soporte limitado de JavaScript 1.7, que incluye un soporte muy básico para la desestructuración de tareas, por lo que no funcionará en Opera, pero funcionará en Firefox.

Esta implementación permite el uso seguro de para [cada] (elemento en matriz) :

Array.prototype.__iterator__ = function (flag) {
    var len = this.length, i = 0;

    for (; i < len; i++) {
        yield flag ? i : this[i];
    }
};

Como indicaron otros, NO debe usar for..in para iterar sobre matrices. Es más lento que usar a para (;;).

También debe almacenar en caché la longitud de la matriz si está preocupado por el rendimiento, como:

for (var i=0, len=arr.length; i<len; i++) 
{
  ... 
}

Utilice solo para ... in para iterar sobre las propiedades de los objetos. Para excluir las propiedades heredadas, use el método hasOwnProperty ():

for (var prop in object)
{
  // Don't include properties inherited from the prototype chain
  if (object.hasOwnProperty(prop))
  {
    ...
  }
}

Hay otra opción ahora con soporte para ES5, ¡te permite definir propiedades no enumerables! Debería ser posible (aunque no haya probado) hacer algo como esto:

Object.defineProperty( Array.prototype, "myNewMethod", {
   value: function(){},
   writable: true,
   enumerable: false, /* this controls for..in visibility */
   configurable: true
});

Lo que estás describiendo es exactamente por qué lo usas

for (var i=0; i<arr.length; i++) { ... }

en lugar de:

for (var item in arr) { ... }

porque son diferentes.

Si no quieres todos los miembros que obtendrás en el segundo formulario y solo los elementos indexados, utiliza el primer formulario.

Editar: corrigió el tipo de uso incorrecto gracias al comentario de @Bergi

buen punto sobre el rendimiento al iterar sobre arrays (muy) dispersos: sugeriría que tal vez usar isNaN (parseInt ()) en el bucle le permita encontrar solo elementos del array:

for( var propertyName in myArray){
    if( !isNaN(parseInt(propertyName)) ){ /* probably array element */ }
}

No sé cuál es el mejor rendimiento de hasOwnProperty () y el enfoque anterior. Simplemente tienes que medir esto con una gran variedad de iteraciones 10000 veces o algo así. Si realiza algunas mediciones de rendimiento, los resultados serían interesantes, así que ¡compártelos! :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top