¡Hola! Me parece que andas usando un bloqueador de anuncios =( ¿Nos desbloqueas? ¿Por qué?
F13

Funcion 13

Aprende ES6 - Las clases

Este es ya el cuarto artículo en el que hablamos de ES6. En artículos anteriores hemos hablado sobre let, const y los ámbitos las funciones flecha, que son realmente útiles, y las Promesas. Si esto no te suena de nada y estás intentando ponerle algún sentido a las siglas, ¡no te preocupes! Echa un vistazo a nuestra Introducción a ES6.

Ahora mismo creo que puedo ver tu cara pensando, ¿clases? ¿clases en JavaScript? Si has usado casi cualquier otro lenguaje, como PHP o Java, es posible que la idea de las clases no te sea extraña. No obstante, no nos tiremos de los pelos aun.

JavaScript sigue siendo un lenguaje de programación basado en prototipos no obstante las clases en realidad son solo una forma más bonita de escribir los prototipos de manera que sea más sencillo para la gente que llega de otros lenguajes el acostumbrarse a JavaScript. Hay muchas de las características de ES6 que no son más que una forma más sencilla/bonita de hacer algo que siempre hemos hecho.

Nota: Si el tema de los prototipos te resulta extraño, te recomiendo que leas Comprendiendo las variables, objetos, funciones, alcance y prototype en JavaScript antes de continuar.

Clases en ES6 vs Prototipos en ES5

Veamos primero un ejemplo que debería resultarnos familiar:

function Empleado (nombre, apellidos) {  
  this.nombre = nombre;
  this.apellidos = apellidos;
  this.salario = 16000;
  this.trabajoRealizado = 0;
}

Empleado.prototype.nombreCompleto = function() {  
  return this.nombre + ' ' + this.apellidos;
};

Empleado.prototype.trabajar = function() {  
  this.trabajoRealizado += 100;
};

Empleado.prototype.subirSalario = function(cantidad) {  
  cantidad = cantidad || 1000;

  this.salario += cantidad;
};

var empleado = new Empleado('Antonio', 'Laguna');  
console.log(empleado.nombreCompleto()); // Antonio Laguna  

Precioso. ¿Cómo quedaría con una clase de ES6? La sintaxis no varía mucho excepto que usamos la palabra clave class en vez de function. Los métodos de la clase se declaran usando una sintaxis mucho más corta sin usar la palabra prototype.

class Empleado {  
  constructor(nombre, apellidos) {
    this.nombre = nombre;
    this.apellidos = apellidos;
    this.salario = 16000;
  }

  nombreCompleto() {
    return this.nombre + ' ' + this.apellidos;
  }

  trabajar() {
    this.trabajoRealizado += 100;
  }

  subirSalario(cantidad) {
    cantidad = cantidad || 1000;

    this.salario += cantidad;
  }
}

let empleado = new Empleado('Antonio', 'Laguna');  
console.log(empleado.nombreCompleto()); // Antonio Laguna  

Si te fijas, es muy parecida a la notación que usamos al crear un objeto literal. No obstante una diferencia bastante notable es que las comas entre métodos están prohibidas, lo cual crea un poco de confusión. No obstante, en líneas generales, el código se ve bastante mejorado entre ES5 y ES6, ¿no te parece?

Métodos estáticos

Es habitual que las clases tengan métodos estáticos. Por ejemplo, la clase String, tiene métodos de instancia como .replace, .trim o .toUpperCase y métodos estáticos como String.fromCharCode o String.fromCodePoint.

Vamos a ver cómo añadir un método estático a nuestra clase Empleado.

class Empleado {  
  constructor(nombre, apellidos) {
    this.nombre = nombre;
    this.apellidos = apellidos;
    this.salario = 16000;
  }

  static tieneMasSueldo(empleado1, empleado2) {
    return empleado1.salario > empleado2;
  }

  nombreCompleto() {
    return this.nombre + ' ' + this.apellidos;
  }

  trabajar() {
    this.trabajoRealizado += 100;
  }

  subirSalario(cantidad) {
    cantidad = cantidad || 1000;

    this.salario += cantidad;
  }
}

let juan = new Empleado('Juan', 'Gómez');  
let pepe = new Empleado('Pepe', 'González');  
pepe.salario = 20000;

alert(Empleado.tieneMasSueldo(pepe, juan)); // true  

Herencia de clases

Siempre que salen las clases a relucir, existe el tema de la herencia algo que es bastante útil y que, hasta ahora, era bastante complejo de realizar en JavaScript (correctamente del todo).

Vamos a crear la clase Jefe que extiende a la clase Empleado. Un Jefe puede despedir a un empleado así que vamos a crear este método:

class Jefe extends Empleado {  
  despedir(empleado) {
    alert(empleado.nombreCompleto() + ' estás despedido!');
    empleado.despedido = true;
  }
}

let javi = new Jefe('Javi', 'Perales');  
let pedro = new Empleado('Pedro', 'Ortiz');

javi.despedir(pedro); // 'Pedro Ortiz estás despedido!';  
pedro.despedir(javi); // "TypeError: pedro.despedir is not a function  

La clase Jefe contiene todos los métodos y el constructor que contiene la clase Empleado. No obstante, es posible sobreescribir un método cualquiera. Podría decirse que los jefes trabajan... ¿más? ¿menos? Vamos a dejarlo en más por ahora, solo para hacer el ejemplo:

class Jefe extends Empleado {  
  despedir(empleado) {
    alert(empleado.nombreCompleto() + ' estás despedido!');
    empleado.despedido = true;
  }

  trabajar() {
    super.trabajar();
    this.trabajoRealizado += 50;
  }
}

Como ves, hemos implementado el método trabajar también en la clase Jefe. Gracias a la palabra clave super, podemos acceder a la clase Empleado que estamos extendiendo. Es muy habitual que, al reimplementar un método, llamemos al método base para realizar la misma función y añadir algo adicional, aumentado.

Lo más habitual, no obstante, es que sobrescribamos el constructor de una clase, y únicamente tendremos que usar super() para llamar al constructor de la clase extendida. Es importante destacar que es necesario pasar los argumentos que la clase necesite para hacerla funcionar:

class Jefe extends Empleado {  
  constructor(nombre, apellidos) {
    super(nombre, apellidos);
    this.salario = 30000;
  }

  despedir(empleado) {
    alert(empleado.nombreCompleto() + ' estás despedido!');
    empleado.despedido = true;
  }

  trabajar() {
    super.trabajar();
    this.trabajoRealizado += 50;
  }
}

Como ves aquí, la clase Jefe ahora tiene un salario base más alto que la clase Empleado.

¡Espero haberos aclarado cómo funcionan, qué son (y qué no), las clases en ES6!

Programador Front-end en First + Third y Potato. Trabajando con JavaScript y HTML5 desde el corazón de Sevilla.

Comentarios ¡Únete a la conversación!