Altri modelli di riutilizzare il codice in YUI3

7 gennaio 2010 alle 06:41 da Stoyan Stefanov | In Sviluppo | 2 Commenti

Stoyan Stefanov. Chi l'Autore: Stoyan Stefanov ( @ stoyanstefanov ) è un front-end ingegnere presso Yahoo! Search. Egli è anche l'architetto di YSlow 2.0, co-creatore della Image Optimizer smush.it, altoparlante e technical writer. Il suo ultimo libro si chiama Object-Oriented JavaScript .

Questo post è un follow-up per l'articolo "modelli di ereditarietà in YUI3" e le immersioni più in profondità le API YUI3 mostrando più modelli per il riutilizzo del codice. La Banda dei Quattro libro sostiene che dovremmo "preferiscono composizione di oggetti di ereditarietà delle classi". E infatti, l'ereditarietà è talvolta usato come una soluzione in lingue fortemente tipizzati in cui la firma di un oggetto o una classe deve essere fissato al momento della compilazione. JavaScript è debolmente tipizzato e gli oggetti possono essere composti, mescolate e aumentata in qualsiasi momento.

Aumentare gli oggetti

Nella vita reale JavaScript, è raro che ci si deve impostare catene eredità profonda. Spesso si può solo desidera convertire un oggetto esistente (o un costruttore) con i membri di un altro, senza necessariamente formando una relazione padre-figlio. YUI offre il metodo Y.augment(...) di fare proprio questo.

Il seguente esempio mostra la differenza tra l'eredità corretto con Y.extend(...) e l'aumento semplice oggetto con Y.augment(...) .

 / / Genitore, aka fornitore di funzionalità
 funzione di programmatore () {}
 Programmer.prototype.writeCode = funzione (){};

 / / Un costruttore che viene aumentata con i membri del fornitore
 CodeMonkey funzione () {}
 Y.augment (CodeMonkey, Programmatore);
 var = new scimmia CodeMonkey ();

 / / Un costruttore che eredita dal genitore-fornitore
 Guru funzione () {}
 Y.extend (Guru, Programmatore);
 Guru Guru var = new ();

Ora che abbiamo riutilizzato Programmer funzionalità 's in due modi, cerchiamo di verificare il risultato. Entrambi gli oggetti monkey e guru ora ottenere un writeCode() metodo, ma solo il guru fa parte della catena di ereditarietà.

 alert (typeof monkey.writeCode) / / "funzione"
 alert (typeof guru.writeCode) / / "funzione"

 / / Scimmia non è un programmatore, mentre il guru è
 alert (scimmia instanceof programmatore); / / falso
 alert (guru instanceof programmatore); / / true

Y.augment(...) può anche prendere un oggetto (al contrario di un costruttore) per essere aumentata.

 var n00b = {};
 Y.augment (n00b, Programmatore);

 / / Ora n00b può writeCode
 alert (typeof n00b.writeCode) / / "funzione"

Y.augment(...) permette al destinatario di essere più esigente quando riutilizzo del codice da parte del fornitore. Un terzo parametro opzionale per Y.augment(...) definisce se le proprietà esistenti devono essere sovrascritti ( false per default, il che significa preservare le proprietà originali del destinatario). Il quarto parametro può facoltativamente fornire una whitelist - un array contenente i nomi delle proprietà che dovrebbero essere riportati.

Clonazione

La clonazione degli oggetti è ancora un altro modello per il riutilizzo del codice, che consente di creare oggetti nuovissimi, che sono proprio come quelli già esistenti. In un certo senso, l'idea è simile a quella eredità prototipale (vedi Y.Object(...) nel precedente articolo), dove gli oggetti ereditano da oggetti. La differenza principale è che quando la clonazione, le proprietà del genitore vengono copiati per il bambino direttamente, non attraverso la catena di prototipi.

Y.clone(...) crea una copia profonda, il che significa che ricorsivamente all'interno di un array e proprietà degli oggetti. Inoltre, crea copie di valore, in modo che l'oggetto clonato non modifica il genitore per errore (in array JavaScript, oggetti e funzioni vengono copiati per riferimento).

Per illustrare la differenza, si consideri un oggetto pro che viene clonato in un nuovo oggetto clone e anche ereditato come wiz con Y.Object(...) .

 / / Oggetto originale
 var pro = {groks: ['html']};

 / / Eredita
 var wiz = Y. Object (pro);

 / / Clone
 var clone = Y.clone (pro);

Ora aggiungiamo un nuovo elemento array l'oggetto originale

 pro.groks.push ('css');

L'oggetto bambino vede il valore aggiornato, mentre il clone no, perché il clone è un'istantanea di ciò che l'oggetto è stato al momento della clonazione.

 wiz.groks.join () / / "html, css"
 clone.groks.join () / / "html"

Questo funziona al contrario, come pure - quando il bambino modifica l'array.

 wiz.groks.push ('js');
 pro.groks.join () / / "html, css, js"
 clone.groks.join () / / "html"

Clone di discussione

Come si può vedere Y.clone(...) crea nuovi oggetti deep-copia di tutte le loro proprietà e metodi. Anche se questo non è probabilmente quello che normalmente si chiama eredità, è ancora uno schema piuttosto semplice e diretto per il riutilizzo del codice. Dopo tutto il riutilizzo del codice è di evitare la necessità di duplicare il codice e il riutilizzo di funzionalità esistenti.

Qualcosa si potrebbe chiedere - che dire delle prestazioni? Non è inefficiente per copiare i valori in questo modo. La risposta è - sì, potrebbe essere inefficiente. Ma per la maggior parte delle applicazioni questo è raramente il collo di bottiglia. Infatti Firebug (estensioni di Firefox sono scritti in JavaScript), che è un pezzo abbastanza complessa del software ha un extend() metodo che funziona semplicemente copiando le proprietà dall'oggetto padre al figlio oggetto, utilizzando una copia (non ricorsione in oggetti e gli array).

Quindi, dal momento che la clonazione è solo profonda copia delle proprietà da un oggetto all'altro, non sarebbe bello se si può ereditare funzionalità da più oggetti, non solo da uno? Qui è dove Y.merge(...) viene in aiuto con questa sorta di mix-in oggetti.

Oggetti mixin con Y.merge(...)

Il modello mixin permette di catturare le proprietà e metodi più oggetti e riporto in un nuovo oggetto. YUI3 fornisce il metodo Y.merge(...) che può prendere qualsiasi numero di oggetti e restituire uno solo che è un mix di tutti gli oggetti fonte.

Ecco un esempio:

 var = {mad_skillz cuocere: funzione (){}, mix: funzione (){}, mangiare: funzione (){}};
 ingredienti var = {zucchero: "lotti", farina: 1, uova: 2};
 var = {caseificio latte: 1};

 / / Mixin
 var = torta Y.merge (mad_skillz, ingredienti, prodotti lattiero-caseari);

Ora è possibile verificare quali proprietà ha riportato al cake oggetto utilizzando il comodo metodo Y.Object.keys(...) che vi dà un array di tutti i nomi delle proprietà.

 . Y.Object.keys (torta), join (), / / ​​"cuocere, miscelare, mangiare, zucchero, farina, uova, latte"

Y.merge(...) assomiglia clonazione, ma invece di deep-copia di un oggetto, crea una copia e può richiedere più oggetti da mescolare con la chiamata al metodo stesso. La logica sovrascrittura dei Y.merge(...) in caso di collisioni di proprietà di denominazione è diverso dalla maggior parte di altri metodi - se si dispone di due membri con lo stesso nome, l'ultimo vince e sovrascrive il precedente.

Proprio come con Y.clone(...) , Y.merge(...) non è necessariamente limitato ai fini del riutilizzo del codice. Si possono usare anche per manipolare gli array o qualsiasi tipo di hash oggetti simili, come ad esempio gli oggetti di configurazione.

Y.mix(...)

Y.mix(...) è il più basso livello di metodo dietro la maggior parte delle funzionalità di cui sopra. Si offre un controllo accurato sul quale vengono copiati proprietà e dove esattamente. Inoltre permette di combinare due proprietà con lo stesso nome, ignorare alcune proprietà e così via.

Ecco un esempio un po 'complessa utilizzando il Y.mix(...) API:

 / / Un oggetto
 var pro = {
   groks: ['html', 'css', 'js'],
   dice: ['latino'],
   tweet: true
 };

 / / Un costruttore
 WebGuru funzione () {}

 / / Aumentare il prototipo del costruttore
 / / Con alcune delle proprietà pro
 Y.mix (WebGuru, pro, vero, ['groks', 'tweet'], 4);

 / / Test
 guru var = new WebGuru ();
 guru.groks.join () / / "html, css, js"
 guru.tweets; / / true
 guru.speeks; / / indefinito

Se guardate la chiamata a Y.mix(...) , abbiamo 5 argomenti, che significa:

  1. WebGuru diventa più membri ...
  2. da pro ...
  3. sovrascrivendo quelle esistenti ...
  4. solo se si trovano in questo array whitelist ['groks', 'tweets'] . Ciò significa che la speaks proprietà non saranno mescolati
  5. 4 è il modo. Ci sono cinque modalità di miscelazione - da 0 a 4, dove 4 significa che il prototipo di WebGuru riceverà membri provenienti da pro .

Si può controllare la documentazione per ulteriori informazioni sui parametri accettati da Y.mix(...) .

Questo è tutto gente!

Grazie per aver letto! Per ulteriori informazioni ed esempi sulla funzionalità OOP in YUI3, potete consultare questi link:

Condividere ed estendere: Bookmark with del.icio.us | Digg it! | reddit!

2 Commenti

  1. Davvero molto bello blog ... è davvero molto utile per capire le differenze tra eredità classica e prototipale.

    uno buono ..

    Commento di Vishwa Bandhu - 23 Luglio 2010 #

  2. Ma se dite "Ci sono cinque modalità di miscelazione - da 0 a 4, dove 4 significa che il prototipo di WebGuru riceverà membri provenienti da professionista." Poi quando ho esempio 2 WebGuru, i cambiamenti faccio in un caso ad un array groks si rifletterà negli altri casi, come viene copiato il prototipo ...: S o mi manca qualcosa?

    Commento di Totty - 18 Gennaio 2011 #

Al momento l'inserimento di commenti non è in questo momento.

Ospitato da Yahoo!

Copyright © 2006-2011 Yahoo! Inc. Tutti i diritti riservati. Privacy Policy - Termini del Servizio

Powered by WordPress su Yahoo! Web Hosting .