Encapsulación con Propiedades Privadas en Clases de JavaScript
La encapsulación es un concepto clave en la programación orientada a objetos que permite proteger el acceso directo a los datos de un objeto. En JavaScript, las propiedades privadas se utilizan para restringir el acceso a ciertos datos y evitar que sean modificados desde fuera de la clase. Esto proporciona un mayor control sobre el estado del objeto y ayuda a mantener la integridad de los datos.
En este artículo exploraremos cómo se implementa la encapsulación con propiedades privadas en clases, las ventajas de su uso y algunos ejemplos prácticos.
¿Qué son las Propiedades Privadas?
Las propiedades privadas en JavaScript son atributos de una clase que solo pueden ser accedidos o modificados desde dentro de la propia clase. A diferencia de las propiedades públicas, las privadas no son visibles desde el exterior lo que ayuda a proteger la integridad de los datos.
Sintaxis para Definir Propiedades Privadas
Para definir una propiedad privada, se utiliza el símbolo #
antes del nombre de la propiedad. Esta sintaxis fue introducida en ES2022.
class CuentaBancaria {
#saldo; // Propiedad privada
constructor(titular, saldoInicial) {
this.titular = titular;
this.#saldo = saldoInicial;
}
mostrarSaldo() {
return `El saldo de ${this.titular} es ${this.#saldo} dólares.`;
}
}
const cuenta = new CuentaBancaria('Ana', 1000);
console.log(cuenta.mostrarSaldo()); // Output: El saldo de Ana es 1000 dólares
console.log(cuenta.#saldo);
SyntaxError: Private field '#saldo' must be declared in an enclosing class
En este ejemplo la propiedad #saldo
es privada y solo puede ser accedida desde los métodos de la clase CuentaBancaria
.
Ventajas de Usar Propiedades Privadas
- Protección de Datos: Permite proteger el estado interno del objeto, evitando modificaciones no controladas desde fuera de la clase.
- Encapsulación y Abstracción: Facilita la implementación de la encapsulación, ocultando los detalles de la implementación y exponiendo solo una interfaz pública.
- Mejora la Mantenibilidad: Ayuda a evitar dependencias directas en la estructura interna del objeto, lo que facilita el mantenimiento del código.
Acceder a Propiedades Privadas Desde Dentro de la Clase
Las propiedades privadas solo pueden ser leídas o modificadas mediante métodos definidos dentro de la clase. Esto proporciona un control total sobre cómo se accede y modifica el estado interno del objeto.
Ejemplo: Métodos para Acceder a Propiedades Privadas
class Usuario {
#password; // Propiedad privada
constructor(nombre, password) {
this.nombre = nombre;
this.#password= password;
}
validarPassword(password) {
return this.#password === password;
}
cambiarPassword(nuevoPassword) {
this.#password= nuevoPassword;
}
}
const usuario = new Usuario('Carlos', 'secreto123');
console.log(usuario.validarPassword('secreto123'));
usuario.cambiarPassword('nuevoSecreto');
console.log(usuario.validarPassword('nuevoSecreto'));
true
true
En el ejemplo anterior la propiedad #password
es privada y solo puede ser accedida o modificada a través de los métodos validarPassword()
y cambiarPassword()
.
Encapsulación con Getters y Setters
Los getters y setters permiten controlar el acceso a las propiedades privadas de una forma más segura y proporcionar una interfaz pública para interactuar con ellas.
Ejemplo: Uso de Getters y Setters para Encapsular Propiedades Privadas
class Producto {
#precio;
constructor(nombre, precio) {
this.nombre = nombre;
this.#precio = precio;
}
get precio() {
return this.#precio;
}
set precio(nuevoPrecio) {
if (nuevoPrecio > 0) {
this.#precio = nuevoPrecio;
} else {
console.log('El precio debe ser mayor que cero.');
}
}
}
const producto = new Producto('Laptop', 1500);
console.log(producto.precio);
producto.precio = 1800;
console.log(producto.precio);
producto.precio = -200;
1500
1800
"El precio debe ser mayor que cero."
En este ejemplo el uso de getters y setters permite acceder y modificar la propiedad privada #precio
de manera controlada.
Consideraciones al Usar Propiedades Privadas
- Acceso Restringido: Las propiedades privadas solo son accesibles desde dentro de la clase, lo que puede ser limitante si se necesita interactuar con ellas desde fuera.
- No Son Parte del Objeto Literal: Las propiedades privadas no se pueden definir en un objeto literal ni acceder a través de la notación de corchetes (
obj['propiedad']
). - Compatibilidad: La sintaxis de propiedades privadas fue introducida en ES2022, por lo que es necesario asegurarse de que el entorno de ejecución lo soporte.
Ejemplo Completo: Encapsulación y Protección de Datos
class Carro {
#marca;
#modelo;
#año;
constructor(marca, modelo, año) {
this.#marca = marca;
this.#modelo = modelo;
this.#año = año;
}
get detalles() {
return `${this.#marca} ${this.#modelo}, Año ${this.#año}`;
}
actualizarAño(nuevoAño) {
if (nuevoAño >= this.#año) {
this.#año = nuevoAño;
} else {
console.log('El año no puede ser menor al año actual del carro.');
}
}
}
const miCarro = new Carro('Toyota', 'Corolla', 2020);
console.log(miCarro.detalles);
miCarro.actualizarAño(2021);
console.log(miCarro.detalles);
miCarro.actualizarAño(2019);
"Toyota Corolla, Año 2020"
"Toyota Corolla, Año 2021"
"El año no puede ser menor al año actual del carro."
En este ejemplo las propiedades privadas #marca
, #modelo
y #año
están encapsuladas, protegiendo el estado interno del objeto y proporcionando un control seguro sobre sus modificaciones.
Conclusión
La encapsulación con propiedades privadas en JavaScript ofrece un enfoque moderno y seguro para proteger los datos de una clase y controlar cómo se accede y modifica su estado interno. Con la introducción de la sintaxis de propiedades privadas en ES2022 los desarrolladores tienen ahora una forma más eficiente de implementar este tipo de funcionalidad en sus aplicaciones.
En el próximo artículo, exploraremos el uso de Getters y Setters en Clases para aprender cómo definir accesores para controlar el acceso a las propiedades.