Ús de static a les classes Javascript ES6

En aquest article anem a conèixer com treballar amb membres de classe en les classes de ES6, la versió recent de l’estàndard de Javascript. Aprendrem a crear mètodes static per propietaris també, encara que veureu que per el cas de les propietats haurem de valer-nos d’algun truc addicional.

En realitat no és el nostre objectiu introduir el concepte de static, ja és motiu d’estudi en detall en articles anteriors com Explicacions de mètodes i atributs static. No obstant això direm que els membres estàtics de les classes en Programació Orientada a Objectes en general són atributs i mètodes que depenen directament d’una classe, en comptes de dependre d’un objecte en particular. A l’dependre de la classe no estan associats a un objecte, de manera que comparteixen el valor per a tota la classe, independentment de les instàncies que s’hagin creat.

Ja hem comentat que amb la recent versió de Javascript ES6 ara disposem de classes, encara que no són exactament el mateix que en altres llenguatges més tradicionals. En el cas de static no hi ha canvis en el concepte, però al no poder-se declarar atributs d’instància, tampoc podrem declarar atributs static. Ho veurem també amb calma, encara que abans comencem amb els mètodes estàtics.

Definir mètodes static en ES6

Un mètode estàtic es construeix simplement indicant la paraula “static” abans del nom de l’mètode que s’està creant. La resta de la definició d’un mètode estàtic seria igual que la definició d’un mètode convencional, amb l’excepció de disposar de la variable “this” com habitualment en els mètodes.

En el següent exemple tenim una classe anomenada “Sumatori” que té un mètode declarat estàtic, per sumar els valors d’un array.

class Sumatorio { static sumarArray(arrayValores) { let suma = 0; for(let valor of arrayValores){ suma += valor } return suma; }}

El mètode static depèn directament de la classe, de manera que farem servir la mateixa classe per invocar.

let suma = Sumatorio.sumarArray(); //suma valdrá 12
Nota: el fet de no poder disposar de “this” dins d’un mètode estàtic és degut al fet que el mètode no s’invoca amb relació a cap objecte. Com has vist, fem servir el nom de la classe per invocar i no un objecte instanciat. Com saps, “this” té una referència a l’objecte on es va llançar un missatge (l’objecte sobre el qual es va invocar un mètode). Com que no existeix tal objecte d’invocació, no hi ha un objecte a “this”. En principi podríem pensar que “this” llavors valdrà “undefined”, però el que hi ha en realitat és el codi de la pròpia classe.

Els mètodes estàtics poden servir per a moltes coses. És el motiu pel que a vegades es fan servir com un calaix de sastre d’utilitats que puguin tenir a veure amb una classe. Pensant en objectes cal anar amb compte per què i com s’utilitzen. El passat exemple de sumarArray () no era molt bo des de la filosofia de l’orientació a objectes, però en el següent exemple tenim un mètode estàtic una mica millor pensat.

Tenim una classe Data que ens serveix per crear dates en Javascript. És cert que el JavaScript conté ja una classe Dóna’t, però té la possibilitat de crear dates i hores i potser nosaltres només ens cal dates i volem una sèrie d’utilitats addicionals que no estan incloses a la interfície original de Dóna’t.

en el nostre exemple observaràs que tenim un constructor, que rep el dia, mes i any. No obstant això en la pràctica moltes vegades les dates es creen amb el dia actual. Com que no hi ha la sobrecàrrega de mètodes en Javascript i per tant tampoc podem sobrecarregar constructors, podríem recórrer als mètodes static per crear una mena de constructor de la data sense paràmetres que ens retorna un objecte Data inicialitzat amb el dia actual.

class Fecha { constructor(dia, mes, ano) { this.dia = dia; this.mes = mes; this.ano = ano; } static hoy() { var fecha = new Date(); var dia = fecha.getDate(); var mes = fecha.getMonth() + 1; var ano = fecha.getFullYear(); return new Fecha(dia, mes, ano); }}

Com pots veure, el mètode static avui () s’encarrega d’obtenir els valors de el dia, mes i any actuals i invocar a constructor amb aquestes dades, retornant l’objecte que s’acaba de crear.

un altre exemple de mètode estàtic o mètode de classe

Continuem amb un segon exemple de mètode estàtic o mètode de classe. Ara el trobem en el marc d’una classe Coordenada,

class Coordenada { constructor(x, y) { this.x = x; this.y = y; } static coordenadaOrigen() { return new Coordenada(0,0); }}

En el codi anterior tens un exemple de mètode estàtic, anomenat coordenadaOrigen (), que retorna una nova instància d’un objecte de la classe Coordenada, amb els seus putos x i y igual a zero.

Aquest és un mètode de classe, de manera que haurem de fer servir la pròpia classe per accedir-hi.

var origen = Coordenada.coordenadaOrigen();

Atributs estàtics de ECMAScript 2015

la definició de propietats estàtiques, o propietats de classe, no és tan directa com la definició de mètodes estàtics, ja que en ES6 no es poden definir propietats tal com es fa en altres llenguatges de programació més tradicionals.

En ECMAScript 2015 (ES6) tenim la limitació de no poder declarar atributs a la classe (hem de generar-los al constructor o en els mètodes). Això també s’estén als atributs de classe o atributs static. No obstant això, sempre et pots muntar tu mateix algun mecanisme per aconseguir-ho.

Per exemple en el cas de tenir atributs de classe estàtics que tinguin valors comuns a tota la classe, podríem fer ús dels getter, col·locant la paraula static a l’hora de definir el mètode get.

class Circulo { static get pi() { return 3.1416 }}

Podrem accedir a “pi” com si fos una propietat estàtica, dependent directament de la classe. La fem servir directament des del nom de la classe:

console.log(Circulo.pi);

Si el que volem és una variable estàtica, que sigui global per a tota la classe, amb un valor que no depèn de les instàncies i que pot variar al llarg de el temps, podríem fer alguna cosa com això:

class Test {} Test.variableStatic = 'Algo que guardo en la clase';

com Javascript és tan permissiu, podem associar una propietat a la classe simplement assignant qualsevol valor. No m’agrada massa l’exemple, perquè la definició de la propietat estàtica estaria fora de el codi de la pròpia classe i per tant en una lectura a aquest codi podríem no donar-nos compte que més endavant es crea aquesta variable estàtica.

En l’exemple típic de crear una variable estàtica que porta el compte de les instàncies creades a partir d’una classe, podríem optar per alguna cosa com això (que m’agrada més per tenir la creació de la propietat estàtica dins el constructor).

class Habitante { constructor(nombre) { this.nombre = nombre; if(Habitante.contador) { Habitante.contador++; } else { Habitante.contador = 1; } }}

El problema aquí és que únicament hi ha d’haver aquesta propietat estàtica a partir de la primera instanciació d’un objecte. Així que un altre exemple una mica més enrevessat podria ser el següent, que fa ús dels getter i dels setter dels objectes Javascript.

class Habitante { static get contador() { if(Habitante.contadorPrivado) { return Habitante.contadorPrivado; } return 0; } static set contador(valor) { Habitante.contadorPrivado = valor; } constructor(nombre) { this.nombre = nombre; if(Habitante.contador) { Habitante.contador++; } else { Habitante.contador = 1; } } }

Com pots veure , Habitante.contador és la nostra propietat estàtica, que estaria disponible gràcies als getter i els setter com si fos un atribut normal (només que és estàtic per estar predit de “static”).

En el constructor fem ús de Habitante.contador com si fos un atribut normal, només que internament en la implementació de la classe aquestes propietats en realitat es calculen amb funcions computades get i set.

És un codi merament experimental, però et pot donar una idea de les coses que es poden fer en Javascript quan “retuerces” una mica el llenguatge. Aprèn més sobre els get i els set en aquest article.

Conclusió sobre els membres de classe en ES6

Hem après coses interessants sobre la creació de membres de classe, o membres estàtics, en les classes de ES6. Com has pogut veure, hi ha algunes particularitats donades pel llenguatge Javascript, que és important conèixer.

En el següent article de el Manual de ES6 seguirem parlant de classes, abordant una cosa tan important com l’herència de classes en Javascript .

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *