harmony: 4. clases

Introducción a las clases en javaScript

Christian Schloe

archivado en: JavaScript / 28 septiembre, 2016 / taller:

Con la sexta versión de javaScript, aka E6 aka harmony, ya tenemos clases. No son ni de lejos tan potentes como las de java o php, ni siquiera a las que se pueden formular con typescript, pero es de esperar que poco a poco vayan mejorando y son más amables e intuitivas que los objetos con función constructora.

Hasta ahora, para trabajar con algo parecido a clases teníamos que recurrir a fórmulas de este tipo:

var Robot = function(name) {

this.name = name || '';

};

Robot.prototype.walk = function() {

console.log(this.name + ' are walking');

};

var instanceRobot = new Robot('r2d2');

instanceRobot.walk(); // 2d2 are walking

Aparte de cuestiones sobre micro-rendimiento (la búsqueda de propiedades a lo largo de la cadena de prototipos tiene un coste), estas fórmulas tienden a ser bastante enrevesadas cuando tratas de emular las características de las clases clásicas, como la herencia y a la que te descuidas se te llena el código de calls, applys y demás partículas antipáticas.

var Animals = function(name) {

this.name = name || '';

/* Hay que traerse el método aquí para poder usarlo más adelante con apply (y esto no mola) */

this.walk = function() {

console.log(this.name + ' are walking');

};

};

var instanceAnimal = new Animals('Rhino');

instanceAnimal.walk();

var Dinosaur = function(name) {

Animals.apply(this, arguments) // inherit

}

var instanceDinosaur = new Dinosaur ('Triceratops');

instanceDinosaur.walk(); // Triceratops are walking

Por lo tanto, aunque solo sean azúcar sintáctico,  creo que vale la pena empezar a usarlas y enviar las funciones constructoras al limbo de los deprecated.

Las clases de E6

Como no podía ser de otra manera, para declarar una clase se utiliza la palabra reservada class.

class Robot {

};

Aunque también se puede cachear en una expresión.

const Robot = class {

}

A diferencia de las funciones o de los objetos constructores, las clases no se suben de forma automática al principio (hoisting), por lo que las instancias deben declararse después de haber formulado la clase:

/* ¡Al palo! Uncaught ReferenceError: Robot is not defined */

const instanceRobot = new Robot();

class Robot {

};

Como ocurre en otros lenguajes, las clases js tienen un método especial denominado constructor que sirve para inicializar propiedades cuando se instancian:

class Robot {

constructor(name) {

this._name = name;

}

};
const instanceRobot = new Robot('r2d2');

Además, tienen de fábrica dos métodos especiales habituales de las clases denominados getters y setters, los cuales recuperan o setean respectivamente el valor de una propiedad.

class Robot {

constructor(name) {

this._name = name;

}

get name () {

return this._name;

}

set name (name) {

this._name = name;

}

};

const instanceRobot = new Robot('r2d2');

/* Para acceder a los getters y setters se usa la notación de puntos */

instanceRobot.name;

instanceRobot.name = 'c3po';

Y aún hay otros métodos especiales, los denominados estáticos, que se pueden usar sin necesidad de instanciar la clase.

class Robot {

static staticMethod() {

console.log('foo');

}

};

Robot.staticMethod(); // foo

Sin embargo, creo que este tipo de construcciones son erróneas, pues para eso ya contamos en javaScript con los objetos mediante notación de literales.

Herencia

Solo con lo visto hasta ahora, creo que tenemos razones suficientes para empezar a usar las clases, pero cuando realmente se advierte su elegancia frente a las fórmulas de ES5 es con la herencia, que es muy fácil de preparar. Basta con usar el término reservado extends:

class Animals {

constructor(name) {

this._name = name || '';

}

walk () {

console.log(this._name + ' are walking');

}

}

class Dinosaur extends Animals {

becomeExtinct(meteor) {

console.log('Kabum');

}

}

var instanceDinosaur = new Dinosaur('Triceratops');

instanceDinosaur.walk(); // Triceratops are walking

instanceDinosaur.becomeExtinct(); // Kabum

Como es habitual en otros lenguajes, para referirse a los métodos y propiedades de la clase superior dentro de la clase extendida hay que utilizar el método super().

class Dinosaur extends Animals {

constructor(name, surname) {

super(name);

this._completName = this._name + '  ' + surname;

}

becomeExtinct(meteor) {

console.log(this._completName + ' Kabum');

}

}

var instanceDinosaur = new Dinosaur('Triceratops', 'Triceratoidae');

instanceDinosaur.becomeExtinct(); //Triceratops Triceratoidae Kabum

En cambio, lo que no existe, al menos en el momento de escribir estas líneas, es la posibilidad de definir métodos privados y protegidos. Todos son públicos, aunque se pueda hacer alguna pirula para simularlos. Pero bueno, es de esperar que vayan mejorando en próximas versiones.

|| Tags: , ,

Este artículo aún no ha sido valorado.

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Aportar un comentario


*