Objetos en JavaScript y por qué ves [object Object]
Guía de objetos en JavaScript
Objetos en JavaScript: claves, copias y [object Object] resuelto | We.Inc
Crea, lee, recorre y copia objetos en JavaScript, y descubre por qué tu página muestra [object Object] y cómo mostrar el valor real. Pega cualquier JSON para inspeccionarlo en vivo.
Un objeto de JavaScript es un conjunto de valores con nombre escrito como { key: value }. Lees un valor con obj.key u obj['key'], listas las claves con Object.keys y los pares con Object.entries. El texto [object Object] aparece cuando un objeto se convierte en string; usa JSON.stringify(obj) para mostrar su contenido.
Los objetos son la forma en que llegan casi todas las respuestas de API, archivos de configuración y props de React. Esta guía cubre el puñado de operaciones que usas a diario y luego aborda las dos sorpresas clásicas: [object Object] apareciendo en la página o en un alert, y una copia que comparte en secreto sus datos anidados con el original.
Pega o edita JSON en el inspector. Se parsea en tu navegador con JSON.parse.
Cada fila muestra una forma habitual de convertir el objeto en texto o en una lista, incluida la que produce [object Object].
Usa el experimento de copia para cambiar un valor anidado en una copia con spread y en una copia con structuredClone, y mira cuál afecta al original.
Los ejemplos de código de abajo están listos para pegar en tu editor o en la consola del navegador.
Para ver un objeto en la consola, regístralo solo con console.log(obj) o console.table(obj). Unirlo a un string con + lo aplana a [object Object].
Object.keys devuelve las claves como strings, incluso las que parecen números, y las claves de tipo entero salen en orden ascendente antes que el resto.
JSON.stringify omite las propiedades cuyo valor es undefined, una función o un symbol, y lanza un TypeError con referencias circulares.
Usa Object.hasOwn(obj, key) para comprobar si el propio objeto tiene una clave; el operador in también mira las propiedades heredadas.
Preguntas frecuentes
¿Por qué mi código muestra [object Object]?
Algo convirtió el objeto en string: un + con texto, un template literal, un alert, element.textContent o innerText. El toString por defecto de los objetos simples devuelve el texto fijo [object Object]. Muestra JSON.stringify(obj) en su lugar, o elige la propiedad que querías, como obj.name.
¿Cómo recorro un objeto en JavaScript?
Usa for (const [key, value] of Object.entries(obj)) { ... }. Un objeto simple no es iterable, así que usar for...of directamente sobre él lanza un TypeError. for...in también funciona, pero incluye las claves enumerables heredadas.
¿Cómo copio un objeto sin que quede vinculado al original?
Para un objeto plano, basta con { ...obj } u Object.assign({}, obj). Si el objeto contiene objetos o arrays anidados, usa structuredClone(obj), que copia todos los niveles. Admite Dates, Maps y Sets, pero lanza un DataCloneError con funciones y nodos del DOM.
¿Cómo convierto un objeto en array y viceversa?
Object.entries(obj) da un array de pares [key, value]. Transfórmalo con map o filter y luego reconstruye un objeto con Object.fromEntries(pairs). Es la forma habitual de aplicar map a los valores de un objeto.
¿Qué diferencia hay entre un objeto y un Map?
Un Map acepta cualquier tipo como clave, recuerda el orden de inserción de todas las claves y tiene una propiedad size. Los objetos simples usan claves string o symbol y son lo que produce JSON. Ten en cuenta que JSON.stringify convierte un Map en {}, así que conviértelo antes con Object.fromEntries(map).
Notación de punto frente a corchetes
La notación de punto es más corta y funciona cuando la clave es un identificador válido que conoces al escribir el código. Los corchetes son obligatorios cuando la clave está en una variable, contiene un espacio o un guion, o empieza por un dígito, por ejemplo headers['content-type'].
Leer una clave que no existe da undefined en lugar de un error. Lo que lanza el error es leer una propiedad de ese undefined, por eso el optional chaining (user.address?.city) resulta tan útil con datos de APIs.
Copias superficiales y profundas
El spread solo copia el nivel superior. El nuevo objeto tiene sus propias posiciones, pero si una de ellas contiene otro objeto, ambas copias apuntan a ese mismo objeto interior, así que editar copy.address.city también edita el original.
structuredClone recorre toda la estructura y crea también objetos interiores nuevos. No conserva los prototipos de clase, getters ni setters, así que una instancia de clase vuelve como un objeto simple con los mismos datos.
Mostrar el valor real en lugar de [object Object]
Cuatro formas de mostrar un objeto
Solo la primera línea produce [object Object]. Las demás muestran un contenido legible.
Formato legible dentro de la página
Un elemento pre conserva los saltos de línea y la sangría que JSON.stringify añade con su tercer argumento.
Transformar objetos con entries y fromEntries
Añadir impuestos a cada precio
entries convierte el objeto en pares, map cambia cada valor y fromEntries crea un objeto nuevo.
Spread frente a structuredClone
La copia con spread comparte el objeto address interior; el clon no.
Inspector de objetos
Edita el JSON y mira cómo cada método lo convierte en texto o en una lista.
Tu objeto como JSON
JSON no válido: {v}
Es un JSON válido, pero no es un objeto. Rodéalo con llaves.
Formas de mostrar el objeto
Código
Resultado
Experimento de copia
Cambia la ciudad en una copia y comprueba si el original también cambió.