Getters y Setters en Clases de JavaScript
Los getters y setters en JavaScript son funciones especiales que se utilizan para controlar el acceso a las propiedades de un objeto. Permiten definir cómo se deben leer o escribir los valores de las propiedades, proporcionando una interfaz más segura y controlada para interactuar con los datos del objeto. En las clases, los getters y setters ayudan a implementar la encapsulación y mejorar la mantenibilidad del código.
En este artículo exploraremos cómo funcionan los getters y setters en clases, sus ventajas, cómo usarlos correctamente y algunos ejemplos prácticos.
¿Qué son los Getters y Setters?
Estas son funciones que se definen para leer y modificar los valores de las propiedades de un objeto. A través de estas se puede controlar cómo se accede o cambia el valor de una propiedad.
- Getters (
get
): Permiten obtener el valor de una propiedad. - Setters (
set
): Permiten establecer el valor de una propiedad.
Sintaxis para Definir Getters y Setters
Los getters y setters se definen dentro de la clase utilizando las palabras clave get
y set
, respectivamente.
class Persona {
constructor(nombre, edad) {
this.nombre = nombre;
this._edad = edad; // Uso de un guion bajo para la propiedad interna
}
get edad() {
return this._edad;
}
set edad(nuevaEdad) {
if (nuevaEdad > 0) {
this._edad = nuevaEdad;
} else {
console.log('La edad debe ser un número positivo.');
}
}
}
const persona1 = new Persona('Ana', 25);
console.log(persona1.edad);
persona1.edad = 30;
console.log(persona1.edad);
persona1.edad = -5;
25
30
"La edad debe ser un número positivo."
En el ejemplo anterior se define un getter y un setter para la propiedad edad
. El getter permite obtener el valor de _edad
, mientras que el setter valida el nuevo valor antes de asignarlo.
Ventajas de Usar Getters y Setters
- Control de Acceso a las Propiedades: Permiten controlar cómo se accede y modifica el valor de una propiedad, lo que es útil para validar datos antes de actualizarlos.
- Encapsulación y Ocultación de Datos: Facilitan la encapsulación al exponer solo una interfaz pública controlada, ocultando los detalles de implementación.
- Mantienen la Sintaxis de Propiedades: Los getters y setters se usan como si fueran propiedades, manteniendo la sintaxis simple y consistente para el acceso a los datos.
- Flexibilidad para Cambiar la Implementación Interna: Se puede modificar la forma en que se calcula o almacena el valor sin afectar la interfaz pública de la clase.
Definir Getters y Setters para Propiedades Privadas
Aunque los estas funcionalidades son útiles para encapsular propiedades públicas, también se pueden usar para acceder a propiedades privadas. Esto permite mantener el acceso controlado incluso con la nueva sintaxis de propiedades privadas (#
).
Ejemplo: Getters y Setters con Propiedades Privadas
class Cuenta {
#saldo = 0; // Propiedad privada
get saldo() {
return this.#saldo;
}
set saldo(nuevoSaldo) {
if (nuevoSaldo >= 0) {
this.#saldo = nuevoSaldo;
} else {
console.log('El saldo no puede ser negativo.');
}
}
}
const cuenta = new Cuenta();
cuenta.saldo = 1000;
console.log(cuenta.saldo);
cuenta.saldo = -500;
En el ejemplo anterior se utiliza un getter para acceder a la propiedad privada #saldo
y un setter para validar y modificar su valor.
Usos Comunes de Getters y Setters en Clases
- Validación de Datos: Los setters son útiles para validar los valores que se asignan a las propiedades, asegurando que cumplen con ciertos requisitos.
- Cálculo de Propiedades Derivadas: Los getters permiten calcular el valor de una propiedad en función de otras propiedades del objeto.
- Control de Acceso y Protección de Datos: Facilitan el control sobre el acceso a los datos sensibles de la clase, permitiendo leer o modificar el estado de manera controlada.
Ejemplo: Cálculo de Propiedades Derivadas
class Rectangulo {
constructor(ancho, alto) {
this.ancho = ancho;
this.alto = alto;
}
get area() {
return this.ancho * this.alto;
}
}
const rectangulo = new Rectangulo(10, 5);
console.log(rectangulo.area);
50
En este ejemplo el getter area
calcula el área del rectángulo en función de las propiedades ancho
y alto
.
Buenas Prácticas para Usar Getters y Setters
- Evitar Lógica Compleja en Getters y Setters: Estas funciones deben ser simples. La lógica compleja o las operaciones que consumen mucho tiempo no son recomendables.
- Utilizar Nombres Claros y Consistentes: Los nombres deben ser claros y describir adecuadamente la propiedad que están controlando.
- Combinar Getters y Setters con Propiedades Privadas: Para una mayor encapsulación, considera combinar getters y setters con propiedades privadas, lo que proporciona un control total sobre el acceso a los datos.
Ejemplo Completo: Encapsulación y Validación con Getters y Setters
class Empleado {
#salario;
constructor(nombre, salario) {
this.nombre = nombre;
this.#salario = salario;
}
get salario() {
return this.#salario;
}
set salario(nuevoSalario) {
if (nuevoSalario >= 0) {
this.#salario = nuevoSalario;
} else {
console.log('El salario no puede ser negativo.');
}
}
get detalles() {
return `${this.nombre} tiene un salario de ${this.#salario} dólares.`;
}
}
const empleado = new Empleado('Carlos', 3000);
console.log(empleado.detalles);
empleado.salario = 3500;
console.log(empleado.detalles);
empleado.salario = -100;
"Carlos tiene un salario de 3000 dólares."
"Carlos tiene un salario de 3500 dólares."
"El salario no puede ser negativo."
En el código anterior se utilizan getters y setters para controlar el acceso a la propiedad privada #salario
y proporcionar una validación simple.
Consideraciones al Usar Getters y Setters
- Acceso Inesperado a Propiedades: Si se utilizan en exceso, los getters y setters pueden causar efectos secundarios no deseados o complejidad adicional en el acceso a las propiedades.
- Compatibilidad con Herramientas de Análisis Estático: Algunas herramientas pueden no detectar correctamente el uso de getters y setters, lo que podría afectar la generación de documentación o el análisis de dependencias.
Conclusión
Los getters y setters en JavaScript son herramientas poderosas para implementar la encapsulación en las clases. Permiten controlar cómo se accede y modifica el estado de un objeto, ofreciendo una forma segura y flexible de gestionar los datos. Sin embargo es importante usarlos adecuadamente para evitar complicaciones innecesarias.
En el próximo artículo, veremos el uso de Mixins en JavaScript, una técnica para combinar funcionalidades entre clases sin herencia.