Objetos, métodos, clases y array de objetos

 Diferencia, estructura y usos entre método, objeto, clase y arreglo de objetos en JavaScript:  https://lenguajejs.com/javascript/oop/que-es/ 




1. Objeto

Definición: Un objeto es una entidad que agrupa propiedades (datos) y métodos (funciones) relacionados. Se utiliza para modelar cosas del mundo real con atributos y comportamientos.

 const objeto = {
  propiedad: "valor",
  metodo: function() {
    console.log("Soy un método dentro de un objeto");
  }
};
 

Usos:

  • Representar entidades como usuarios, productos, configuraciones, etc.
  • Agrupar datos y funciones relacionadas. 
const usuario = {
  nombre: "Milton",
  edad: 30,
  saludar: function() {
    console.log(`Hola, soy ${this.nombre}`);
  }
};
usuario.saludar(); // "Hola, soy Milton"
 

 

2. Método

Definición: Un método es una función asociada a un objeto o clase que describe un comportamiento específico.

 const objeto = {
  metodo: function() {
    console.log("Este es un método");
  }
};
 

Usos:  Realizar acciones relacionadas con el objeto (ejemplo: modificar propiedades, ejecutar lógica).

 const carrito = {
  productos: [],
  agregarProducto: function(producto) {
    this.productos.push(producto);
    console.log(`Producto agregado: ${producto}`);
  }
};
carrito.agregarProducto("Libro"); // "Producto agregado: Libro"

3. Clase

Definición: Una clase es una plantilla para crear objetos. Define la estructura y el comportamiento de los objetos mediante propiedades y métodos.

 class MiClase {
  constructor(propiedad) {
    this.propiedad = propiedad;
  }

  metodo() {
    console.log(`Propiedad: ${this.propiedad}`);
  }
}
 

Usos:

  • Crear múltiples objetos con características similares.
  • Implementar el paradigma de programación orientada a objetos (OOP).
 class Persona {
  constructor(nombre, edad) {
    this.nombre = nombre;
    this.edad = edad;
  }

  saludar() {
    console.log(`Hola, soy ${this.nombre} y tengo ${this.edad} años`);
  }
}

const persona1 = new Persona("Milton", 30);
persona1.saludar(); // "Hola, soy Milton y tengo 30 años"
 

 

4. Array de objetos

Definición: Un arreglo de objetos es una colección ordenada de múltiples objetos. Cada objeto puede tener sus propias propiedades y métodos.

 const arrayDeObjetos = [
  { nombre: "Objeto1", valor: 10 },
  { nombre: "Objeto2", valor: 20 }
];
 

Usos:

  • Almacenar conjuntos de datos similares.
  • Iterar y manipular colecciones de objetos.
 const productos = [
  { nombre: "Laptop", precio: 1000 },
  { nombre: "Mouse", precio: 20 }
];

productos.forEach(producto => {
  console.log(`Producto: ${producto.nombre}, Precio: ${producto.precio}`);
});
 

 

Relación con el encapsulamiento

El encapsulamiento se refiere a ocultar los detalles internos de un objeto/clase y exponer solo lo necesario. Esto promueve la modularidad, seguridad y facilidad de mantenimiento.

  • Objetos: Encapsulan propiedades y métodos. 
 const objeto = {
  propiedadPrivada: "valor",
  metodoPublico: function() {
    console.log("Este método puede acceder a propiedadPrivada");
  }
};
 

  • Métodos: Garantizan acceso controlado a los datos internos.
 class Cuenta {
  #saldo = 0; // Propiedad privada

  depositar(cantidad) {
    this.#saldo += cantidad;
    console.log(`Saldo: ${this.#saldo}`);
  }
}

const miCuenta = new Cuenta();
miCuenta.depositar(100); // Acceso seguro
// miCuenta.#saldo; // Error: Propiedad encapsulada
  • Clase: Puede encapsular datos y comportamientos en objetos creados desde ella.

Finalidad

  1. Modularidad: Divide el programa en componentes manejables.
  2. Reutilización: Clases y métodos pueden usarse en diferentes partes de un proyecto.
  3. Seguridad: Protege los datos internos al evitar accesos indebidos (ejemplo: propiedades privadas con #).
  4. Facilidad de mantenimiento: El encapsulamiento hace que sea más fácil actualizar una parte del sistema sin afectar todo el proyecto.

Cada uno juega un papel importante en la construcción de sistemas organizados, flexibles y escalables.

 

Vamos a crear un ejemplo más específico que combine objetos, métodos, clases y un array de objetos, todo con encapsulamiento y una aplicación práctica.

Imagina que estamos desarrollando un sistema simple para gestionar un carrito de compras en línea. Cada producto será representado como un objeto, y el carrito estará gestionado por una clase que usará un array de objetos (productos). Además, el acceso a los datos internos del carrito estará encapsulado.

1. Código: Carrito de Compras

 class Carrito {
  // Propiedades privadas
  #productos = []; // Array de objetos encapsulado
  #total = 0;

  // Método público para agregar productos
  agregarProducto(nombre, precio, cantidad) {
    const producto = { nombre, precio, cantidad };
    this.#productos.push(producto);
    this.#total += precio * cantidad;
    console.log(`${cantidad}x ${nombre} agregado al carrito.`);
  }

  // Método público para eliminar productos
  eliminarProducto(nombre) {
    const index = this.#productos.findIndex(p => p.nombre === nombre);
    if (index !== -1) {
      const productoEliminado = this.#productos[index];
      this.#total -= productoEliminado.precio * productoEliminado.cantidad;
      this.#productos.splice(index, 1);
      console.log(`${productoEliminado.nombre} eliminado del carrito.`);
    } else {
      console.log(`El producto ${nombre} no está en el carrito.`);
    }
  }

  // Método público para mostrar los productos
  mostrarProductos() {
    console.log("Productos en el carrito:");
    this.#productos.forEach(producto => {
      console.log(`- ${producto.cantidad}x ${producto.nombre} ($${producto.precio} c/u)`);
    });
  }

  // Método público para calcular el total
  calcularTotal() {
    console.log(`Total a pagar: $${this.#total.toFixed(2)}`);
    return this.#total;
  }
}

// Uso de la clase
const miCarrito = new Carrito();

// Agregar productos
miCarrito.agregarProducto("Laptop", 1200, 1);
miCarrito.agregarProducto("Mouse", 25, 2);

// Mostrar productos
miCarrito.mostrarProductos();

// Calcular total
miCarrito.calcularTotal();

// Eliminar un producto
miCarrito.eliminarProducto("Mouse");

// Mostrar productos y total después de eliminar
miCarrito.mostrarProductos();
miCarrito.calcularTotal(); 

2. ¿Qué está pasando aquí?

  1. Clase: Carrito encapsula toda la lógica relacionada con el carrito de compras.
  • Las propiedades #productos (un array de objetos) y #total están encapsuladas como privadas (#), lo que significa que no pueden ser modificadas directamente desde fuera de la clase.
  • Los métodos públicos como agregarProducto, eliminarProducto y mostrarProductos son las únicas formas de interactuar con los datos.
  1. Objeto: Cada producto dentro del carrito es un objeto con las propiedades nombre, precio y cantidad.
  2. Método: Los métodos (agregarProducto, eliminarProducto, etc.) definen acciones específicas que se pueden realizar sobre el carrito.
  3. Array de objetos: #productos es un array que almacena múltiples objetos (cada uno representando un producto).

3. Relación con el encapsulamiento

  • Seguridad: Las propiedades privadas (#productos y #total) están protegidas contra accesos o modificaciones directas. Por ejemplo, no puedes hacer miCarrito.#productos.push({...}) desde fuera de la clase.
  • Modularidad: La lógica del carrito está aislada, lo que facilita su mantenimiento.
  • Flexibilidad: Puedes crear múltiples instancias de Carrito, cada una con su propio estado.

4. ¿Cómo usarlo en una página HTML?

 <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Carrito de Compras</title>
  </head>
  <body>
    <h1>Carrito de Compras</h1>
    <button onclick="agregarProducto('Teclado', 50, 1)">Agregar Teclado ($50)</button>
    <button onclick="agregarProducto('Monitor', 200, 1)">Agregar Monitor ($200)</button>
    <button onclick="mostrarCarrito()">Mostrar Carrito</button>
    <button onclick="calcularTotal()">Calcular Total</button>
    <script src="carrito.js"></script>
  </body>
</html> 

JavaScript (carrito.js):

 const miCarrito = new Carrito();

function agregarProducto(nombre, precio, cantidad) {
  miCarrito.agregarProducto(nombre, precio, cantidad);
}

function mostrarCarrito() {
  miCarrito.mostrarProductos();
}

function calcularTotal() {
  miCarrito.calcularTotal();
}
 

Finalidad de cada concepto

  1. Objeto: Representa una unidad específica (un producto).
  2. Método: Realiza una acción sobre el carrito (agregar, eliminar, mostrar).
  3. Clase: Define la estructura y el comportamiento del carrito.
  4. Array de objetos: Almacena la lista de productos en un lugar centralizado.

Esto ilustra cómo combinar métodos, objetos, clases y arrays de objetos con encapsulamiento para lograr un sistema organizado, flexible y seguro.

 

Vamos a ampliar el sistema de carrito de compras en un caso más complejo, integrando conceptos avanzados como clases, objetos, arrays de objetos, métodos encapsulados y una estructura para manejar distintos usuarios, múltiples carritos y promociones.

Problema: Sistema de Compra para una Plataforma de e-Commerce

El objetivo será: 

  1. Gestionar múltiples usuarios.
  2. Permitir que cada usuario tenga su propio carrito de compras.
  3. Aplicar descuentos y promociones automáticamente según el tipo de usuario (cliente regular, VIP, etc.).
  4. Integrar una funcionalidad para simular el proceso de pago y generar recibos.
 

1. Código: Sistema Completo de e-Commerce

Clase para Usuario

Cada usuario tendrá una clase que encapsula sus datos y su carrito asociado.

javascript
class Usuario {
  #carrito; // Carrito privado

  constructor(nombre, tipo) {
    this.nombre = nombre;
    this.tipo = tipo; // Tipo: Regular o VIP
    this.#carrito = new Carrito(); // Cada usuario tiene su propio carrito
  }

  agregarProducto(nombre, precio, cantidad) {
    this.#carrito.agregarProducto(nombre, precio, cantidad);
  }

  eliminarProducto(nombre) {
    this.#carrito.eliminarProducto(nombre);
  }

  mostrarCarrito() {
    console.log(`Carrito de ${this.nombre} (${this.tipo}):`);
    this.#carrito.mostrarProductos();
  }

  calcularTotal() {
    let total = this.#carrito.calcularTotal();
    // Aplicar descuento según el tipo de usuario
    if (this.tipo === "VIP") {
      total *= 0.9; // 10% de descuento para VIP
      console.log(`Descuento VIP aplicado: Total con descuento: $${total.toFixed(2)}`);
    }
    return total;
  }

  pagar() {
    const total = this.calcularTotal();
    console.log(`Recibo generado para ${this.nombre}:`);
    console.log(`Total a pagar: $${total.toFixed(2)}`);
  }
}

Clase para Carrito

El carrito sigue encapsulando sus datos y métodos.

javascript
class Carrito {
  #productos = [];
  #total = 0;

  agregarProducto(nombre, precio, cantidad) {
    const producto = { nombre, precio, cantidad };
    this.#productos.push(producto);
    this.#total += precio * cantidad;
    console.log(`${cantidad}x ${nombre} agregado al carrito.`);
  }

  eliminarProducto(nombre) {
    const index = this.#productos.findIndex(p => p.nombre === nombre);
    if (index !== -1) {
      const productoEliminado = this.#productos[index];
      this.#total -= productoEliminado.precio * productoEliminado.cantidad;
      this.#productos.splice(index, 1);
      console.log(`${productoEliminado.nombre} eliminado del carrito.`);
    } else {
      console.log(`El producto ${nombre} no está en el carrito.`);
    }
  }

  mostrarProductos() {
    this.#productos.forEach(producto => {
      console.log(`- ${producto.cantidad}x ${producto.nombre} ($${producto.precio} c/u)`);
    });
  }

  calcularTotal() {
    return this.#total;
  }
}
 

2. Ejemplo Complejo: Simulación del Uso

Vamos a crear múltiples usuarios y manejar sus carritos independientemente. Esto incluye descuentos automáticos para usuarios VIP.

javascript
// Crear usuarios
const usuario1 = new Usuario("Milton", "Regular");
const usuario2 = new Usuario("Ana", "VIP");

// Usuario 1 agrega productos
usuario1.agregarProducto("Laptop", 1200, 1);
usuario1.agregarProducto("Mouse", 25, 2);
usuario1.mostrarCarrito();

// Usuario 2 agrega productos
usuario2.agregarProducto("Monitor", 300, 1);
usuario2.agregarProducto("Teclado Mecánico", 150, 1);
usuario2.mostrarCarrito();

// Eliminar producto del Usuario 1
usuario1.eliminarProducto("Mouse");
usuario1.mostrarCarrito();

// Calcular total y pagar (incluye descuento automático para VIP)
usuario1.pagar();
usuario2.pagar();
 

3. Relación entre las Clases

Entidad Propósito
Usuario Representa cada cliente, almacena datos y maneja el carrito de forma encapsulada.
Carrito Encapsula los datos y métodos de un carrito de compras, como agregar, eliminar y calcular el total.
 
  •  Encapsulamiento: Los datos privados (#productos y #carrito) están protegidos. Solo los métodos públicos permiten interactuar con estos datos.  
  • Métodos: Definen acciones como agregar, eliminar y calcular el total. 
  • Array de objetos: El carrito usa un array (#productos) para gestionar múltiples objetos producto.

4. Extensión: Integrar Promociones

Puedes extender el sistema para aplicar diferentes promociones según criterios personalizados, como días de la semana o categorías de productos.

javascript
class Usuario {
  // Agregar método para promociones
  aplicarPromociones() {
    this.#carrito.#productos.forEach(producto => {
      if (producto.nombre === "Monitor") {
        producto.precio *= 0.8; // Descuento del 20%
        console.log(`Descuento aplicado al Monitor: Nuevo precio: $${producto.precio}`);
      }
    });
  }
}
 

5. Relación con HTML

Podemos integrar el sistema en una página web para gestionar los usuarios y carritos desde la interfaz.

HTML:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sistema de Compra</title>
  </head>
  <body>
    <h1>Sistema de Compra</h1>
    <button onclick="usuario1.agregarProducto('Laptop', 1200, 1)">Agregar Laptop ($1200)</button>
    <button onclick="usuario2.agregarProducto('Monitor', 300, 1)">Agregar Monitor ($300 - VIP)</button>
    <button onclick="usuario1.mostrarCarrito()">Mostrar Carrito de Milton</button>
    <button onclick="usuario2.mostrarCarrito()">Mostrar Carrito de Ana</button>
    <button onclick="usuario1.pagar()">Pagar Milton</button>
    <button onclick="usuario2.pagar()">Pagar Ana</button>
    <script src="sistema.js"></script>
  </body>
</html>

JavaScript (sistema.js):

javascript
// Crear usuarios
const usuario1 = new Usuario("Milton", "Regular");
const usuario2 = new Usuario("Ana", "VIP");
 

Ventajas del Sistema

  1. Escalabilidad: Puedes agregar más usuarios y carritos fácilmente.

  2. Flexibilidad: El encapsulamiento protege los datos y organiza la lógica.

  3. Modularidad: Cada clase tiene responsabilidades claras.

 

 Vamos a mejorar nuestro sistema de carrito de compras agregando soporte para múltiples idiomas y una simulación de inventario. Con estas características, el sistema será más avanzado y adaptable.

1. Soporte para Múltiples Idiomas

Para agregar soporte multilingüe, utilizaremos un objeto que almacenará las traducciones. El sistema cambiará automáticamente el idioma según la configuración seleccionada por el usuario.

 

Implementación del Soporte Multilingüe

Extendemos la clase Usuario para manejar el idioma y usamos un objeto de traducciones.

javascript
// Objeto de traducciones
const traducciones = {
  en: {
    carritoTitulo: "Shopping Cart",
    agregarProducto: "Add Product",
    mostrarProductos: "Show Cart",
    total: "Total",
    pagar: "Checkout",
  },
  es: {
    carritoTitulo: "Carrito de Compras",
    agregarProducto: "Agregar Producto",
    mostrarProductos: "Mostrar Carrito",
    total: "Total",
    pagar: "Pagar",
  },
};

class Usuario {
  #carrito;
  idioma;

  constructor(nombre, tipo, idioma = "en") {
    this.nombre = nombre;
    this.tipo = tipo; // Regular o VIP
    this.idioma = idioma;
    this.#carrito = new Carrito();
  }

  traducir(clave) {
    return traducciones[this.idioma][clave];
  }

  agregarProducto(nombre, precio, cantidad) {
    this.#carrito.agregarProducto(nombre, precio, cantidad);
    console.log(`${cantidad}x ${nombre} ${this.traducir("agregarProducto")}`);
  }

  mostrarCarrito() {
    console.log(`${this.traducir("carritoTitulo")} de ${this.nombre} (${this.tipo}):`);
    this.#carrito.mostrarProductos();
  }

  calcularTotal() {
    let total = this.#carrito.calcularTotal();
    if (this.tipo === "VIP") {
      total *= 0.9; // Descuento VIP
      console.log(`Descuento VIP aplicado: ${this.traducir("total")}: $${total.toFixed(2)}`);
    }
    return total;
  }

  pagar() {
    const total = this.calcularTotal();
    console.log(`${this.traducir("pagar")} ${this.nombre}:`);
    console.log(`${this.traducir("total")}: $${total.toFixed(2)}`);
  }
}
 

2. Simulación de Inventario

El inventario será gestionado por una clase aparte que verificará la disponibilidad de productos antes de agregarlos al carrito.

 

Clase de Inventario

javascript
class Inventario {
  constructor() {
    this.productos = [
      { nombre: "Laptop", precio: 1200, stock: 5 },
      { nombre: "Mouse", precio: 25, stock: 10 },
      { nombre: "Monitor", precio: 300, stock: 3 },
      { nombre: "Teclado", precio: 50, stock: 8 },
    ];
  }

  verificarStock(nombre, cantidad) {
    const producto = this.productos.find(p => p.nombre === nombre);
    if (producto && producto.stock >= cantidad) {
      return true;
    }
    console.log(`Producto "${nombre}" no disponible o no hay suficiente stock.`);
    return false;
  }

  reducirStock(nombre, cantidad) {
    const producto = this.productos.find(p => p.nombre === nombre);
    if (producto) {
      producto.stock -= cantidad;
    }
  }

  mostrarInventario() {
    console.log("Inventario Actual:");
    this.productos.forEach(p => {
      console.log(`- ${p.nombre}: $${p.precio} (Stock: ${p.stock})`);
    });
  }
}
 

Integrar Inventario con el Usuario

Modificamos la clase Usuario para interactuar con el inventario.

javascript
class Usuario {
  #carrito;
  idioma;

  constructor(nombre, tipo, idioma = "en") {
    this.nombre = nombre;
    this.tipo = tipo; // Regular o VIP
    this.idioma = idioma;
    this.#carrito = new Carrito();
  }

  agregarProducto(nombre, precio, cantidad, inventario) {
    if (inventario.verificarStock(nombre, cantidad)) {
      this.#carrito.agregarProducto(nombre, precio, cantidad);
      inventario.reducirStock(nombre, cantidad);
      console.log(`${cantidad}x ${nombre} ${this.traducir("agregarProducto")}`);
    }
  }

  // Métodos traducir, mostrarCarrito, calcularTotal, pagar permanecen igual
}
 

3. Código Final de Simulación

javascript
// Crear inventario
const inventario = new Inventario();

// Crear usuarios
const usuario1 = new Usuario("Milton", "Regular", "es");
const usuario2 = new Usuario("Ana", "VIP", "en");

// Mostrar inventario inicial
inventario.mostrarInventario();

// Usuario 1 agrega productos
usuario1.agregarProducto("Laptop", 1200, 1, inventario);
usuario1.agregarProducto("Mouse", 25, 2, inventario);

// Usuario 2 agrega productos
usuario2.agregarProducto("Monitor", 300, 2, inventario);

// Mostrar carritos
usuario1.mostrarCarrito();
usuario2.mostrarCarrito();

// Mostrar inventario después de las compras
inventario.mostrarInventario();

// Usuarios pagan
usuario1.pagar();
usuario2.pagar();
 

4. Integrar con HTML

Agrega botones para manipular el sistema directamente desde la interfaz.

HTML:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sistema de Compra Avanzado</title>
  </head>
  <body>
    <h1>Sistema de Compra Avanzado</h1>
    <button onclick="comprarProducto('Milton', 'Laptop', 1200, 1)">Milton: Comprar Laptop</button>
    <button onclick="comprarProducto('Ana', 'Monitor', 300, 1)">Ana: Comprar Monitor</button>
    <button onclick="mostrarInventario()">Mostrar Inventario</button>
    <script src="sistemaAvanzado.js"></script>
  </body>
</html>

JavaScript (sistemaAvanzado.js):

javascript
const inventario = new Inventario();
const usuario1 = new Usuario("Milton", "Regular", "es");
const usuario2 = new Usuario("Ana", "VIP", "en");

const usuarios = { Milton: usuario1, Ana: usuario2 };

function comprarProducto(nombreUsuario, nombreProducto, precio, cantidad) {
  const usuario = usuarios[nombreUsuario];
  usuario.agregarProducto(nombreProducto, precio, cantidad, inventario);
}

function mostrarInventario() {
  inventario.mostrarInventario();
}
 

Ventajas de las Nuevas Funcionalidades

  •  Soporte para Múltiples Idiomas: Mejora la experiencia del usuario en diferentes regiones. 
  • Escalabilidad: Puedes agregar más usuarios, productos y funciones como reportes o cupones fácilmente. 
  • Inventario: Asegura la disponibilidad de productos y permite rastrear el stock.
Artículo Anterior Artículo Siguiente