Posant ordre al Javascript: de les classes fins a Typescript

Enviat per Jaume Moral el Dc, 25/10/2017 - 07:01

Si heu programat alguna vegada amb Javascript més enllà d'alguna funció senzilleta, us haureu adonat que és molt fàcil tenir un poti-poti totalment desordenat. Javascript no és un llenguatge que hagi nascut d'entrada amb un disseny elegant i hi ha certes coses que grinyolen una mica. Però no tot està perdut. Podem programar amb orientació a objectes en Javascript i fins i tot podem tenir declaració de tipus! Veurem com fer-ho a continuació.

Classes en Javascript

Javascript es caracteritza per ser un dels pocs llenguatges orientat a objectes però sense classes. El que sí que tenim, són objectes com a tals. I que és un objecte en Javascript? Doncs una estructura de dades clau-valor a l'estil d'un hash. Com que a javascript les funcions són ciutadans de primera, l'objecte pot contenir atributs i mètodes.

Com creem objectes si no tenim classes? Doncs el que fem és tenir una funció que actua com a constructor. Així doncs, la sintaxi per una classe bàsica és una cosa tan poc intuïtiva com ara.

function Cotxe(marca, model, color, any) {
    this.marca=marca;
    this.model=model;
    this.color=color;
    this.any=any
}

seat=new Cotxe("Seat","Ibiza","blanc",2008);
ford=new Cotxe("Ford","Mustang","vermell",1970);

Quan creem un nou objecte d'aquesta forma, Javascript li afegeix una propietat anomenada "prototype" que és un altre objecte que pot tenir funcions o propietats compartides per tots els objectes d'aquest tipus. Aquest "prototype" és el més semblant que té Javascript al concepte de classe.

Quan volem definir un mètode d'una classe, la forma més habitual (no l'única) és assignar-los directament al "prototype".

Cotxe.prototype.esClassic = function() {
    return (new Date().getFullYear()-this.any)>25;
}

D'aquesta forma, amb funcions i amb el "prototype", podem treballar d'una forma molt similar a com si tinguéssim classes.

seat.esClassic()
>> false
ford.esClassic()
>> true

Herència

Podem tenir herència? Doncs si, i la forma de fer-ho és realment enginyosa. Per heretar el que fem es assignar la classe pare com si fos el nostre "prototype". Com que les funcions i atributs definits al "prototype" s'incorporen als objectes que creem d'aquella classe, a tots els efectes el que estem fent és heretar. I a més d'heretar, podem afegir mètodes i propietats i sobreescriure mètodes. Aquí tenim un exemple, on també es mostra com cridar al constructor de la classe pare.

Cotxe.prototype.repostar = function() {
    console.log("Posant benzina...");
}
function CotxeElectric(marca, model, color, any, autonomia) {
    Cotxe.call(this,marca, model, color, any);
    this.autonomia=autonomia;
}

CotxeElectric.prototype=new Cotxe();
CotxeElectric.prototype.repostar = function() {
    console.log("Carregant bateries...");
}

tesla=new CotxeElectric("Tesla","S","negre",2017,900);
tesla.repostar();
>> Carregant bateries...
tesla.autonomia;
>> 900
ford.repostar();
>> Posant benzina...
ford.autonomia;
>> undefined

Encapsulació

Podem tenir mètodes privats i encapsulació? Doncs si, retorçant una mica la sintaxi i jugant amb les variables locals i funcions dintre de funcions. Com que l'explicació és una mica densa, us deixo amb un article del 2001 (juràssic superior, en termes de Javascript) on el Douglas Crockford ja explicava com es podia:

http://www.crockford.com/javascript/private.html

De veritat ha de ser tot tan enrevessat?

Arribats aquí potser estareu pensant... molt bé Javascript permet fer moltes coses, però la sintaxi és poc intuïtiva, per dir-ho suaument. Doncs bé, no sou els primers a pensar-ho. La sintaxi que hem vist és la pròpia de l'especificació ECMAScript 5 (que és el Javascript que suporten els navegadors actuals). ECMAScript en la seva versió 6 ja inclou formes més entenedores de treballar amb classes. Però que el jo us volia comentar és TypeScript, que va un pas més enllà.

Typescript al rescat

Typescript és una ampliació de Javascript desenvolupada per Microsoft (sí, sí, Microsoft) que permet entre altres coses treballar amb tipus i una sintaxi de classes una mica més entenedora. La idea és que typescript es transforma (transcompila) cap a Javascript, ja que són 100% equivalents. El que permet Typescript és evitar errors que es poden detectar en temps de compilació i per tant tenir un llenguatge molt més robust i entenedor.

class Cotxe {
    private marca: string;
    private model: string;
    private color: string;
    private any: number;

    constructor (marca:string, model:string,color:string,any:number) {
        this.marca=marca;
        this.model=model;
        this.color=color;
        this.any=any;
    }
    public esClassic():boolean {
        return (new Date().getFullYear()-this.any)>25;
    }
    public repostar() {
        console.log("Posant benzina...");
    }
}

class CotxeElectric extends Cotxe {
    constructor (marca:string, model:string,color:string,any:number,autonomia:number) {
        super(marca,model,color,any)
        this.autonomia=autonomia;
    }
    public repostar() {
        console.log("Carregant bateries...");
    }
}

Una altra gran utilitat de Typscript són els Interfaces, que ens permeten declarar objectes que només tenen propietats i que quedi clar quines són permeses i quines no.

interface Estudiant {
    nom: string
    assignatures: Assignatura[]   
}

interface Assignatura {
    nom: string
    sigles: string
}

var estudiants: Estudiant[];
estudiants = [
    {
        nom: "Jaume",
        assignatures:[
            {nom:"AC",sigles:"Arquitectura de Computadors"},
            {nom:"PRO1",sigles:"Programació 1"},
        ]
    },
    {
        nom:"Albert",
        assignatures:[
            {nom:"F",sigles:"Física"},
            {nom:"PRO2",sigles:"Programació 2"},
        ]
    }
];

Si en aquest codi per exemple afegim els crèdits a una assignatura, el llenguatge ens donarà un error de compilació, ja que no estem complint l'especificació que ens hem autoimposat.

Com treballar amb Typescript

Typescript no està directament suportat pel navegador ni per node ni per res que suporti Javascript. Qualsevol programa Typescript s’ha de transformar a Javascript. Aquesta transformació es pot fer amb un paquet de Nodejs o bé utilitzar un plugin pel nostre editor preferit.

Si ja tenim Nodejs instal·lat al nostre sistema...

npm install -g typescript

I per compilar el nostre fitxer helloworld.ts i generar el .js

tsc helloworld.ts

Això ho necessitarem independentment de l'editor que fem servir. VSCode i Web Storm ja suporten fitxers .ts de forma nativa i per exemple Sublime té un plugin per compilar i un per fer syntax highlighting que podem instal·lar a partir de Package Control.

Conclusions

A partir d'ara, ja sabeu que potser el Javascript és molt més del que pensàveu i que, a més, el podeu convertir un llenguatge que tingui al mateix temps la flexibilitat de Javascript i la robustesa de Java.

Més informació

 

Segueix-nos a

Els nostres articles del bloc d'inLab FIB

         
         

inLab FIB incorpora esCert

Icona ESCERT

inLab és membre de