"El diseño es el embajador silencioso de tu marca"
- Paul Brand

Clases en ES6

Hoy hablamos de las Clases en ES6 porque, aunque hasta ahora en Javascript podíamos trabajar con clases, no existía una manera específica de crearlas, de poder usar programación orientada a objetos de forma clara.

Existían diversas alternativas que se podrían usar para crear componentes parecidos a lo que serían las clases en la POO tradicional, pero teniamos una declaración «class» como se podría esperar.

Ahora sí que la tenemos pero hay que aclarar que esta sintaxis de clases no introduce un nuevo modelo de herencia orientada a objetos a JavaScript, pero proporciona una sintaxis más clara y sencilla para crearlas.

Por lo que si esta nueva sintaxis solo se trata de una capa sobre la sintaxis actual mediante prototipos más simple de entender, veamos como se hace con los prototipos.

function Coche(marca, modelo, fecha) {
  this.marca= marca;
  this.modelo = modelo;
  this.fecha = fecha;
}
Coche.prototype.informacion = function() {
  return 'Este coche es un ' + this.marca + ' ' + this.modelo + ' del año ' + this.fecha;
}

var miCoche= new Coche('Seat', 'Ibiza', 2010);
Coche.informacion(); // 'Este coche es un Seat Ibiza del año 2010'

Si no queremos usar prototipos también podriamos hacer esto, el resultado es el mismo.

function Coche(marca, modelo, fecha) {
  this.marca= marca;
  this.modelo = modelo;
  this.fecha = fecha;
  this.informacion = function() {
    return 'Este coche es un ' + this.marca + ' ' + this.modelo + ' del año ' + this.fecha;
  }
}

var miCoche= new Coche('Seat', 'Ibiza', 2010);
Coche.informacion(); // 'Este coche es un Seat Ibiza del año 2010'

Aunque la forma actual de realizar POO usando prototype es muy potente las clases en ES6 tienen los beneficios antes mencionados los cuales cuando usemos clases, subclases o tengamos que reutilizar código nos van a hacer más facil la vida, vamos a ver entonces como se hace!

Declarar clases en ES6

Una manera de definir una clase es mediante una declaración de clase.
Para la declaración de una clase, es necesario el uso de la palabra reservada class y un nombre para la clase («Coche» en esté caso).

class Coche {
  constructor(marca, modelo, fecha) {
    this.marca = marca;
    this.modelo = modelo;
    this.fecha = fecha;
  }
  informacion() {
    return 'Este coche es un ' + this.marca + ' ' + this.modelo + ' del año ' + this.fecha;
  }
}

Otra manera de declarar clases en ES6 es mediante lo que se conoce como expresiones. Básicamente consiste en crear una variable y asignarle una expresión definida mediante class y las llaves.

var Coche = class {
  constructor(marca, modelo, fecha) {
    this.marca = marca;
    this.modelo = modelo;
    this.fecha = fecha;
  }
  informacion() {
    return 'Este coche es un ' + this.marca + ' ' + this.modelo + ' del año ' + this.fecha;
  }
}

En este caso la clase es anónima aunque podemos poner un nombre si lo preferimos, lo importante es que da igual el método que usemos, el resultado es el mismo.

Dentro de la definición de la clase no es posible escribir código directamente, ya que como tal no se comporta como una función, lo que vamos a encontrar es la definición de métodos.

Si miramos el código veremos un método que siempre está presente y es especial, el método constructor, el cual tiene estas características:

  • Si no lo definimos se utilizará un constructor por defecto.
  • Representa la función de la propia clase e implicitamente devuelve el objeto this.
  • Es la función llamada cuando se instancia un objeto de esa clase mediante new.

Los otros métodos que podemos definir pueden ser estáticos o no, en el caso del ejemplo que hemos puesto hemos definido un método llamado informacion, el cual no es estático pues en su interior utiliza diversas propiedades que tiene el objeto.

Un método estático por el contrario siempre devuelve lo mismo y tiene la particularidad de que puede ser llamado incluso sin instanciar la clase, veámoslo.

var Coche = class {
  constructor(marca, modelo, fecha) {
    this.marca = marca;
    this.modelo = modelo;
    this.fecha = fecha;
  }
  informacion() {
    return 'Este coche es un ' + this.marca + ' ' + this.modelo + ' del año ' + this.fecha;
  }
  static ayuda(){
    return 'Un coche debe tener marca, modelo y la fecha de compra';
  }
}

Para declarar el método estático a mayores antes de definir el nombre tenemos que poner la palabra static.

Y como decíamos ahora podriamos llamarlo sin necesidad de haber creado una instancia.
Al escribir el siguiente código devuelve la cadena de texto que hay en su interior.

console.log(Coche.ayuda());
// 'Un coche debe tener marca, modelo y la fecha de compra'

 

Instanciar clases en ES6

Como en otros lenguajes, para crear una instancia usamos la palabra reservada new seguida del nombre de la clase y todos los parámetros que se deban indicar para invocar al constructor.

Una instancia de una clase no deja de ser un objeto nuevo a partir de una clase, por tanto tendrá sus propiedades y sus métodos.

Vamos a instanciar la clase anterior…

var miCoche = new Coche('Seat', 'Ibiza', 2010);

Como se puede apreciar si lo comparamos con la antigua manera de trabajar con clases, para instanciar un objeto hacemos exactamente lo mismo, aquí no hay novedades.

Por supuesto las clases en ES6 no se pueden llamar antes de definirse.

Extender clases en ES6

Al igual que en otros lenguajes de programación, una clase puede extender otra clase heredando métodos o propiedades de la clase padre.
Pongamos nuestra clase Coche además extendiera de la clase Vehículo, ya que un vehículo puede ser una moto, un coche, un camión…

class Vehiculo{
  constructor(potencia, consumo, peso) {
    this.potencia = potencia;
    this.consumo = consumo;
    this.peso = peso;
  }
}

class Coche extends Vehiculo{
  constructor(potencia, consumo, peso, marca, modelo, fecha) {
    super(potencia, consumo, peso);
    this.marca = marca;
    this.modelo = modelo;
    this.fecha = fecha;
  }
  informacion() {
    return 'Este coche es un ' + this.marca + ' ' + this.modelo + ' del año ' + this.fecha;
  }
}

Vamos a detenernos un segundo en lo que acabamos de hacer, en primer lugar vemos que Coche extiende de Vehiculo, y para ello hemos usado la palabra clave extends a cotinuación de haber definido el nombre.
Como extiende de ella ha heredado sus 3 propiedades, y la manera de acceder a ellas fue usando super, el cual referencia a la clase superior.
Al llamar a super directamente estamos haciendo referencia a su constructor.

Consideraciones

Cuando declaramos clases en ES6 hay ciertas reglas del lenguaje que debemos respetar:

  • Los nombres de las clase no pueden ser *eval* ó *arguments*.
  • No están permitidos nombres de clase repetidos.
  • El nombre *constructor* solo puede ser usado para métodos, ni para getters, setters o generadores de métodos.

En muchos lenguajes existen los getters y los setters, que son lo que se llama mutator method, los accesores y mutadores nos permiten dar formato a los valores de las propiedades del objeto.
Para usarlos simplemente se agrega get o set delante del nombre del método de la siguiente forma:

class Coche {
  constructor(marca, modelo, fecha) {
    this.marca = marca;
    this.modelo = modelo;
    this.fecha = fecha;
  }
  informacion() {
    return 'Este coche es un ' + this.marca + ' ' + this.modelo + ' del año ' + this.fecha;
  }
  get marca(){
    return this._nombre;
  }
  set marca(marca){
    this.marca = marca;
  }
  get modelo(){
    return this.modelo;
  }
  set modelo(modelo){
    this.modelo = modelo;
  }
  get fecha(){
    return this.fecha;
  }
  set fecha(fecha){
    this.fecha = fecha;
  }
}

La realidad es que las clases en ES6 no nos aportan nada que no pudiéramos hacer ya, pero esta forma de definir los objetos es en la práctica, clara y fácil de manejar, por lo que deberíamos habituarnos a trabajar con ella.

The following two tabs change content below.
Especialista en diseño web responsive, programador html5, css3, jquery, php y java.

Latest posts by Óscar Lijó (see all)