La encapsulación es un concepto que proviene de la programación orientada a objetos (POO) que consiste en ocultar y proteger los detalles internos de una clase
La encapsulación tiene dos aspectos principales:
- Ocultar el estado interno de los objetos: Los objetos pueden tener propiedades privadas, que no son accesibles directamente desde fuera de la clase
- Proveer una interfaz pública: La clase puede exponer métodos públicos que permiten interactuar con sus propiedades de manera controlada
Es decir, se trata de proteger el acceso directo a los datos y exponer solo lo necesario para que otras partes del programa interactúen con esa clase.
Al ocultar el estado interno de los objetos y proporcionar una interfaz pública controlada, aseguramos que nuestros objetos sean más robustos, fáciles de mantener y menos propensos a errores.
Si quieres aprender más puedes consultar
Propiedades privadas
En JavaScript ES2022 introdujo la sintaxis de campos privados. Para ello se antepone el nombre de la propiedad con el prefijo #
.
Las propiedades que utilizan este prefijo son accesibles solo dentro de la clase en la que están definidas (no pueden ser accedidas ni modificadas desde fuera de la clase).
class Persona {
#nombre;
constructor(nombre) {
this.#nombre = nombre;
}
obtenerNombre() {
return this.#nombre;
}
}
const persona1 = new Persona("Juan");
// Acceso correcto a través de un método público
console.log(persona1.obtenerNombre()); // "Juan"
// Esto causará un error: "Cannot read private member"
console.log(persona1.#nombre); // Error
En este ejemplo:
#nombre
es una propiedad privada. Solo puede ser accedida dentro de la clasePersona
.obtenerNombre()
es un método público que permite acceder al valor de#nombre
.
Métodos privados
Los métodos también pueden ser privados. Al igual que las propiedades, se definen con el prefijo #
:
class Usuario {
#claveSecreta;
constructor(clave) {
this.#claveSecreta = clave;
}
#mostrarClave() {
console.log(`La clave secreta es: ${this.#claveSecreta}`);
}
autenticar() {
this.#mostrarClave(); // Llamada válida desde dentro de la clase
}
}
const usuario1 = new Usuario("12345");
usuario1.autenticar(); // La clave secreta es: 12345
// Esto causará un error: "Cannot read private member"
// usuario1.#mostrarClave(); // Error
En este ejemplo, #mostrarClave()
es un método privado. Solo puede ser llamado desde dentro de la clase, no desde fuera.
Métodos getters y setters
La encapsulación encaja muy bien con el uso de métodos getter y setter.
class Persona {
#edad;
constructor(edad) {
this.#edad = edad;
}
get edad() {
return this.#edad;
}
set edad(nuevaEdad) {
if (nuevaEdad > 0) {
this.#edad = nuevaEdad;
} else {
console.log("La edad debe ser positiva.");
}
}
}
const persona2 = new Persona(25);
console.log(persona2.edad); // 25
persona2.edad = 30; // Modifica la edad
console.log(persona2.edad); // 30
persona2.edad = -5; // La edad debe ser positiva.
En este ejemplo:
- El getter
edad
permite acceder al valor de la propiedad privada#edad
. - El setter
edad
permite modificar el valor de#edad
solo si es un número positivo.
Ejemplo simple de encapsulación
Vamos a ver un ejemplo básico de cómo se puede encapsular un dato dentro de una clase:
class CuentaBancaria {
// Propiedad privada (accedida solo desde la clase)
#balance;
constructor(inicial) {
this.#balance = inicial;
}
// Método público para obtener el balance
obtenerBalance() {
return this.#balance;
}
// Método público para depositar dinero
depositar(cantidad) {
if (cantidad > 0) {
this.#balance += cantidad;
} else {
console.log("El cantidad debe ser positivo.");
}
}
// Método público para retirar dinero
retirar(cantidad) {
if (cantidad <= this.#balance) {
this.#balance -= cantidad;
} else {
console.log("Fondos insuficientes.");
}
}
}
const cuenta1 = new CuentaBancaria(1000);
console.log(cuenta1.obtenerBalance()); // 1000
cuenta1.depositar(500);
console.log(cuenta1.obtenerBalance()); // 1500
cuenta1.retirar(200);
console.log(cuenta1.obtenerBalance()); // 1300
En este ejemplo:
- La propiedad
#balance
es privada y no puede ser accedida directamente desde fuera de la clase. - Los métodos
depositar()
,retirar()
yobtenerBalance()
permiten interactuar con el balance de la cuenta de forma controlada.
También podíamos haber usado métodos setter y getter, pero así vemos otra forma con métodos normales