EcmaScript 6

Ya hemos visto una pequeña introducción a las clases y la herencia en JavaScript. En esta tercera parte nos toca revisar los métodos y atributos estáticos. Primero pasemos a definir que es un miembro estático de manera más o menos oficial:

Un miembro estático es aquel que reside en una clase sin requerir una instancia de esta para ser ejecutado. De forma que hay sólo una copia de éste, y se puede llamar sin tener objetos de la clase.

Yo mismo, resumiendo un poco lo que se habla en otros muchos sitios 😂

Para declarar un miembro estático, no os podéis imaginar la palabra reservada que se va a usar... así es, se utiliza "static".

Bueno, pongámonos serios y pasemos a ver un ejemplo de código:

class Operation {
  static add(sum1, sum2) {
    return sum1 + sum2;
  }

  addMultiple(sum1, sum2, sum3, sum4) {
    return Operations.add(sum1, sum2) + Operations.add(sum3, sum4);
  }
}

const operation = new Operation();
operation.addMultiple(45, 4535, 785, 2934); // 8299
Operations.add(1438, 2438);                 // 3876

Partiendo del código anterior, podemos ver como con static, hacemos que un método pase a ser estático, y que tanto para llamarlo desde dentro de la clase como desde fuera, se indicará el nombre de la clase y el nombre del atributo o método al que acceder.

En este caso, sólo hay definido un método add(), es decir, al contrario que ocurre con un método normal (también lo podemos aplicar a los atributos), no habrá un objeto con su propia "copia" del método, sino que habrá uno global para todos los objetos.

¿Esto cómo aplica a la herencia? Pues veamos otro ejemplo:

class Article {
  static taxPercent = 1.1;
  #name;
  #price;

  constructor(name, price) {
    this.#name = name;
    this.#price = price;
  }

  get Name() {
    return this.#name;
  }

  get Price() {
    return this.#price;
  }

  calculatePrice() {
    return this.#price * Article.taxPercent;
  }
}

class DeluxeArticle extends Article {
  static taxPercent = 1.21;
}

const article = new Article("Osito de peluche", 10);
article.calculatePrice(); // 11

deluxeArticle = new DeluxeArticle("Lijadora", 100);
deluxeArticle.calculatePrice(); // 110

¡Hey espera! ¿Por qué el cálculo del precio de la lijadora devuelve 110, en lugar de 121?. Esto es porque en el método de la clase padre tenemos Article.taxPercent. En este caso al ser un elemento estático, no sobre-escribimos dicho valor, como si podría dar pie con miembros no estáticos. Es por ello que en el cálculo estamos llamando a taxPercent del padre. Si fuera necesario llamar al nuevo taxPercent, tendríamos que sobreescribir el método de DeluxeArticle de forma que quedara tal que así:

class DeluxeArticle extends Article {
  static taxPercent = 1.21;

  calculatePrice() {
    return this.Price * DeluxeArticle.taxPercent;
  }
}

Ahora si estamos llamando al atributo estático de nuestra clase. En resumen, en el código de ejemplo estamos teniendo dos atributos estáticos con el mismo nombre, uno accesible con Article.taxPercent, y el otro con DeluxeArticle.taxPercent. Es más podemos acceder a uno u otro indistintamente según nos haga falta, siempre anteponiendo el nombre de la clase que lo contiene.

Con todo lo visto, es muy sencillo pasar a implementar el conocido patrón singleton en JavaScript:

class MySingleton {
  static #instance = null;

  // Añadimos un atributo nombre para poder hacer pruebas más adelante 😉
  #name;

  static getInstance() {
    if (!MySingleton.#instance) {
      MySingleton.#instance = new MySingleton();
    }

    return MySingleton.#instance;
  }

  set Name(name) {
    this.#name = name;
  }

  get Name() {
    return this.#name;
  }


}

const instance1 = MySingleton.getInstance();
const instance2 = MySingleton.getInstance();

instance1.Name = "Soy un singleton";
instance1.Name; // Soy un singleton
instance2.Name; // Soy un singleton

La pena es que no se puedan tener constructores privados en JavaScript para evitar instancias ajenas que no vayan por el método getInstance().

Más artículos de esta serie: Parte 1. Clases y Parte 2. Herencia

Comparte este artículo con quien quieras
Orientación a objetos con JavaScript (ES6). Parte 2. Herencia
Diferencias entre var y let en JavaScript

Leave a Comment

Your email address will not be published. Required fields are marked *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.