Tengo un objeto JavaScript como el siguiente:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Ahora quiero recorrer todo p
los elementos ( p1
, p2
, p3
...) y obtener sus claves y valores. ¿Cómo puedo hacer eso?
Puedo modificar el objeto JavaScript si es necesario. Mi objetivo final es recorrer algunos pares de valores clave y, si es posible, quiero evitar usareval
.
javascript
loops
for-loop
each
Tanmoy
fuente
fuente
Respuestas:
Puede usar el
for-in
bucle como lo muestran otros. Sin embargo, también debe asegurarse de que la clave que obtiene es una propiedad real de un objeto y no proviene del prototipo.Aquí está el fragmento:
Alternativa For-of con Object.keys ():
Observe el uso de en
for-of
lugar defor-in
, si no se usa, devolverá indefinido en propiedades con nombre, yObject.keys()
garantiza el uso de solo las propiedades propias del objeto sin las propiedades completas de la cadena del prototipo.Usando el nuevo
Object.entries()
método:Nota: Internet Explorer no admite este método de forma nativa. Puede considerar usar un Polyfill para navegadores antiguos.
fuente
alert(key + " -> " + JSON.stringify(p[key]));
__proto__
oprototype
. Esta propiedad tiene una referencia a su objeto padre. Un objeto hereda automáticamente la propiedad de su padre. Esta es la razón del usohasOwnProperty
, lo que significa que estamos interesados en los objetos de propiedad propia y no en los primarios.En ECMAScript 5, puede combinar
Object.keys()
yArray.prototype.forEach()
:ECMAScript 6 agrega
for...of
:ECMAScript 8 agrega
Object.entries()
que evita tener que buscar cada valor en el objeto original:Puedes combinar
for...of
, desestructurar yObject.entries
:Ambos
Object.keys()
yObject.entries()
Iterar propiedades en el mismo orden que unfor...in
bucle pero ignoran la cadena de prototipo . Solo se iteran las propiedades enumerables propias del objeto.fuente
Object.forEach(obj, function (value, key) {...})
? :( Ciertamenteobj.forEach(function...)
sería más corto y complementarioArray.prototype.forEach
, pero eso correría el riesgo de que los objetos definan su propiaforEach
propiedad. Supongo queObject.keys
protege contra la devolución de llamada que modifica las claves del objeto.Object.forEach = function (obj, callback) { Object.keys(obj).forEach(function (key) { callback(obj[key], key); }); }
Object.entries(obj).map/forEach(([key, value]) => console.log(key, value))
([clave, valor] es la desestructuración de la matriz, para acceder a ambos elementos directamente. Y tiene que ajustar los parámetros en parens adicionales.)index
la clave en json? ¿O si fuera necesario, debería usar un contador separado?for...of
es el estándar ES6, no ES2016.Tienes que usar el bucle for-in
Pero tenga mucho cuidado al usar este tipo de bucle, porque esto hará un bucle de todas las propiedades a lo largo de la cadena del prototipo .
Por lo tanto, cuando use bucles for-in, siempre use el
hasOwnProperty
método para determinar si la propiedad actual en iteración es realmente una propiedad del objeto que está revisando:fuente
{ }
personalmente porqueif
sin ellos, no queda claro qué es parte deif
lo que no es. Pero supongo que es solo una cuestión de opinión :){ }
principalmente para evitar confusiones si más adelante uno necesita agregar algo alif
alcance.Object.prototype.hasOwnProperty.call(p, prop)
Sin embargo, esto tampoco puede proteger contra las manipulaciones del prototipo de Object ...La pregunta no estará completa si no mencionamos métodos alternativos para recorrer objetos.
Hoy en día, muchas bibliotecas JavaScript conocidas proporcionan sus propios métodos para iterar sobre colecciones, es decir, sobre matrices , objetos y objetos similares a matrices . Estos métodos son convenientes de usar y son totalmente compatibles con cualquier navegador.
Si trabaja con jQuery , puede usar el
jQuery.each()
método. Se puede usar para iterar sin problemas sobre objetos y matrices:En Underscore.js puedes encontrar el método
_.each()
, que itera sobre una lista de elementos, dando a cada uno una función proporcionada (¡preste atención al orden de los argumentos en la función iteratee !):Lo-Dash proporciona varios métodos para iterar sobre las propiedades del objeto. Basic
_.forEach()
(o su alias_.each()
) es útil para recorrer tanto los objetos como las matrices, sin embargo (!) Los objetos conlength
propiedad se tratan como matrices, y para evitar este comportamiento se sugiere usar_.forIn()
_.forOwn()
métodos y métodos (estos también tienenvalue
argumentos en primer lugar):_.forIn()
itera sobre propio y heredado propiedades enumerables de un objeto, mientras que_.forOwn()
itera solo sobre las propiedades propias de un objeto (básicamente verificando lahasOwnProperty
función). Para objetos simples y literales de objeto, cualquiera de estos métodos funcionará bien.En general, todos los métodos descritos tienen el mismo comportamiento con cualquier objeto suministrado. Además de usar el
for..in
ciclo nativo , generalmente será más rápido que cualquier abstracción, por ejemplojQuery.each()
, estos métodos son considerablemente más fáciles de usar, requieren menos codificación y proporcionan un mejor manejo de errores.fuente
En ECMAScript 5 tiene un nuevo enfoque en los campos de iteración de literal:
Object.keys
Más información que puedes ver en MDN
Mi elección está a continuación como una solución más rápida en las versiones actuales de los navegadores (Chrome30, IE10, FF25)
Puede comparar el rendimiento de este enfoque con diferentes implementaciones en jsperf.com :
Soporte de navegador que puede ver en la tabla de compatibilidad de Kangax
Para el navegador antiguo, tiene un polyfill simple y completo
UPD:
Comparación de rendimiento para todos los casos más populares en esta pregunta sobre
perfjs.info
:iteración literal de objeto
fuente
Prefacio:
Aquí en 2018, sus opciones para recorrer las propiedades de un objeto son (algunos ejemplos siguen la lista):
for-in
[ MDN , spec ]: una estructura de bucle que recorre los nombres de las propiedades enumerables de un objeto , incluidas las heredadas, cuyos nombres son cadenasObject.keys
[ MDN , spec ] - Una función de proporcionar una matriz de los nombres de los de un objeto propias , enumerables propiedades cuyos nombres son cadenas.Object.values
[ MDN , spec ] - Una función de proporcionar una matriz de los valores de de un objeto propias , enumerables propiedades.Object.entries
[ MDN , spec ] - Una función de proporcionar una matriz de los nombres y valores de de un objeto propias , enumerables propiedades (cada entrada de la matriz es una[name, value]
matriz).Object.getOwnPropertyNames
[ MDN , spec ]: una función que proporciona una matriz de los nombres de las propiedades propias de un objeto (incluso las no enumerables) cuyos nombres son cadenas.Object.getOwnPropertySymbols
[ MDN , spec ]: una función que proporciona una matriz de los nombres de las propiedades propias de un objeto (incluso las no enumerables) cuyos nombres son símbolos.Reflect.ownKeys
[ MDN , spec ]: una función que proporciona una matriz de los nombres de las propiedades propias de un objeto (incluso las no enumerables), ya sea que esos nombres sean cadenas o símbolos.Object.getPrototypeOf
[ MDN , spec ] y el usoObject.getOwnPropertyNames
,Object.getOwnPropertySymbols
oReflect.ownKeys
en cada objeto en la cadena de prototipo (ejemplo en la parte inferior de esta respuesta).Con todos ellos, excepto
for-in
, que tendría que utilizar algún tipo de bucle construcción de la matriz (for
,for-of
,forEach
, etc.).Ejemplos:
for-in
:Mostrar fragmento de código
Object.keys
(con unfor-of
bucle, pero puede usar cualquier construcción de bucle) :Mostrar fragmento de código
Object.values
:Mostrar fragmento de código
Object.entries
:Mostrar fragmento de código
Object.getOwnPropertyNames
:Mostrar fragmento de código
Object.getOwnPropertySymbols
:Mostrar fragmento de código
Reflect.ownKeys
:Mostrar fragmento de código
Todas las propiedades , incluidas las heredadas no enumerables:
Mostrar fragmento de código
fuente
Puedes iterar sobre él como:
Tenga en cuenta que
key
no tomará el valor de la propiedad, es solo un valor de índice.fuente
Como es2015 se está volviendo cada vez más popular, estoy publicando esta respuesta que incluye el uso del generador y el iterador para iterar suavemente a través de
[key, value]
pares. Como es posible en otros idiomas, por ejemplo, Ruby.Ok, aquí hay un código:
Toda la información sobre cómo puede hacer un iterador y un generador puede encontrarla en la página del desarrollador Mozilla.
Espero que haya ayudado a alguien.
EDITAR:
ES2017 incluirá lo
Object.entries
que hará que la iteración sobre[key, value]
pares en objetos sea aún más fácil. Ahora se sabe que será parte de un estándar según el ts39 información de la etapa .Creo que es hora de actualizar mi respuesta para que se vuelva aún más fresca de lo que es ahora.
Puede encontrar más información sobre el uso en la página MDN
fuente
Nota: puede hacer esto sobre matrices, pero también iterará sobre las
length
otras propiedades.fuente
key
solo tomará un valor de índice, por lo que solo alertará a 0, 1, 2, etc ... Debe acceder a p [clave].var p = {"p1":"q","p2":"w"}; for(key in p) { alert( key ); }
está apareciendo "p1" y "p2" en las alertas, ¿qué tiene de malo eso?Después de revisar todas las respuestas aquí, hasOwnProperty no es necesario para mi propio uso porque mi objeto json está limpio; realmente no tiene sentido agregar ningún procesamiento javascript adicional. Esto es todo lo que estoy usando:
fuente
Object.prototype
, entonces será enumerado porfor..in
. Si está seguro de que no está utilizando ninguna biblioteca que lo haga, no necesita llamarhasOwnProperty
.Object.create(null)
a través de un prototipo con forEach () que debe omitir las propiedades de la cadena del prototipo :
fuente
obj = { print: 1, each: 2, word: 3 }
produceTypeError: number is not a function
. UsarforEach
para igualar laArray
función similar puede reducir un poco el riesgo.Es interesante que las personas en estas respuestas hayan tocado ambos
Object.keys()
yfor...of
nunca los hayan combinado:Puede no sólo
for...of
unaObject
, porque no es un iterador, yfor...index
o.forEach()
ing elObject.keys()
es feo / ineficiente.Me alegra que la mayoría de las personas se abstengan
for...in
(con o sin verificación.hasOwnProperty()
), ya que eso también es un poco desordenado, por lo que, aparte de mi respuesta anterior, estoy aquí para decir ...¡Puedes hacer que las asociaciones de objetos ordinarios se repitan! Comportarse como
Map
s con el uso directo de la elegantefor...of
DEMO que funciona en Chrome y FF (supongo que solo ES6)
Siempre que incluyas mi cuña a continuación:
Sin tener que crear un objeto Map real que no tenga el agradable azúcar sintáctico.
De hecho, con esta cuña, si aún desea aprovechar la otra funcionalidad de Map (sin calzarlas todas) pero aún desea usar la notación de objeto ordenada, ya que los objetos ahora son iterables, ¡ahora puede hacer un Mapa a partir de ella!
Para aquellos a quienes no les gusta calzar, o meterse con ellos
prototype
en general, siéntanse libres de hacer la función en la ventana, llamándola asígetObjIterator()
;Ahora solo puede llamarlo como una función ordinaria, nada más se ve afectado
o
No hay razón para que eso no funcione.
Bienvenido al futuro.
fuente
For those who don't like to shim, or mess with prototype in general, feel free to make the function on window instead, calling it something like getObjIterator() then;
ordinaryObject
para enfatizar que la magia aún funciona para esos tipos). ¿Revisaste las demos? ¿Qué no te funciona, @ noɥʇʎԀʎzɐɹƆ? (PD: tu imagen de perfil de SE es jefe)Por lo tanto, proporciona la misma lista de claves que pretendía al probar cada clave de objeto con hasOwnProperty. No necesita esa operación de prueba adicional y
Object.keys( obj ).forEach(function( key ){})
se supone que es más rápido. Probémoslo:En mi Firefox tengo los siguientes resultados
PD. en Chrome la diferencia aún más grande http://codepen.io/dsheiko/pen/JdrqXa
PS2: en ES6 (EcmaScript 2015) puede iterar mejor el objeto iterable:
fuente
of
sin crearMap
sAquí hay otro método para iterar a través de un objeto.
fuente
for
método podría ser más eficaz.fuente
También puede usar Object.keys () e iterar sobre las teclas de objeto como a continuación para obtener el valor:
fuente
Solo código JavaScript sin dependencias:
fuente
El
Object.keys()
método devuelve una matriz de propiedades enumerables propias de un objeto dado. Lea más sobre esto aquífuente
Actuación
Hoy 2020.03.06 realizo pruebas de las soluciones elegidas en Chrome v80.0, Safari v13.0.5 y Firefox 73.0.1 en MacOs High Sierra v10.13.6
Conclusiones
for-in
(A, B) son rápidas (o más rápidas) para todos los navegadores de objetos grandes y pequeñosfor-of
solución (H) es rápida en Chrome para objetos pequeños y grandesi
(J, K) son bastante rápidas en todos los navegadores para objetos pequeños (para Firefox también es rápido para objetos grandes pero medio rápido en otros navegadores)Detalles
Se realizaron pruebas de rendimiento para
A continuación, los fragmentos presentan soluciones usadas
Mostrar fragmento de código
Y aquí están los resultados para objetos pequeños en cromo
fuente
Puede agregar una función forEach simple a todos los objetos, para que pueda recorrer automáticamente cualquier objeto:
Para aquellas personas a las que no les gusta el método " para ... en ":
Ahora, puede llamar simple:
Si no desea tener conflictos con otros métodos para cada método, puede nombrarlo con su nombre único.
fuente
Object
) generalmente se considera un antipatrón porque puede causar fácilmente conflictos con otro código. Así que no recomiendo hacerlo de esta manera.Los bucles pueden ser bastante interesantes cuando se usa JavaScript puro. Parece que solo ECMA6 (nueva especificación JavaScript 2015) tiene los bucles bajo control. Desafortunadamente, mientras escribo esto, los navegadores y el popular entorno de desarrollo integrado (IDE) todavía están luchando para soportar completamente las nuevas campanas y silbatos.
De un vistazo, aquí se ve un bucle de objetos JavaScript antes de ECMA6:
Además, sé que esto está fuera de alcance con esta pregunta, pero en 2011, ECMAScript 5.1 agregó el
forEach
método solo para matrices, que básicamente creó una nueva forma mejorada de recorrer las matrices y al mismo tiempo dejar objetos no iterables con el antiguofor
ciclo detallado y confuso . Pero la parte extraña es que este nuevoforEach
método no es compatible, lobreak
que condujo a todo tipo de problemas.Básicamente, en 2011, no hay una forma realmente sólida de bucle en JavaScript que no sea lo que muchas bibliotecas populares (jQuery, Underscore, etc.) decidieron volver a implementar.
A partir de 2015, ahora tenemos una mejor manera de hacer un bucle (y romper) cualquier tipo de objeto (incluidas matrices y cadenas). Así es como se verá un bucle en JavaScript cuando la recomendación se convierta en la corriente principal:
Tenga en cuenta que la mayoría de los navegadores no admitirán el código anterior a partir del 18 de junio de 2016. Incluso en Chrome, debe habilitar este indicador especial para que funcione:
chrome://flags/#enable-javascript-harmony
Hasta que este se convierta en el nuevo estándar, el método anterior todavía puede usarse, pero también hay alternativas en bibliotecas populares o incluso alternativas livianas para aquellos que no usan ninguna de estas bibliotecas.
fuente
Uncaught TypeError: Object.entries is not a function
. ¿Todavía no está implementado en Chrome?En ES6 tenemos símbolos bien conocidos para exponer algunos métodos internos anteriores, puede usarlo para definir cómo funcionan los iteradores para este objeto:
esto dará el mismo resultado que usar for ... en el bucle es6.
¡Pero es importante conocer las capacidades que tiene ahora usando es6!
fuente
Object.keys()
y se asigna en la memoria ... ¡Genial!Haría esto en lugar de verificar
obj.hasOwnerProperty
dentro de cadafor ... in
bucle.fuente
fuente
json = [{"key1":"value1","key2":"value2"},{"key1":"value3","key2":"value4"}] for (var i = 0; i < json.length; i++) { for (var key in json[i]) { if (json[i].hasOwnProperty(key)) { console.log(key + " -> " + json[i][key]); } } }
Usando un
for-of
encendidoObject.keys()
Me gusta:
fuente
Si también desea iterar sobre propiedades no enumerables , puede usar
Object.getOwnPropertyNames(obj)
para devolver una matriz de todas las propiedades (enumerables o no) encontradas directamente sobre un objeto dado.fuente
Error
objeto y no podía acceder a las propiedades en un bucle o una_.forIn(err)
llamada. El usoObject.getOwnPropertyNames(err)
me permitió acceder a todas las partes de lasError
que no podía acceder antes. ¡Gracias!Si alguien necesita recorrer los objetos de matriz con condición :
fuente
Considerando ES6, me gustaría agregar mi propia cucharada de azúcar y proporcionar un enfoque más para iterar sobre las propiedades del objeto.
Dado que el objeto JS simple no es iterable de fábrica, no podemos usar el
for..of
bucle para iterar sobre su contenido. Pero nadie puede detenernos para que sea iterable .Vamos a tener
book
objeto.Como lo hemos hecho, podemos usarlo de esta manera:
O si conoce el poder de los generadores ES6 , entonces ciertamente puede hacer que el código anterior sea mucho más corto.
Claro, puede aplicar dicho comportamiento para todos los objetos haciendo que sea
Object
iterable en elprototype
nivel.Además, los objetos que cumplen con el protocolo iterable se pueden usar con el nuevo operador de propagación de características ES2015, por lo que podemos leer los valores de las propiedades de los objetos como una matriz.
O puede usar la asignación de desestructuración :
Puede consultar JSFiddle con todo el código que he proporcionado anteriormente.
fuente
desde ES06 puede obtener los valores de un objeto como matriz con
¡devuelve una matriz de valores de objetos y no extrae valores de Prototype!
MDN DOCS Object.values ()
y para llaves (ya respondí antes que yo aquí)
fuente
En la última secuencia de comandos ES, puede hacer algo como esto:
fuente