Apartémonos de las estructuras de datos individuales y hablemos de las iteraciones sobre ellas.
En el capítulo anterior vimos los métodos map.keys()
, map.values()
, map.entries()
.
Estos métodos son genéricos, hay un acuerdo común para usarlos para las estructuras de datos. Si alguna vez creamos una estructura de datos propia, deberíamos implementarlos también.
Se soportan para:
Map
Set
Array
Los objetos planos también soportan métodos similares, pero la sintaxis es un poco diferente.
Object.keys, values, entries
Para los objetos planos, están disponibles los siguientes métodos:
- Object.keys(obj) – devuelve una matriz de claves.
- Object.values(obj) – devuelve una matriz de valores.
- Object.entries(obj) – devuelve una matriz de pares
.
Nota las distinciones (comparado con map por ejemplo):
Map | Object | |
---|---|---|
Sintaxis de llamada | map.keys() |
Object.keys(obj) , pero no obj.keys() |
Devuelve | iterable | Array «real» |
La primera diferencia es que tenemos que llamar a Object.keys(obj)
, y no a obj.keys()
.
¿Por qué? La razón principal es la flexibilidad. Recuerda que los objetos son la base de todas las estructuras complejas en JavaScript. Así que podemos tener un objeto propio como data
que implemente su propio método data.values()
. Y todavía podemos llamar a Object.values(data)
sobre él.
La segunda diferencia es que los métodos Object.*
devuelven objetos de array «reales», no sólo un iterable. Eso es principalmente por razones históricas.
Por ejemplo:
let user = { name: "John", age: 30};
Object.keys(user) =
Object.values(user) =
Object.entries(user) = , ]
Aquí tienes un ejemplo de uso de Object.values
para hacer un bucle sobre los valores de las propiedades:
let user = { name: "John", age: 30};// loop over valuesfor (let value of Object.values(user)) { alert(value); // John, then 30}
Al igual que un bucle for..in
, estos métodos ignoran las propiedades que utilizan Symbol(...)
como claves.
Usualmente eso es conveniente. Pero si también queremos claves simbólicas, existe un método independiente Object.getOwnPropertySymbols que devuelve un array de sólo claves simbólicas. Además, existe un método Reflect.ownKeys(obj) que devuelve todas las claves.
Transformación de objetos
Los objetos carecen de muchos métodos que existen para los arrays, por ejemplo map
, filter
y otros.
Si queremos aplicarlos, entonces podemos usar Object.entries
seguido de Object.fromEntries
:
- Usa
Object.entries(obj)
para obtener un array de pares clave/valor deobj
. - Utilizar métodos de array en ese array, por ejemplo
map
. - Utilizar
Object.fromEntries(array)
en el array resultante para convertirlo de nuevo en un objeto.
Por ejemplo, tenemos un objeto con precios, y nos gustaría duplicarlos:
let prices = { banana: 1, orange: 2, meat: 4,};let doublePrices = Object.fromEntries( // convert to array, map, and then fromEntries gives back the object Object.entries(prices).map(() => ));alert(doublePrices.meat); // 8
Puede parecer difícil a primera vista, pero se hace fácil de entender después de usarlo una o dos veces. Podemos hacer poderosas cadenas de transformaciones de esta manera.