2012-05-24 27 views
11

leo en Javascript: las partes buenas ...JQuery y Underscore "cada" orden de garantía para una matriz?

Desde matrices de JavaScript son realmente objetos, la declaración for in se puede utilizar para iterar sobre todas las propiedades de una matriz. Por desgracia, en no ofrece ninguna garantía sobre el orden de las propiedades ...

Por lo que yo sé los "cada uno" funciones se basan en for in, luego hace each forma de función jQuery y bibliotecas Guión garantizar el orden cuando iterar sobre una matriz? Estoy tratando de evitar el molesto estándar for.

Gracias de antemano.

+1

Asegúrate de tener claro qué es una matriz y qué objeto hay en JavaScript ... – Pointy

Respuesta

16

Al iterar a través de una matriz, el orden siempre está garantizado. Es cuando itera a través de objetos (que no son de matriz) cuando no hay garantía. Las matrices siguen siendo objetos por cierto.


each no es más que un for in para los objetos, y for para array-similares. el marco determina el ciclo correcto para el trabajo y se aplica la misma lógica: las iteraciones de matrices son ordenadas mientras que la iteración de objetos no.

fuente de Subrayado:

var each = _.each = _.forEach = function (obj, iterator, context) { 
     if (obj == null) return; 
     if (nativeForEach && obj.forEach === nativeForEach) { 
      obj.forEach(iterator, context); 
     } else if (obj.length === +obj.length) { 
      for (var i = 0, l = obj.length; i < l; i++) { 
       if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return; 
      } 
     } else { 
      for (var key in obj) { 
       if (_.has(obj, key)) { 
        if (iterator.call(context, obj[key], key, obj) === breaker) return; 
       } 
      } 
     } 
    }; 

fuente de jQuery:

each: function (object, callback, args) { 
    var name, i = 0, 
     length = object.length, 
     isObj = length === undefined || jQuery.isFunction(object); 
    if (args) { 
     if (isObj) { 
      for (name in object) { 
       if (callback.apply(object[name], args) === false) { 
        break; 
       } 
      } 
     } else { 
      for (; i < length;) { 
       if (callback.apply(object[i++], args) === false) { 
        break; 
       } 
      } 
     } 
     // A special, fast, case for the most common use of each 
    } else { 
     if (isObj) { 
      for (name in object) { 
       if (callback.call(object[name], name, object[name]) === false) { 
        break; 
       } 
      } 
     } else { 
      for (; i < length;) { 
       if (callback.call(object[i], i, object[i++]) === false) { 
        break; 
       } 
      } 
     } 
    } 
    return object; 
} 
+0

Edité la pregunta porque creo que no estaba clara. Me preocupan más las funciones que el problema de objetos/matrices. – davidgnin

+0

@davidgnin cada uno no es más que 'for' y' for in' loops. Se aplica la misma lógica. – Joseph

+0

¡Gracias! Luego, en las matrices, cada una es para, no para adentro. Eso era exactamente lo que intentaba saber. – davidgnin

3

Hay dos formas en las que puede recorrer más de una matriz: un bucle numérica sobre los elementos indexados de una matriz o una for in iteración sobre las propiedades de objeto de una matriz.

var a = ['a','b']; 
a[3] = 'e'; 
a[2] = 'd'; 
a.foo = function() { }; 
for(key in a) 
    console.log(key); 

Esto devuelve 0 1 3 2 foo, ya que ese es el orden de las propiedades fueron definidos (pero no hay promesa de que su navegador siquiera necesita exhibir un comportamiento que, tampoco).

Hasta el momento, los bucles numéricos se ven superiores, pero no pueden manejar matrices de repuesto, es decir, matrices con espacios. El ES5 Array.forEach omite valores no especificados, mientras que jQuery's $.each utiliza un bucle numérico basado en la propiedad length.

var a = [1,2]; 
a[1000000] = 4; 
a[9000] = 3; 
a.foo = function() {}; 

// outputs 0, 1, 9000, 1000000 -- note they are in order 
a.forEach(function(elem, index){ console.log(index); }) 

// outputs 0, 1, 9000, 1000000 -- same as above 
_.each(a, function(elem, index){ console.log(index); }) 

// outputs a million values and locks up your browser for a while 
$.each(a, function(index){ console.log(index); }) 

Así, tanto forEach y $.each volver a sus valores con el fin índice, pero forEach y subrayado parece superior para matrices dispersas, ya que ignoran los índices que no han tenido un valor asignado a ellos.

Cuestiones relacionadas