¿Por qué mi bucle for-each no itera sobre mi objeto de matriz asociativa de JavaScript?
// defining an array
var array = [];
// assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";
// expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
console.log(array[i]);
}
EDITAR: jQuery each()
podría ser útil: https://api.jquery.com/jQuery.each/
javascript
arrays
foreach
Szymon Toda
fuente
fuente
associative arrays
en JS: es una matriz simple o un objeto. Nada impide agregar propiedades no numéricasArray
, pero eso no lo haceassociative
, en particular, lalength
propiedad no contará automáticamente estas propiedades.Respuestas:
La
.length
propiedad solo rastrea propiedades con índices numéricos (claves). Estás usando cadenas para las teclas.Puedes hacerlo:
Para estar seguro, es una buena idea en bucles como ese asegurarse de que ninguna de las propiedades sean resultados inesperados de la herencia:
editar : probablemente sea una buena idea tener en cuenta que la
Object.keys()
función está disponible en los navegadores modernos y en el Nodo, etc. Esa función devuelve las teclas "propias" de un objeto, como una matriz:La función de devolución de llamada pasada
.forEach()
se llama con cada clave y el índice de la clave en la matriz devuelta porObject.keys()
. También pasó la matriz a través de la cual la función está iterando, pero esa matriz no es realmente útil para nosotros; Necesitamos el objeto original . Se puede acceder a eso directamente por su nombre, pero (en mi opinión) es un poco mejor pasarlo explícitamente, lo que se hace pasando un segundo argumento al.forEach()
objeto original, que se vinculará comothis
dentro de la devolución de llamada. (Acabo de ver que esto se observó en un comentario a continuación).fuente
var arr_jq_TabContents = {};
? Quiero decir {}[]
y{}
? ¿Solo los diferentes prototipos?Object.keys(arr_jq_TabContents).forEach( function(key) { ... } );
Este es un enfoque muy simple. La ventaja es que también puede obtener claves:
Para ES6:
Para ES6: (si desea valor, índice y la matriz en sí)
fuente
var
en bucles que sugieran un alcance que no existe. Usevar
en frente del bucle olet
en el bucle.for
bucle genera un alcance limitado al cuerpo delfor
bucle. Pero en JavaScript, una variable declarada porvar
siempre es una función global, incluso si la escribe en unfor
bucle. Ver aquí: davidwalsh.name/for-and-against-letvar
en Javascript crea variables en la memoria incluso después de que se completa el ciclo.Ya hay algunos ejemplos sencillos, pero me doy cuenta de cómo redactó su pregunta que probablemente proviene de un fondo PHP y espera que JavaScript funcione de la misma manera, no es así. Un PHP
array
es muy diferente de un JavaScriptArray
.En PHP, una matriz asociativa puede hacer la mayor parte de lo que puede hacer una matriz indexada numéricamente (las
array_*
funciones funcionan, puedecount()
, etc.) Simplemente cree una matriz y comience a asignar índices de cadena en lugar de numéricos.En JavaScript, todo es un objeto (excepto las primitivas: cadena, numérico, booleano), y las matrices son una implementación determinada que le permite tener índices numéricos. Cualquier cosa empujado a una matriz afectará a su
length
, y puede ser iterado sobre el uso de métodos Array (map
,forEach
,reduce
,filter
,find
, etc.) Sin embargo, como todo es un objeto, que está siempre libre para asignar propiedades simplemente, porque eso es algo que se hace a cualquier objeto La notación de corchetes es simplemente otra forma de acceder a una propiedad, por lo que en su caso:en realidad es equivalente a:
Según su descripción, supongo que desea una 'matriz asociativa', pero para JavaScript, este es un caso simple de usar un objeto como un mapa hash. Además, sé que es un ejemplo, pero evite nombres sin sentido que solo describan el tipo de variable (por ejemplo
array
) y el nombre en función de lo que debe contener (por ejemplopages
). Los objetos simples no tienen muchas buenas formas directas de iterar, por lo que a menudo los convertiremos primero en matrices utilizandoObject
métodos (Object.keys
en este caso, también hayentries
yvalues
se agregarán a algunos navegadores en este momento) que podemos recorrer.fuente
arr_jq_TabContents[key]
ve la matriz como una forma de índice 0.fuente
Aquí hay una manera simple de usar una matriz asociativa como un tipo de objeto genérico:
fuente
Si el node.js o el navegador son compatibles
Object.entries()
, se puede usar como alternativa al usoObject.keys()
( https://stackoverflow.com/a/18804596/225291 ).en este ejemplo,
forEach
usa la asignación Destructuring de una matriz.fuente
Esto es (esencialmente) incorrecto en la mayoría de los casos:
Eso crea una propiedad no elemento en la matriz con el nombre
Main
. Aunque las matrices son objetos, normalmente no desea crear propiedades que no sean elementos en ellas.Si desea indexar
array
por esos nombres, normalmente usaría unMap
objeto simple o simple, no una matriz.Con un
Map
(ES2015 +), al que llamarémap
porque soy creativo:A continuación, iterar utilizando los iteradores de sus
values
,keys
, oentries
métodos, por ejemplo:Usando un objeto simple, que llamaré creativamente
obj
:que había entonces iterar sus contenidos utilizando
Object.keys
,Object.values
oObject.entries
, por ejemplo:fuente
en este código, utilicé el método de paréntesis para los valores de llamada en la matriz porque contenía la matriz, sin embargo, brevemente, la idea de que una variable i tiene una clave de propiedad y con un bucle llamado ambos valores de la matriz asociada
Método perfecto, si está interesado, presione como
fuente
Puedes hacerlo
fuente