Saltar al contenido principal

Classes en JavaScript

¿Qué es una clase?

Una clase es una plantilla o modelo para crear objetos.
Permite definir de forma organizada las propiedades (atributos) y los comportamientos (métodos) que tendrán los objetos creados a partir de ella.

Podemos imaginar una clase como un molde, y los objetos como las figuras creadas con ese molde.

Estructura básica de una clase

class NombreClase {
constructor(parametro1, parametro2) {
this.propiedad1 = parametro1;
this.propiedad2 = parametro2;
}

metodoEjemplo() {
console.log("Este es un método de la clase");
}
}

Crear un objeto (instancia) de una clase

Para crear un nuevo objeto a partir de una clase usamos la palabra clave new.
Cada vez que usamos new, creamos una instancia (un objeto individual) basada en la clase.

class Persona {
constructor(nombre, edad) {
this.nombre = nombre;
this.edad = edad;
}

saludar() {
console.log(`Hola, mi nombre es ${this.nombre}`);
}
}

let persona1 = new Persona("María", 25);

Podemos crear tantas instancias como queramos de la misma clase, todas ellas siguiendo la misma "plantilla".

let persona2 = new Persona("Juan", 25);
let persona3 = new Persona("Nuria", 12);
let persona4 = new Persona("Esther", 21);

Como podemos observar, podemos acceder tanto a las propiedades como a los métodos de la clase con la estructura instancia.propiedad o instancia.metodo(). En el siguiente ejemplo, accedemos a la propiedad nombrey al método saludar().

persona2.nombre; // "Juan"
persona2.saludar(); // Hola, mi nombre es Juan

Propiedades y métodos

Las propiedades son las características que definen a un objeto, mientras que los métodos son las acciones que puede realizar.

En una clase, las propiedades se definen dentro del constructor, y los métodos directamente en el cuerpo de la clase.

class Coche {
constructor(marca, modelo) {
this.marca = marca;
this.modelo = modelo;
}

arrancar() {
console.log(`El ${this.marca} ${this.modelo} está arrancando...`);
}

detener() {
console.log(`El ${this.marca} ${this.modelo} se ha detenido.`);
}
}

let miCoche = new Coche("Toyota", "Corolla");
miCoche.arrancar();

En este ejemplo las propiedades eran marca y modelo, por eso están en el consutrctor. Mientras que los métodos eran arrancar() y detener() por lo que se definen abajo.

Es muy importante tener en cuenta que al crear la instancia de la clase, ésta reciba el mismo número de parámetros que propiedades definidas en el constructor. Para el ejemplo anterior, si la clase Coche tenía en el constructor las propiedades marca y modelo, necesariamente al crear la instancia miCoche debíamos pasarle dos valores, equivaliendo el primero a la marca y el segundo al modelo.

Hemos de tener en cuenta que si el método que creamos recibe un parámetro al definirlo en la clase, necesariamente ha de recibir un parámetro cuando se "llame" desde la instancia, al igual que haríamos con una función o método normalmente.

class Persona {
constructor(nombre, edad) {
this.nombre = nombre;
this.edad = edad;
}

sumar_edad(anyo) {
this.edad += anyo;
console.log(`Ahora mi edad es ${this.edad}`);
}
}

let nuria = new Persona("Nuria", 23);
nuria.sumar_edad(1); // Ahora mi edad es 24

En este ejemplo, el método sumar_edad suma a la edad actual de la instancia el número que pasemos por parámetro.

Observad también que para modificar la edad de la instancia dentro del método sumar_edad, he hecho referencia a ella a través de this.edad, ya que cuando quiero utilizar las propiedades de la clase he de poner delante siempre el this.

Añadir nuevos métodos o propiedades

En JavaScript, también podemos añadir métodos o propiedades después de haber definido una clase, utilizando el prototype.

¿Qué es prototype?
El prototype es un mecanismo que permite añadir nuevas funcionalidades a objetos o clases ya existentes sin modificar su definición original.

Coche.prototype.color = "rojo";
Coche.prototype.pitar = function() {
console.log("¡Piiiiip!");
};

miCoche.pitar(); // ¡Piiiiip!

Encapsulación: getters y setters

¿Qué es la encapsulación?
La encapsulación es un principio de la programación orientada a objetos que consiste en proteger los datos internos de un objeto para evitar que se modifiquen directamente desde fuera.
Para ello, se usan getters (accesores) y setters (modificadores).

¿Qué son los getters y setters?

  • Un getter es una función que permite leer el valor de una propiedad.
  • Un setter es una función que permite modificar una propiedad de forma controlada.
class Producto {
constructor(nombre, precio) {
this._nombre = nombre;
this._precio = precio;
}

get nombre() {
return this._nombre;
}

set precio(nuevoPrecio) {
if (nuevoPrecio > 0) {
this._precio = nuevoPrecio;
} else {
console.log("El precio debe ser positivo");
}
}
}

let producto1 = new Producto("Camiseta", 20);
console.log(producto1.nombre); // Camiseta
producto1.precio = -5; // El precio debe ser positivo

🔹 Nota: el guion bajo _ delante de una propiedad es una convención para indicar que es interna o privada.


Herencia: extends y super

¿Qué es la herencia?
La herencia permite que una clase (hija) utilice las propiedades y métodos de otra clase (padre).
De esta forma se puede reutilizar código y crear relaciones entre clases.

class Animal {
constructor(nombre) {
this.nombre = nombre;
}

hacerSonido() {
console.log("El animal hace un sonido");
}
}

class Perro extends Animal {
constructor(nombre, raza) {
super(nombre); // llama al constructor de la clase padre
this.raza = raza; // añade una nueva propiedad
}

}

const miPerro = new Perro("Rex", "Labrador");
miPerro.hacerSonido(); // El animal hace un sonido

Podemos observar que a pesar de no tener ningún método en la propia clase Animal llamado hacerSonido(), la instancia miPerroha podido utilizar el método. Esto se debe a que "extendía" de la clase Animal y por tanto puede utilizar sus métodos.

Polimorfismo

En cambio, si añadimos en la clase "hija" un método con el mismo nombre que la clase "padre", éste sobreescribe el del padre. Es decir, ante dos métodos iguales, se ejecuta el de la propia clase "hija".

class Animal {
constructor(nombre) {
this.nombre = nombre;
}

hacerSonido() {
console.log("El animal hace un sonido");
}
}

class Perro extends Animal {
constructor(nombre, raza) {
super(nombre);
this.raza = raza;
}
hacerSonido() {
console.log("GUAU GUAU!");
}

}

const miPerro = new Perro("Rex", "Labrador");
miPerro.hacerSonido(); // GUAU GUAU!

Métodos estáticos

¿Qué es un método estático?
Un método estático pertenece a la clase en sí misma, no a los objetos creados con ella.
Esto significa que se llama directamente desde la clase, sin crear una instancia.

class Matematicas {
static sumar(a, b) {
return a + b;
}
}

console.log(Matematicas.sumar(5, 3)); // 8

Clases con objetos dentro

Una clase puede contener objetos, arrays o incluso otras clases como propiedades.

class Empresa {
constructor(nombre, empleados) {
this.nombre = nombre;
this.empleados = empleados; // array de objetos Persona
}
}

class Persona {
constructor(nombre, edad) {
this.nombre = nombre;
this.edad = edad;
}
}

const empleados = [
new Persona("Lucía", 30),
new Persona("Juan", 28)
];

const miEmpresa = new Empresa("Skilly", empleados);
console.log(miEmpresa.empleados[0].nombre); // Lucía

Como podéis observar hemos creado un array llamado empleadosformado por instancias de la clase Persona, y lo hemos utilizado como propiedad para la clase Empresa.


Resumen

ConceptoDescripción
classDefine una nueva clase
constructor()Inicializa los valores al crear una instancia
thisHace referencia al objeto actual
newCrea una nueva instancia de la clase
extends / super()Permite heredar de otra clase
staticDefine un método o propiedad estática
get / setPermiten controlar el acceso a propiedades