Desarrollo Web

Objetos en JavaScript explicados paso a paso

Jairo
6 min de lectura
Objetos en JavaScript explicados paso a paso

Objetos en JavaScript explicados paso a paso

1) Qué es un objeto en JavaScript (con analogías claras)

Un objeto en JavaScript es un contenedor de pares clave → valor. Si vengo del mundo real, me sirve pensar que es como una ficha de un “ser humano”: nombre: "Pepito", talla: 1.50, ciudad: "Ibarra", país: "Ecuador". Cuando empecé, esta analogía me sacó de apuros: un objeto agrupa información relacionada en una sola unidad.

const humano = {
  nombre: "Pepito",
  talla: 1.50,
  ciudad: "Ibarra",
  pais: "Ecuador"
};

Un detalle clave: los objetos no tienen orden garantizado de propiedades, y la igualdad es por referencia (dos objetos con el mismo contenido no son “iguales” si no son el mismo objeto en memoria).

Prueba rápida

  1. Crea el objeto humano y compara {} con {} usando ===.
  2. Cambia humano.ciudad a "Quito" y observa cómo muta el mismo objeto.

2) Crear objetos: literal, new Object() y Object.create

La vía moderna y clara es el objeto literal:

const bici = { marca: "Yamaha", modelo: "MT-03", anio: 2026, color: "azul" };

También existe new Object(), pero lo uso poco; añade ruido sin beneficio real:

const carro = new Object();
carro.marca = "Toyota";
carro.modelo = "Camry";
carro.anio = 2026;
carro.color = "negro";

Object.create(proto) sirve para crear un objeto con un prototipo específico (útil para herencia ligera o patrones muy controlados):

const vehiculoBase = { mover() { return "rueda"; } };
const moto = Object.create(vehiculoBase);
moto.marca = "Kawasaki";

Cuando expliqué esto a mi equipo, usé tu idea: “los objetos existen en todos los lenguajes; en JS el literal es la puerta de entrada más sencilla”.

Prueba rápida
Crea vehiculoBase, deriva moto con Object.create y comprueba que moto.mover() funciona aun si moto no define mover.

3) Propiedades y métodos: acceso por punto y corchetes

Dos formas de acceder a propiedades:

bici.marca         // notación punto (rápida y legible)
bici["marca"]      // corchetes (clave dinámica o nombres no válidos)

Corchetes brillan cuando la clave es dinámica:

const clave = "color";
console.log(bici[clave]); // "azul"

Añadir métodos es tan simple como colgar una función:

bici.descripcion = function () {
  return `${this.marca} ${this.modelo} (${this.anio})`;
};

Aquí aparece this: dentro de un método, this suele apuntar al objeto. En callbacks sueltos puede perderse; yo suelo evitar líos usando funciones flecha donde no necesito re-vincular this, o Function.prototype.bind cuando sí.

Prueba rápida
Agrega descripcion y llámala. Luego asigna const d = bici.descripcion; d(); y observa qué pasa con this. Repite usando d = bici.descripcion.bind(bici).

4) Recorrer objetos: for…in, Object.keys/values/entries

Cuando dijiste “podemos iterar estos objetos”, encaja perfecto aquí:

  • for…in recorre propias y heredadas (filtra con hasOwnProperty).
  • Object.keys(obj) → array de claves propias.
  • Object.values(obj) → array de valores.
  • Object.entries(obj) → array de [clave, valor].
for (const k in humano) {
  if (Object.prototype.hasOwnProperty.call(humano, k)) {
    console.log(k, humano[k]);
  }
}

Object.entries(bici).forEach(([k, v]) => console.log(k, v));

Prueba rápida
Convierte entries a un objeto nuevo filtrando solo las claves cuyo valor sea string.

5) this, getters y setters sin dolor de cabeza

Los getters/setters permiten exponer propiedades calculadas y validar entradas sin cambiar la API de uso:

const persona = {
  nombre: "Pepito",
  _anioNac: 2000,
  get edad() { return new Date().getFullYear() - this._anioNac; },
  set anioNac(v) {
    if (typeof v !== "number") throw new TypeError("Año inválido");
    this._anioNac = v;
  }
};

Tips que me funcionan siempre:

  • Métodos que usan this → defínelos como funciones normales (function(){}), no flechas.
  • Callbacks donde no quiero this → flechas (() => {}) para heredar el this léxico o, directamente, no usar this.

Prueba rápida
Lee persona.edad, cambia anioNac a un número inválido y captura el error.

6) Herencia y prototipo: lo justo para entenderlo

Cada objeto tiene un prototipo (otro objeto del que “hereda”). Dos rutas habituales:

  • Prototipos directos (Object.create(proto)).
  • Clases (azúcar sintáctico sobre prototipos):
class Vehiculo {
  constructor(marca, modelo) { this.marca = marca; this.modelo = modelo; }
  descripcion() { return `${this.marca} ${this.modelo}`; }
}

class Moto extends Vehiculo {
  constructor(marca, modelo, anio) { super(marca, modelo); this.anio = anio; }
}

Yo uso clases cuando el modelo de datos requiere comportamiento compartido y relaciones claras; si solo guardo pares clave-valor, me quedo con objetos literales.

Prueba rápida
Crea new Moto("Kawasaki","Ninja",2026) y llama descripcion().

7) Comparar, clonar e inmutar objetos (pitfalls comunes)

Comparación: {} === {} es false porque compara referencias. Si necesitas comparar contenido, serializa o implementa una función de comparación profunda.

Clonado:

  • Sencillo (superficial): { ...obj } o Object.assign({}, obj)
  • Profundo: structuredClone(obj) (navegadores modernos / Node 17+).
     Evita JSON.parse(JSON.stringify(obj)) si hay fechas, funciones o undefined.

Inmutabilidad práctica: cuando no quiero que un objeto cambie, uso:

  • Copias antes de mutar.
  • Object.freeze(obj) para congelar (shallow).
  • Patrones de actualización inmutable:
  • const bici2 = { ...bici, color: "rojo" }; // no toco el original
    

Prueba rápida
Clona humano con spread, cambia la ciudad del clon y verifica que el original sigue igual. Luego prueba structuredClone con un objeto anidado.

8) ¿Objeto, Map o clase? Elegir la herramienta correcta

Sin tabla; te dejo una lista de criterios rápidos:

  • Objeto literal
    • Cuando represento entidades con un conjunto relativamente fijo de propiedades.
    • Excelente para configuraciones y modelos simples.
    • Acceso muy rápido y serialización fácil.
  • Map
    • Cuando las claves no son strings (pueden ser objetos o funciones).
    • Necesito orden de inserción y tamaño (map.size).
    • Operaciones frecuentes de agregar/eliminar claves dinámicas.
  • Clase
    • Cuando hay comportamiento compartido, reglas y métodos bien definidos.
    • Necesito instancias con una interfaz consistente y extensible.

Cuando hablé de la bicicleta y el carro, suelo mapearlos como objetos si solo guardo datos; si voy a validar y operar mucho (arrancar, acelerar, frenar con reglas), me paso a clases.

Prueba rápida
Crea un Map que use objetos como clave (ej. { id: 1 }) y comprueba que funciona donde un objeto plain no podría.

9) Mini-proyecto guiado: de un “humano” a un modelo de datos

Objetivo: partir del ejemplo “humano” y construir un mini-modelo con validación ligera e iteración.

  1. Define el objeto:
const humano = {
  nombre: "Pepito",
  talla: 1.50,
  ciudad: "Ibarra",
  pais: "Ecuador",
  hobbies: ["ciclismo", "lectura"]
};

  1. Agrega métodos seguros:
humano.addHobby = function (h) {
  if (typeof h !== "string" || !h.trim()) return false;
  this.hobbies = [...this.hobbies, h.trim()];
  return true;
};

  1. Expón una vista calculada (getter):
Object.defineProperty(humano, "resumen", {
  get() { return `${this.nombre} (${this.ciudad}, ${this.pais})`; }
});

  1. Itera limpiamente:
const soloStrings = Object.fromEntries(
  Object.entries(humano).filter(([, v]) => typeof v === "string")
);

A mí me gusta cerrar este ejercicio conectándolo con POO: si mañana “humano” crece y necesita reglas complejas, extraigo una clase Persona.

Prueba rápida
Llama humano.addHobby(" JS "), verifica que no mutaste accidentalmente el array original (se crea uno nuevo), y lee humano.resumen.

10) Preguntas frecuentes

¿Objeto literal o new Object()? Literal, por legibilidad y concisión.
¿Cómo recorro solo propiedades propias? for…in + hasOwnProperty o directamente Object.keys/entries.
¿Por qué {} !== {}? Igualdad por referencia. Usa comparación profunda si necesitas equivalencia estructural.
¿Cómo clono sin mutar? Spread para superficial, structuredClone para profundo.
¿Cuándo usar Map? Claves no-string, orden de inserción y operaciones frecuentes de alta/baja.
¿this me falla en callbacks? Usa flechas (sin this propio) o bind.

Conclusión

Los objetos son el “contenedor” por excelencia en JavaScript. Empezar con literales, dominar acceso por punto/corchetes, iteración con Object.* y entender lo básico de prototipos te da el 80%. A partir de ahí, decisiones prácticas: clases cuando hay comportamiento, Map cuando las claves mandan. Y siempre que puedas, evita mutaciones sorpresivas.


JavaScript

Jairo

Comentarios (0)

No hay comentarios aún. ¡Sé el primero en comentar!

Envíame un comentario

🍪 Utilizamos cookies para mejorar tu experiencia de navegación, analizar el tráfico del sitio y personalizar el contenido. Al continuar navegando, aceptas nuestro uso de cookies. Más información