2015-04-06 16 views
101

Sono stato sorpreso di non riuscire a trovare nulla sulle classi astratte durante la lettura su ES6. (Con "classe astratta" sto parlando del suo significato in Java, in cui una classe astratta dichiara le firme del metodo che una sottoclasse deve implementare per essere istantaneabile).ECMAScript 6 ha una convenzione per le classi astratte?

Qualcuno sa di alcune convenzioni che hanno preso piede per implementare classi astratte in ES6? Sarebbe bello essere in grado di cogliere una violazione astratta della classe con l'analisi statica.

Se dovessi generare un errore in fase di esecuzione per segnalare un tentativo di creazione di classi astratte, quale sarebbe l'errore?

+4

ES6 non modifica il meccanismo di ereditarietà prototipo di base delle versioni JavaScript precedenti. Il concetto di "classe astratta" non ha molto senso in termini JavaScript, sebbene un linguaggio di tipo pre-processore possa certamente implementare una cosa del genere. – Pointy

+1

Dato che javascript non è fortemente tipizzato, le classi astratte non sarebbero utili. – gorgi93

+0

Le classi astratte, insieme a tratti e mixin, sono in attesa ["strawman"] (http://wiki.ecmascript.org/doku.php?id=strawman:strawman) [proposta] (http: //wiki.ecmascript ? .org/doku.php id = Strawman: trait_composition_for_classes). –

risposta

191

ES2015 non dispone di classi in stile Java con costi integrati per il modello di progettazione desiderato. Tuttavia, ha alcune opzioni che possono essere utili, a seconda esattamente di ciò che stai cercando di realizzare.

Se volete una classe che non può essere costruita, ma la cui sottoclassi può, quindi è possibile utilizzare new.target:

class Abstract { 
    constructor() { 
    if (new.target === Abstract) { 
     throw new TypeError("Cannot construct Abstract instances directly"); 
    } 
    } 
} 

class Derived extends Abstract { 
    constructor() { 
    super(); 
    // more Derived-specific stuff here, maybe 
    } 
} 

const a = new Abstract(); // new.target is Abstract, so it throws 
const b = new Derived(); // new.target is Derived, so no error 

Per ulteriori dettagli su new.target, si consiglia di leggere questo quadro generale di come le classi nel lavoro ES2015: http://www.2ality.com/2015/02/es6-classes-final.html

Se stai specificamente alla ricerca di alcuni metodi che richiedono essere attuate, è possibile verificare che nella costruzione della superclasse così:

class Abstract { 
    constructor() { 
    if (this.method === undefined) { 
     // or maybe test typeof this.method === "function" 
     throw new TypeError("Must override method"); 
    } 
    } 
} 

class Derived1 extends Abstract {} 

class Derived2 extends Abstract { 
    method() {} 
} 

const a = new Abstract(); // this.method is undefined; error 
const b = new Derived1(); // this.method is undefined; error 
const c = new Derived2(); // this.method is Derived2.prototype.method; no error 
+8

grazie. Ma non penso che dovresti contrassegnarlo come duplicato perché 1) è una domanda diversa e 2) la risposta accettata all'altra domanda è la risposta sbagliata alla mia domanda e 3) la mia domanda è stata posta per prima.Vedo la risposta di AWB (all'altra domanda) risponde alla mia domanda qui ma non è contrassegnata come risposta accettata. – obelia

+0

L'altra domanda stava ottenendo risposte migliori e migliori ed è materialmente la stessa. Ah bene. – Domenic

+4

Appena scoperto che 'new.target' non è supportato da Safari. Il codice transpiled genera: 'SyntaxError: Unexpected token '.'' – siannone

Problemi correlati