Experimentalia

Appunti raminghi

Javascript: Ereditarietà basata su delega (Eredità prototipale)

leave a comment »

Dopo la traduzione dell’illuminante divertissement sull’ereditarietà classica in Javascript. Douglas Crockford arriva a commentare il suo stesso articolo (a distanza di qualche anno) affermando che l’ereditarietà prototipale è di gran lunga più potente ed espressiva di quella basata su classi e che più si conosce Javascript e meno si utilizza ed apprezza quest’ultima. Ragione per cui ho deciso di tradurre anche il pezzo di Crockford che tratta l’ereditarietà prototipale. Ho invertito la posizione delle date rispetto alla versione originale mettendole all’inizio del parte di testo a loro associato, piuttosto che alla fine, perché la cosa mi lasciava un pò perplesso. Si tratta solamente di gusti personali, però.

Buona Lettura

Ereditarietà Prototipale in Javascript

Titolo originale: Prototypal Inheritance in JavaScript
Douglas Crockford (www.crockford.com)

7 Giugno 2006

Cinque anni fa scrissi Ereditarietà classica in Javascript. Il testo mostrava che Javascript è un linguaggio ad oggetti senza classi, basato sui prototipi, e che aveva sufficiente potenza espressiva da simulare un sistema classico. Il mio stile di programmazione è cambiato da allora, come dovrebbe fare quello di ogni buon programmatore. Ho imparato a sfruttare pienamente l’ereditarietà prototipale, e mi sono liberato dei limiti del modello classico.

Il percorso che ho seguito è stato tortuoso perché lo stesso Javascript si scontra con la propria natura di sistema a prototipi. In un sistema prototipale, gli oggetti ereditano da altri oggetti. Javascript, tuttavia, non ha un operatore che permette questa operazione. Al suo posto ha un operatore new tale che

    new f()

costruisce un nuovo oggetto che eredita da f.prototype.

Questa indirezione era stata pensata per rendere il linguaggio più familiare ai programmatori abituati al sistema classico, ma ha fallito lo scopo, come possiamo desumere dalla scarsa opinione su Javascript che hanno i programmatori Java. Lo schema sottinteso al costruttore in Javascript non piace alla folla di programmatori tradizionale. Oltretutto nasconde il pattern prototipale, che è la vera natura di Javascript. Come risultato, ci sono pochi programmatori che sanno usare bene il linguaggio.

Fortunatamente è facile creare un operatore che implementi la vera ereditarietà prototipale. E’ una funzione standard della mia personale cassetta degli attrezzi, e vi raccomando vivamente di includerla nella vosta.


    function object(o) {
        function F() {}
        F.prototype = o;
        return new F();
    }

La funzione object semplifica il patter di costruzione di Javascript, dando luogo alla vera ereditarietà prototipale. Prende in input un oggetto esistente e restituisce un nuovo oggetto, vuoto, che eredita da quello passato come parametro. Se cerchiamo di ottenere dal nuovo oggetto un membro che non possiede, questo verrà fornito dal vecchio oggetto.
Gli oggetti ereditano da altri oggetti. Si può essere più orientati agli oggetti di così?

Ora, invece di creare classi, possiamo costruire oggetti prototipo, ed usare la funzione appena definita pre derivarne nuove istanze. In Javascript gli oggetti possono mutare, possiamo arricchire le nuove istanze fornendogli nuovi campi e metodi. Queste, a loro volta, possono fare da prototipo per altri oggetti. Non abbiamo bisogno delle classi per creare oggetti simili.

Per comodità, possiamo creare delle funzioni che chiamino la funzione object al posto nostro, e aggiungano le personalizzazioni necessarie ai nuovi oggetti con funzioni privilegiate. A volte chiamo queste funzioni fabbriche. Possiamo sfruttare l’ereditarietà parassita se scrivessimo funzioni fabbrica che invocano altre funzioni fabbrica piuttosto che chiamare direttamente la funzione object.

Ho scoperto che usando questi strumenti, insieme alle funzioni lambda e agli oggetti quasi-letterali, è possibile scrivere programmi ben strutturati, grandi, complessi ed efficienti. Oggigiorno, il modello ad oggetti classico è di gran lunga il più popolare, ma penso che il modello basato sui prototipi sia più efficiente

I have found that by using these tools, coupled with JavaScript’s lambdas and object quasi-literals, I can write well-structured programs that are large, complex, and efficient. The classical object model is by far the most popular today, but I think that the prototypal object model is more capable and offers more expressive power.

Learning these new patterns also made me a better classical programmer. Insights from the dynamic world can have application in the static.

2 Aprile 2007

Ecco un’altra versione:


Object.prototype.begetObject = function () {
    function F() {}
    F.prototype = this;
    return new F();
};

newObject = oldObject.begetObject();

7 Aprile 2008

La funzione object è globale, e questo è chiaramente un problema. Il problema con
Object.prototype.begetObject è che può ingannare programmatori inesperti, e può produrre
risultati inaspettati se viene ___overriden___.

Attualmente preferisco questa ulteriore versione:


if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}
newObject = Object.create(oldObject);

Written by Eineki

novembre 8, 2009 a 4:58 am

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: