Tanto di cappello Antrè![]()
Tanto di cappello Antrè![]()
Addio Aldo, amico mio... [03/12/70 - 16/08/03]
mi permetto di completare con alcuni link:
crockford: http://www.crockford.com/javascript/private.html
e talvolta si possono trovare articoli interessanti sul blog di dustin diaz:
http://www.dustindiaz.com/
esempi:
http://www.dustindiaz.com/javascript...ic-privileged/
e l'interessantissimo
http://www.dustindiaz.com/namespace-your-javascript/
dove spiega il concetto di namespacing, utilizzando function autorichiamanti;
esempio
codice:var com={}; com.blogspot={}; com.blogspot.mykenta={}; com.blogspot.mykenta.test=function(){ var a; //qui avviene la dichiarazione della classe //bla bla bla function _saluta(){ alert('ciao') }; //ritorniamo un oggetto usando la eval-notation return {saluta:_saluta} }(); com.blogspot.mykenta.test.saluta();
Grazie kenta, sempre meglio approfondire, ma spero che il namespace non crei confusione, visto che si tratta più di un annidamento di parametri o metodi di oggetti {} che di classi vere e proprie, comunque reperibili o istanziabili dai metodi di oggetti.Originariamente inviato da kentaromiura
mi permetto di completare con alcuni link:
Riguardo il link di crockford vorrei fare una doverosa correzione a quanto scritto nella sua pagina.
Non è vero che scrivere
function Qualcosa(){}
al posto di
var Qualcosa = function(){}
è solo una scorciatoia, perlomeno non è vero a livello di gestione del browser, nel senso che quasi tutti gli Internet Explorer non permettono di creare oggetti / classi voluminosi se si utilizza var al posto di function.
In poche parole:
function MiaClasse(){};
permette di creare classi con migliaia di linee di codice
var MiaClasse = function(){};
ha invece un limite di gestione codice interno che presumo sia più per colpa dell'allocazione della libreria javascript di IE piuttosto che dello standard ECMA (ma non ne sono sicuro).
Per concludere, se scrivete classi e non volete avere brutte sorprese, usate sempre function MiaClasse(){}; e mai var MiaClasse = function(){};
[edit]
ovviamente il discorso cade se sfruttate prototype sul nome di funzione ... ma se posso dare un consiglio, usate comunque il metodo "tradizionale" ... visto che è anche una scorciatoia![]()
mi pare cambi anche un altra cosa (non mi ricordo se il constructor o era una cosa simile)Originariamente inviato da andr3a
Grazie kenta, sempre meglio approfondire, ma spero che il namespace non crei confusione, visto che si tratta più di un annidamento di parametri o metodi di oggetti {} che di classi vere e proprie, comunque reperibili o istanziabili dai metodi di oggetti.
Riguardo il link di crockford vorrei fare una doverosa correzione a quanto scritto nella sua pagina.
Non è vero che scrivere
function Qualcosa(){}
al posto di
var Qualcosa = function(){}
è solo una scorciatoia, perlomeno non è vero a livello di gestione del browser, nel senso che quasi tutti gli Internet Explorer non permettono di creare oggetti / classi voluminosi se si utilizza var al posto di function.
In poche parole:
function MiaClasse(){};
permette di creare classi con migliaia di linee di codice
var MiaClasse = function(){};
ha invece un limite di gestione codice interno che presumo sia più per colpa dell'allocazione della libreria javascript di IE piuttosto che dello standard ECMA (ma non ne sono sicuro).
Per concludere, se scrivete classi e non volete avere brutte sorprese, usate sempre function MiaClasse(){}; e mai var MiaClasse = function(){};
[edit]
ovviamente il discorso cade se sfruttate prototype sul nome di funzione ... ma se posso dare un consiglio, usate comunque il metodo "tradizionale" ... visto che è anche una scorciatoia![]()
per il discorso Namespacing dal mio punto di vista e' bene elencarlo, poiche' permette di creare script che non "collidono" con altri.
Salve a tutti, sono nuovo nel forum e desidero anzitutto fare i complimenti ad andr3a per questa pillola, semplicemente eccezionale!
Tuttavia vorrei chiarimi alcuni dubbi, riguardo il namespacing e il fantomatico this.
1) Namespacing
Come si legge nel link postato da kentaromiura (http://www.dustindiaz.com/namespace-your-javascript/), l'approccio tramite il namespacing offre indubbi vantaggi tra cui l'assenza di eventuali "collisioni" ed in generale un codice - a mio avviso - più "pulito".
Tuttavia mi sembra di capire che il namespace non sia propriamente una definizione di classe (perdonatemi se vi sembra una cosa ovvia, è la prima volta che ho a che fare coi namespace): questo comporta che un simile approccio sia più utile a definire una sorta di libreria di variabili e funzioni globali, più che ad una effettiva programmazione a oggetti... o sbaglio?
Provo a spiegarmi meglio: stando agli ultimi esempi riportati nella pagina linkata qui sopra, è come se alla fine disponessi di una unica istanza di un oggetto che fa capo al nome di MyNamespace, ma senza la possibilità di creare nuove istanze.
Se le cose stanno così, trovo che la cosa sia alquanto limitante... qualcuno ha per caso sperimentato uno stile di programmazione basato su namespacing che consenta di costruire delle classi vere e proprie?
2) This
A seguito di svariati esperimenti, mi sembra che il contesto venga perso abbastanza facilmente, ad esempio quando si usano funzioni callback:
Per cui ad esempio se volessi creare una animazione, l'unico modo che sono riuscito a trovare per risolvere il problema è:codice:my_class = function () { this.message='ok'; this.metodo_a = function () { setTimeout(this.metodo_b, 1); } this.metodo_b = function () { setTimeout(this.metodo_c, 1); } this.metodo_c = function () { alert(this.message); } } ciccio = new my_class(); ciccio.metodo_c(); //alert('ok'); ciccio.metodo_b(); //alert('undefined') --> metodo_c non trova this.message ; ciccio.metodo_a(); //Errore --> metodo_b non trova this.metodo_c ;
...che è poi quanto precisato da andr3a:codice:my_animation = function () { ... this.step = function (oClass) { var next_step = function () { oClass.step(oClass); } // fai qualcosa this.timer = setTimeout(next_step, 1000); } ... this.start = function () { this.step(this); } ... this.stop = function () { if (this.timer) { clearTimeout(this.timer); } } }
(a proposito andr3a, nei tuoi esempi usi 'self' dove io uso 'oClass'... self è sicuramente + intuitivo, ma siccome è utilizzato nel DOM... non fa confusione? posso usarlo senza problemi?)Per ovviare a questa serie di problematiche, è sufficiente ricordarsi di inviare il referente stesso alle funzioni interne che lo richiedono.
Piccola nota al codice: perché definisco la funzione next_step? Semplice:
la sintassi di setTimeout è:
ma per il "magico" Internet Explorer è:codice:timer_id = setTimeout(callback_function, millisecondi[, param_1[, param2...]]);
...quindi ho adottato questo semplice trucco.codice:timer_id = setTimeout(callback_function, millisecondi[, language]);
Tuttavia questo codice mi sembra alquanto aggrovigliato... qualche idea per migliorarne leggibilità e/o efficienza?
Grazie e a presto,
gi_gio
il self come qualunque nome a scope locale può essere usato senza alcunissimo problema.codice:this.step = function () { var self = this; // fai qualcosa this.timer = setTimeout(function(){self.step()}, 1000); }
var window = 123;
var setInterval = 123;
var setTimeout = 123;
var document = 123;
ovvio che se nello scope devi usare window, setTimeout, documento o altro ti ritroveresti la top-level o globale che sia sovrascritta.
P.S. nel tuo caso preferirei setInterval
codice:function my_animation() { ... this.step = function () { // il this andrà // fai qualcosa } ... this.start = function () { var self = this; this.stop(); this.timer = setInterval(function(){self.step()}, 2000); } ... this.stop = function () { if (this.timer) { clearInterval(this.timer); this.timer = 0; }; } }
Ciao andr3a, grazie per la risposta!
Sull'utilizzo di parole chiave all'interno di funzioni come variabili locali... ok, buono a sapersi!
Per quanto riguarda setInterval... effettivamente talvolta le cose sono così semplici da non essere neanche prese in considerazione... ehm... ehm...
Quindi ancora grazie per queste due "dritte"!
... non è che avresti qualche dritta anche sul discorso del namespacing? Posso creare delle vere e proprie classi con costruttori e tutto il resto? O è possibile solo utilizzare uno schema Singleton?
codice:var andr3a = { parametro:"Andrea", metodo:function(){ alert(this.parametro) }, classe:function(){ this.test = function(){ return this instanceof andr3a.classe } } }; alert((new andr3a.classe).test()); // true
il namespace (o spazio dei nomi)
puoi pensarlo come a un contenitore per tue diverse funzioni,
puoi strutturare come vuoi avendo namespace annidati (
un esempio qui:
http://rey9999.altervista.org/kenta/framework_0.1.zip
)
per il discorso Singleton, ovviamente puoi crearti classi istanziabili piu' volte.
mi sà che devi rileggerti i primi post del topic...![]()
..per finire potrei tirare in ballo base ma non voglio creare confusione in questa pillola.
Ok, avevo letto tutti i post, ma avevo ancora qualche dubbio sui namespaces, adesso è tutto chiaro.
Come sospettavo, di fatto un namespace è più simile ad una libreria che ad una classe.
Tuttavia, come indicato da andr3a, è possibile definire una o più classi all'interno di un namespace.
Ero a caccia di uno stile di codice "pulito" per gestire gli oggetti, e come andr3a ha mostrato in questa pillola c'è la possibilità di usare prototype, oppure di "rinchiudere" la definizione di classe tra { }. Io ero convinto che il namespace consentisse un ulteriore metodo di scrittura, invece è un ottimo metodo per riorganizzare il codice!
Base sembra più indicato per quello che desideravo fare (grazie kentaromiura!), ma devo ancora approfindire!
Grazie ancora a tutti e due e a presto!
laluigino