Clases en JavaScript
                En este post verás las diferentes formas de crear clases en JavaScript, desde el método de la vieja escuela hasta las técnicas modernas y recomendadas por la comunidad. Después de leer este post tendrás un conocimiento profundo acerca de cómo funcionan las clases en JavaScript.
JavaScript es un lenguaje de programación basado en prototipos y orientado a objetos. Debido a esto, te recomendamos pasar primero por Introducción a la Programación Orientada a Objetos en el caso de que no tengas ninguna experiencia anteiror con este paradigma.
Constructor de función
Antes de los constructores la forma de crear una clase consistía en crear una función como la siguiente:
let Person = function(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
}
// otra forma de hacerlo es esta
function Person(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
}
 De esta forma podría utilizar el operador new y pasar los argumentos en el "constructor".
let person = new Person('Steave', 'Jobs')
person.firstName;   // Steave
 Para crear métodos en nuestra clase podríamos en el mismo constructor de función definir funciones de la siguiente manera:
function Person(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
    this.toString = function() {
        return this.firstName + ' ' + this.lastName
    }
}
 Ahora bien la forma más eficaz de crear métodos a dicha clase sería utilizar la propiedad prototype así:
Person.prototype = {
    toString: function() {
        return this.firstName + ' ' + this.lastName
    }
} De cualquier forma podemos utilizar los métodos de manera tan sencilla como
person.toString();    // Steave Jobs
 Declaración y expresión de clase
Una de las formas modernas de definir una clase es utilizando la palabra reservada class. A esta forma de definir una clase se le conoce como declaración de clase.
class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName
        this.lastName = lastName
    }
}
 Por otro lado, podemos definir también una clase utilizando una expresión. A esta forma alternativa se le conoce como expresión de clase.
let Person = class {
    constructor(firstName, lastName) {
        this.firstName = firstName
        this.lastName = lastName
    }
}
 Existe una diferencia sutil entre declarar una clase de la forma moderna y es que las clases declaradas con class no presentan hoisting. Para ver un poco más a fondo este tópico te invitamos a ver nuestro artículo Hoisting en JavaScript.
Métodos
Para crear métodos en las clases solo debemos agregar nuevas funciones después del constructor. Observa también como en el siguiente método utilizamos this para referirnos a la instancia actual de la clase.
class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName
        this.lastName = lastName
    }
    toString() {
        return this.firstName + ' ' + this.lastName
    }
}
 Métodos estáticos
Los métodos estáticos son útiles cuando no necesitamos crear una instancia de una clase para implementar una funcionalidad.
class Greeting {
    static sayHelloTo(person) {
        return 'Hello, ' + person.name
    }
}
Greeting.sayHelloTo({ name: 'Andrew' })