25 giugno 2011

Javascript & gwt tutorials

HTML


Utilizzo corretto di alcuni attributi (utile per i programmatori e per grafici css)
http://gheryd.blogspot.com/2011/09/html-utilizzo-corretto-degli-attributi.html


Javascript (ES6)

Aggiornamento javascript ES6
http://gheryd.blogspot.com/2019/07/javascript-es6-es2015.html

Javascript (ES5)

Tutorial di base (1a parte, sintassi e basi del linguaggio)
http://gheryd.blogspot.com/2011/07/javascript-tutorial-di-base.html

Tutorial di base (2a parte, operazioni matematiche, su string, array etc)
http://gheryd.blogspot.com/2011/07/javascript-le-basi-2a-parte.html



Manipolare il DOM (Document object model)
http://gheryd.blogspot.com/2011/06/javascript-manipolare-dom-codice.html

Programmazione ad oggetti
http://gheryd.blogspot.com/2011/06/javascript-programmazione-ad-oggetti.html

Programmazione eventi browser compatibili (esempi completi: currency text boxeditable table)
http://gheryd.blogspot.com/2011/05/javascript-funzioni-compatibili-per-gli.html

Funzione parseint (caso specifico per i valori "08" e 09)
http://gheryd.blogspot.com/2011/05/javascript-parseint-per-valori-08-e-09.html

Regular expression targa italiana
http://gheryd.blogspot.com/2011/05/javascript-regular-expression-targa.html

Controllare se jquery è caricato (o qualsiasi altro script)
http://gheryd.blogspot.com/2011/07/javascript-check-jquery-loaded.html

Ricerca dei numeri primi (crivello di Eratostene)
http://gheryd.blogspot.com/2011/08/javascript-numeri-primi.html

Grepolis tools
http://gheryd.blogspot.com/2011/05/da-ex-giocatore-di-grepolis-mi-ero.html


GWT

Widget Currency Text Box
http://gheryd.blogspot.com/2011/04/gwt-currency-generic-number-text-box.html

Detect popup blocker
http://gheryd.blogspot.com/2011/03/gwt-detect-popup-blocker-rilevazione.html

Widget Tree (impedire da tastiera la selezione degli item nascosti)
http://gheryd.blogspot.com/2011/03/se-si-nasconde-un-item-di-un-tree.html

Developer plugin
http://gheryd.blogspot.com/2010/08/plugins-gwt-developer-plugin-per-chrome.html

Suggest box (forzare la visualizzazione della lista sul campo vuoto)
http://gheryd.blogspot.com/2010/02/gwt-forzare-la-visualizzazione-per-il.html

gwt & gears (fixing del plugin)
http://gheryd.blogspot.com/2010/02/utilizzando-gwt-2.html

gwt & php (utilizzare i servizi creati con php su gwt e lavorare in debug su ecplise)
http://gheryd.blogspot.com/2011/09/gwt-tutorial-utilizzare-gwt-con-php.html

Gestire Eventi riga per FlexTable
http://gheryd.blogspot.com/2012/01/gwt-eventi-righe-per-flextable.html

Mostrare/nascondere pannelli con un doppio click sugli splitters dellp SplitLayoutPanel
http://gheryd.blogspot.com/2012/02/public-class-splitlayoutpanelext.html

Questi tutorials sono nati dai miei appunti che ho raccolto nel tempo durante la mia esperienza lavorativa come programmatore web.
Nel tempo li ho riordinati e li ho inseriti in questo blog in modo che fossero sempre disponibili.
Li ho poi resi pubblici sperando che possano essere di utilità non solo per nuovi programmatori ma anche per i più esperti. ;)
Consigli, proposte, segnalazioni di errore sono ben accetti :)
Quindi aggiungete pure commenti.
Beh, buona lettura, anzi, buona programmazione!

18 giugno 2011

Ubuntu 11.04 DELL VOSTRO 3750 CRASH

english version

In maggio 2011 La mia esperienza con Ubuntu 11.04 sulla mia nuova macchina DELL Vostro 3750 è stato un completo disastro.
Dopo una settimana il sistema è andato in crash e non era possibile reinstallare  neanche da cd.
La macchina è stata acquistata a maggio 2011. Le caratteristiche tecniche sono in questa pagina: specifiche tecniche Dell Vostro 3750

Inizialmente per risolvere i problema ho reinstallato Windows Seven, e poi in una seconda partizione ho installato Ubuntu 10.04 LTS con un kernel 2.6.38. Ma non funzionavano gli effetti visivi.
Poi ultimamente (fine luglio 2011) mi sono deciso a riprovare la versione 11.04. Ho cercato in mezzo web, ho installato diversi pacchetti .deb per far funzionare la scheda NVIdia, ho cambiato impostazioni di avvio. Man mano che procedevo non vedevo alcun miglioramento, anzi, gli errori crescevano finchè il sistema è andato in crash definitivo, senza la possibilità di avvio da cdrom. Non riuscivo a far partire neanche il cd della versione 10.04 con le impostazioni "nomodeset" o "acpi=off".
Poi quando stavo per mollare, ho voluto fare un ultimo tentativo con un installatore testuale. Ho provato  la versione 11.04 alternate e sembrava funzionare senza la necessità di "smanettare".
Poi dopo due giorni, mentre stavo scaricando dei file con filezilla è andato in completo crash.
Per cui devo ritornare alla versione 10.04 LTS.

Ubuntu 10.04 LTS con kernel 2.6.38
Se sul vostro Dell Vostro 3750 non riuscite proprio ad utilizzare Ubuntu versine 11.04, provate la versione Ubuntu 10.04 LTD (Long Term Support) e poi aggiornate il kernel per il riconoscimento dei componenti harware (altrimenti non potete utilizzare la wireless e la grafica è a 1024)
- ho reinstallato Windows Seven da cd fornito da Dell con tutti i drivers. 
- da Seven ho ridotto lo spazio della partizione primaria tramite pannello di controllo->strumenti di amministrazione->gestione disco; da 500 gb sono riuscito a liberare solo 250 gb.
- ho scaricato il file .iso UBUNTU 10.04 LTS 64 bit (dalla pagina ufficiale di ubuntu in alternativa alla 11.04) e l'ho masterizzato su cd (tasto destro sul file, masterizza immagine su cd). 
- ho fatto il boot dal cd  (riavviando il computer tenere premuto F12); durante l'installazione di Ubuntu 10.04 ho creato due partizioni nello spazio libero, uno per root "/" (50gb) e una per "/home" (150gb) per preservare dati e configurazioni in caso di reinstallazione
- con il kernel fornito su cd non mi veniva riconosciuta la scheda grafica e la wireless, così ho installato il nuovo kernel 2.6.38-1-generic. (vedi comandi sotto)
gheryd@gheryd-laptop:~$ sudo add-apt-repository ppa:kernel-ppa/ppa
gheryd@gheryd-laptop:~$ sudo apt-get update
gheryd@gheryd-laptop:~$ sudo apt-get install linux-headers-2.6.38-1-generic linux-image-2.6.38-1-generic

8 giugno 2011

javascript manipolare DOM, codice browser compatibile

Indice dei tutorials: http://gheryd.blogspot.com/2011/06/javascript-gwt-tutorials.html

Indice
  • Manipolazione di base
  • Ottimizzare le performances
  • Operazione con gli attributi
  • Aggiungere html
  • Gestire eventi
  • Gestire le classi e le proprietà di stile
  • Mostrare/nascondere un elemento
  • Select
  • CheckBox
  • Caricare uno script
  • Caricare un css
  • Templates


Introduzione
In javascript, ogni elemento grafico inserito nella pagina HTML è rappresentato da un oggetto accessibile tramite l'oggetto "document".
L'oggetto "document" è una proprietà dell'oggetto "window" e viene popolato con una struttura ad albero durante il caricamento della pagina.
La struttura che viene così creata è il DOM, document object model, cioè una rappresentazione a oggetti di tutti i componenti della pagina HTML.
Se conoscete XML, vi saranno familiari i comandi in questo tutorial per manipolare questi oggetti che di base sono chiamati nodi (node). Ogni nodo può contenere dei nodi figli (child nodes).
L'oggetto "element" è un particolare tipo di nodo che rappresenta un tag html.
Esistono altri tipi di nodi, come per esempio gli attributi dell'elemento, oppure i commenti.
Anche il testo inserito all'interno di una tag sarà rappresentato nel DOM come nodo figlio.
Esistono delle "scorciatoie" che consentono di cercare elementi esistenti nella pagina, il più usato è sicuramente:
var el = document.getElementById("myId");
Il metodo restituisce un oggetto element che ha come attributo id = "myId".
Con javascript  possiamo modificare gli elementi esistenti cambiandone l'aspetto grafico per esempio, oppure crearne di nuovi e farli apparire dove ci è necessario come per esempio aggiungere una riga ad una tabella o un elemento in una lista.

Manipolazione di base
Creare un elemento:
var el = document.createElement("div");
Creare un elemento di testo:
var txt = document.createTextNode("Hello world!");
Ottenere un elemento dal suo id:
var el = document.getElementById("myId");
se l'elemento non è nella pagina el sarà nullo, verificare prima di accedere alle proprietà dell'elemento:
if( el ) {
    alert(" element exists" );
}
Nota: per accedere ad elementi gia esistenti, dovrete attendere la fine del caricamento della pagina come nell'esempio seguente:
<html>
<head>
<script type="text/javascript">
function init() {
    var el = document.getElementById("myDiv");
    ....
}
</script>
</head>
<body onload="init()">
<div id="myDiv">....</div>
</body>
</html>
Ottenere elementi in base al tag:
var els = document.getElementsByTagName("input");
for(var i=0; i<els.length; i++) {
   var el = els[i];
 ...
}
Ottenere il nome del tag
var tagname = el.tagName;
Aggiungere un elemento alla fine:
elParent.appendChild(elChild);
Inserire un elemento:
elParent.insertBefore(newEl, elChild);
Rimuovere un elemento:
elParent.removeChild(elChild);
Sostituire un elemento:
elParent.replaceChild(newChild, oldChild);
Inserire un elemento all'inizio:
elParent.insertBefore(elChild, elParent.childNodes[0]);
Ottenere la lista (array) degli elementi figli:
var nodes= elParent.childNodes;
Ottenere il primo figlio:
var node = elParent.firstChild;
Ottenere l'ultimo figlio:
var node = elParent.lastChild;
Ottenere il fratello successivo:
var node = el.nextSibling;
Ottenere il fratello precendente:
var node = el.previousSibling;
Sapere il tipo di nodo:
var type = node.nodeType;
il valore restituito è un numero, di solito interessa verificare se il tipo è relativo ad un element node o un text node come nell'esempio seguente:
if( type  == 1) {
   alert("is element");
   // node.nodeName = "DIV" //=tagName
   var el = node;
}else if(type ==3) {
   alert("is text");
   // node.nodeName = "#text"
   var text = node.nodeValue;
}
Cercare il primo elemento:
var firstEl = null;
var children = parentEl.childNodes;
for(var i=0; i<children.length; i++) {
   var node = children[i];
   if(node.nodeType==1) {
       firstEl = node;
       break;
   }
}
in modo analogo per cercare l'ultimo elemento:
var lastEl = null;
var children = parentEl.childNodes;
for(var i=children.length; i>=0; i--) { 
   var node = children[i];
   if(node.nodeType==1) {
       lastEl = node;
       break;
   }
}

Ottenere l'elemento padre:
var parentEl = el.parentNode


Ottimizzare le performances
Se dobbiamo aggiungere molti elementi figli come dell'esempio seguente:
var container = document.getElementById("idContainer");
for(var i=0; i<100; i++) {
    var child = document.createElement("p");
    child.appendChild( document.createTextNode("paragraph "+i) );
    container.appendChild(child);
}
per migliorare le performances in alternativa è possibile creare un frammento:
var  docFrag= document.createDocumentFragment();
for(var i=0; i<100; i++){
    var child = document.createElement("p");
    child.appendChild( document.createTextNode("paragraph "+i) );
    docFrag.appendChild(child);
}
container.appendChild(docFrag); 
è equivalente all'esempio precedente, ma molto più veloce perchè tutti gli elementi sono aggiunti alla pagina alla fine con un'unica istruzione.

In generale, è sempre meglio aggiungere elementi alla pagine verso la fine.
Per esempio, nel caso di creazione di una tabella:
var table = document.createElement("table");
container.appendChild(table);
var tbody = document.createElement("tbody");
table.appendChild(tbody);
for(var r=0;r<100; r++) {
    var tr = document.createElement("tr");
    tbody.appendChild(tr);
    for(var c=0;c<10;c++){
       var td = document.createElement("td");
       tr.appendChild(td);
       td.appendChild(document.createTextNode("cell "+r+","+c));
   }
}
aggiungendo la tabella subito nella pagina prima di popolarla di righe e colonne, rallenta parecchio l'esecuzione perchè costringe il browser a renderizzare all'istante la cella ad ogni ciclo del loop di popolamento.

Invece spostando alla fine l'istruzione evidenziata miglioriamo le prestazioni perchè la tabella è gia completa del suo contenuto, e la renderizzazione avviene in una sola volta.
var table = document.createElement("table");
var tbody = document.createElement("tbody");
table.appendChild(tbody);
for(var r=0;r<100; r++) {
    var tr = document.createElement("tr");
    tbody.appendChild(tr);
    for(var c=0;c<10;c++){
       var td = document.createElement("td");
       tr.appendChild(td);
       td.appendChild(document.createTextNode("cell "+r+","+c));
   }
}
container.appendChild(table);





Operazione con gli attributi
Settare il valore di un attributo di un elemento:
el.setAttribute("id", "myId");
oppure
el.id = "myId";
Ottenere il valore di un attributo
var id = el.getAttribute("id");
oppure
var id = el.id;
Rimuovere un attributo
el.removeAttribute("id");
oppure
el.id = null;
Ottenere la lista degli attributi:
var attrs = el.attributes,
var s = "";
for(var i=0; i<attrs.length; i++) {
    var attr = attrs[i];
    var name = attr.nodeName;
    var value = attr.nodeValue;
....
}
Può essere interessante aggiungere un attributo "custom" come nell'esempio seguente:
var textbox = document.getElementById("myInput");
textbox.valueDefault = textbox.value;
in questa istruzione ho aggiunto la proprietà "valueDefault" che non esiste normalmente; questa istruzione potrebbe essere eseguita sull'onload della pagina; sull'onclick di un bottone per  ripristinare il valore iniziale della textbox basta utilizzare la seguente istruzione:
textbox.value = textbox.valueDefault;


Aggiungere html
Settare html:
el.innerHTML = "<a href='#'>my link</a>"
tutti gli eventuali figli verranno rimossi.
Aggiungere html:
el.innerHTML += "<a href='#'>my link</a>"
Inserire html all'inizio:
el.innerHTML = "<a href='#'>my link</a>"+el.innerHTML;
A mio giudizio è meglio evitare di utilizzare innerHTML se non per aggiungere un semplice testo formattato:
el.innerHTML = "<b>title</b><br/><i>italic</i><br/>etc....";
Per i casi  come quello dell'esempio precedente del link preferisco operare nel modo seguente:
var link = document.createElement("a");
link.href = "#";
link.appendChild( document.createTextNode("my link") );
el.appendChild(link);
La proprietà innerHTML è utile per svuotare in maniera semplice un elemento:
el,innerHTML = "";
Importante: non aggiungete nel innerHTML attributi di eventi perchè non funzionano su ie:
el.innerHTML = "<a href='#' onclick='alert(clicked);'>my link</a>";
occorre crearsi l'elemento come dell'esempio precedente a aggiungere l'handler così:
link.onclick = function(event){ alert("clicked") }


Gestire eventi
Registrare un handler di un evento:
div.onclick = function(event){ alert("clicked") }

E' possibile specificare delle istruzioni direttamente dentro il codice HTML:
<input type="checkbox" name="myCheck" onClick="alert('checked: '+this.checked)" />
Il termine this si riferisce all'elemento.

Per maggiori dettagli sulla gestione degli eventi vedere il seguente post:
http://gheryd.blogspot.com/2011/05/javascript-funzioni-compatibili-per-gli.html


Gestire le classi e le proprietà di stile
Settare una classe di stile:
el.className = "myClass";
Aggiungere una classe di stile:
el.className += " "+"myClass2";
Sostituire una classe di stile con un'altra:
el.className = el.className.replace("oldClass", "newClass");
Rimuovere una classe di stile:
el.className = el.className.replace("myClass", "");
Verificare se ha una classe di stile:
var hasMyClass = el.className.indexOf("myClass")>-1;
if( hasMyClass  ) {
    alert("has class");
}
Ottenere un'array di classi di stile
var classes = el.className.split(" ");
for(var i=0; i<classes.length; i++) {
    var class = classes[i];
...
}
Settare proprietà di stile:
el.style.borderColor = "red";
el.style.fontSize = "10px";
el.style.textAlign = "right";
el.style.backgroundColor = "#faa";
el.style.border = "1px solid #000";
in generale la proprietà in javascript è uguale alla proprietà css senza trattini:
border-color -> el.style.borderColor
font-size -> el.style.fontSize
text-align -> el.style.textAlign
background-color -> el.style.backgroundColor

Cercare tutti gli elementi con una certa classe di stile
function getElementsByClass(classname, elContainer) {
if(!classname) return null;
 elContainer = elContainer || document.body;
var els = [];
 var findElClass = function(el) {
    var nodes = el.childNodes;
for(var i=0; i<nodes.length; i++) {
var node = nodes[i];
if(node.nodeType!=1) continue;
if(node.className.indexOf(classname)>-1) els.push(node);
findElClass(node);
}
}
findElClass(elContainer);
return els;
}


Mostrare/nascondere un elemento
Mostrare:
document.getElementById("myElement").style.display="";
Nascondere:
document.getElementById("myElement").style.display="none";


Select
var sel = document.getElementById("mySelect");
Ripuliamo la select dalle option esistenti:
sel.options.length = 0;
Popoliamo la select con un option
var opt = new Option("", "value");
try {
    sel.add(opt, null);
}catch(ex){
    sel.add(opt);
}
opt.innerHTML = "text";
l'ultima istuzione ci consente di usare html entities come per esempio "&egrave;" E' importante che l'assegnazione della  proprietà innerHTML sia successiva all'instruzione di inserimento della option all'interno della select.


CheckBox
Recuperarne il riferimento DOM:
var cb = document.getElementById("myCheckbox");
Se è in un form si può ottenere in base al suo attributo name:
var cb = document.getElementById("myForm").myCheckbox;
<form id="myForm">
    <input id="myCheckbox" name="myCheckbox" />
</form>
Modificarne lo stato:
cb.checked = true;
Verificare lo stato:
if(cb.checked) {
    alert("is checked");
}
Intercettarne il cambio di stato:
cb.onclick = function() {
     //TODO handle event
}


Caricare uno script
var script= document.createElement('script');
script.src = '/js/myscript.js';
script.type = 'text/javascript';
script.async = 'true'
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(script, s);


Caricare un css
var css= document.createElement('link');
css.href = '/css/mycss.css';
css.rel= 'stylesheet';
css.type = 'text/css'
css.media = 'all';
document.getElementsByTagName("head")[0].appendChild(css);


Templates
Possiamo utilizzare una porzione di HTML adibita a template per creare altri elementi.
<div style="display:none">
<div id="template1">
<div id="#id#">
<span>#text#<span>
<div>
</div>
<div id="template2">
<div style="border:1px solid #CCC;background-color:#AAA">#block#</div>
</div>
</div>
<div id="container"></div>
Il codice HTML che utilizzeremo come template non sarà visibile in quanto è inserito in un div nascosto.
Con il seguente codice javascript di esempio aggiungiamo ad un div contenitore nuovi elementi basati sui nostri template:
var tpl1 = document.getElementById("template1").innerHTML;
var tpl2 = document.getElementById("template2").innerHTML;
var container = document.getElementById("container");
for(var i=0; i<10;i++) {
var block = block.replace("#text#", "item text "+i).replace("#id#", "item"+i);
var block2 = tpl2.replace("#block#", block);
container.innerHTML += block2;
}
La tecnica quindi consiste nel prendere il contenuto html di un template. Si sostituiscono le eventuali "chiavi" che abbiamo definito all'interno dei template con il testo che si vuole visualizzare e infine si aggiunge il codice html che si è preparato all'interno del div contenitore.
Il vantaggio di usare questo sistema è il fatto di non dover creare elementi grafici all'interno di codice javascript. La porzione di html che utilizziamo come template può essere modificata successivamente senza dover metter mano al codice javascript.

7 giugno 2011

ubuntu installare headers kernel for virtual box


Verifichiamo la versione del kernel
gheryd@gheryd-laptop:~$ uname -a
Linux gheryd-laptop 2.6.38-10-generic-pae #44-Ubuntu SMP Thu Jun 2 21:50:56 UTC 2011 i686 i686 i386 GNU/Linux
Istalliamo gli headers:
gheryd@gheryd-laptop:~$ sudo apt-get install linux-headers-lbm-2.6.38-10-generic-pae
oppure
gheryd@gheryd-laptop:~$ sudo apt-get install linux-headers-lbm-$(uname -r)

Riaggiorniamo virtual box con il nuovo kernel
gheryd@gheryd-laptop:~$ sudo /etc/init.d/vboxdrv setup

2 giugno 2011

javascript programmazione ad oggetti

Indice dei tutorials: http://gheryd.blogspot.com/2011/06/javascript-gwt-tutorials.html


Indice

  • Indroducendo
  • Function
  • Singleton
  • Classe
  • Visibilità e scope delle variabili
  • Variabili static
  • Prototype
  • Ereditarietà
  • Estendere una classe
  • Cenni sull'oggetto window
  • Approfondimento


Introducendo.
Per chi è abituato alla classica programmazione ad oggetti in C o in Java, il primo impatto con javascript risulta poco familiare, e richiede un po' di elasticità sia per quanto concerne la sintassi sia per la definizione di classe.
Javascript in quanto script e non linguaggio di programmazione puro tipizzato, permette molte libertà sugli oggetti,
Negli esempi utilizzerò analogie con la programmazione ad oggetti JAVA che spero possano aiutare nella comprensione dal punto di vista pratico. 
Insomma quando parlo di classe in javascript, in realtà è un qualcosa che si comporta come una classe. Ma non lo è.
Prima di iniziare a parlare di classi e oggetti, verrà introdotto il concetto di funzione attraverso una serie di esempi. Ritengo che aver ben chiaro cosa siano le funzioni sia fondamentale nella programmazione avanzata in javascript e credo possa essere propedeutico per gli argomenti affrontati nelle sezioni successive.


Function
Come gia saprete è possibile definire una funzione in questa maniera:
function show(message) {
    alert(message);
}
ma le funzioni in javascript sono oggetti il cui riferimento si può assegnare ad una variabile:
var show = function(message) {
     alert(message);
}
la funzione può essere così invocata:
show("hello!");
oppure:
show.call(this, "hello!");
o ancora
(show)("hello!");
in cui il termine this definisce lo scope (spiegato in seguito) della funzione, invocata al di fuori di qualsiasi oggetto si riferisce all'oggetto contenitore window.
Una funzione, in quanto oggetto, può essere passata come parametro in ingresso ad un'altra funzione:
var myLogger = function(message) {
     alert(message);
}
function show(message, logger) {
      logger(message);
}
show("hello", myLogger);
Possiamo  definirla in maniera anonima e invocarla al volo:
(function(message){
     alert(message);
})("hello");
Possiamo definire una funzione all'interno di un altra:
function show(message) {
     function log() {
           alert(message);
     }
     log();
}
show("hello");
Ad una funzione possiamo far restituire un'altro oggetto funzione:
function createLogger() {
      return function(message){
            alert(message);
     }
}
createLogger()("hello");
var logger = createLogger();
logger("hello2");
Il riferimento dell'oggetto funzione può essere passato su più variabili:
var show = function(message) {
    alert(message);
}
var show2 = show;
show2("hello");
In quanto oggetti, le funzioni possono essere create tramite new:
var show = new Function("message", "alert(message);");
show("hello");
perchè sono oggetti, la sintassi tipica di javascript ci nasconde questa loro vera natura!
Possiamo sapere i valori dei parametri passati all'invocazione della funzione:
function test() {
   var s = "";
   for(var i=0;i<arguments.length;i++) {
      var arg = arguments[i];
      s += arg+" "+typeof(arg)+"\n";
    }
   alert(s);
}
test("text", 2, function(){alert("hello")}, 2.5);
E infine, come vedremo nelle sezioni successive, possiamo instanziare un oggetto usando una funzione
come costruttore:
function Test() {
     //code
    return 5;
}
var a = new Test();
var b = Test();
Ma attenzione, la variabile a conterrà un riferimento all'instanza di un oggetto che avrà eventuali proprietà e metodi definiti secondo quanto spiegato nelle sezioni successive, mentre b conterrà il valore numerico "5".
Verificate  con un alert(a) e un alert(b) ;)
In entrambi i casi la funzione Test verrà eseguita.
Inoltre anticipo che lo scope della funzione cambia, cioè il riferimento this usato all'interno si riferirà all'oggetto che stiamo instanziando a, altrimenti all'oggetto contenitore (per esempio window per b)


Singleton
Incominciamo con la creazione di un instanza al volo:
var obj = {}
oppure
var obj = new Object();
Abbiamo assegnato alla variabile obj un'instanza di un oggetto senza definire proprietà e metodi.
Certo, così non ci serve a niente. aggiungiamogli una proprietà:
obj.prop1 = "property 1";
oppure potevamo definirla direttamente dentro l'instanza con la sintassi propertyName:value (per più proprieta utilizzare la virgola come separatore)
var obj = { prop1:"property 1" };
Proviamo a visualizzarla su un alert:
alert( obj.prop1 );
Creiamo ora un metodo alla nostra istanza che visualizza sull'alert il valore prop1:
obj.alertProp1 = function() {
     alert( this.prop1 );
}
o in alternativa:
var obj = {
   prop1:"property 1",
   alertProp1: function() {
       alert( this.prop1 );
   }
};
Per eseguire il metodo appena creato:
obj.alertProp1();
C'è ancora un'altra alternativa per accedere a tutte le proprietà e metodi del nostro oggetto:
alert( obj['prop1'] ); 
cioè il nome della proprietà è la chiave per accedere al suo valore con la stessa sintassi di un array.
Possiamo così anche ciclare tutte le proprietà di un oggetto:
var s = "";
for(var p in obj)  {
    s += p + "=" + obj[p] + " (" + typeof(obj[p])  + ")\n";
}
alert(s);
Creare in questa maniera un singleton, può essere interessante se vogliamo definire, per esempio, una serie di proprietà da passare ad una funzione:
var mySetup = {
   color: "yellow",
   backcolor: "black",
   text: "hello",
   border: 1,
   click: function(event) {
      alert("clicked");
  }
}
function createLabel(setup) {
    setup = setup || {}; //se non mi viene passato il parametro ne creo uno nuovo
    var e = document.createElement("div");
    e.appendChild( document.createTextNode(setup.text || "" ) );
    e.style.color = setup.color || "black";
    e.onclick = setup.click;
    // etc...  
    return e;
}
var label = createLabel(mySetup), 
Notate che se non aggiungete metodi al vostro singleton, abbiamo l'equivalente di una hashmap o array associativo.
A proposito di array, dimenticavo che potete aggiungere alle proprietà del vostro oggetto:
var obj = {
    prop1: "property 1",
    alertProp1: function(){  alert(this.prop1); },
    arr: [1, "2",  3 ]
}
alert( obj.arr[1] );
La proprietà arr è quindi un riferimento ad un oggetto di tipo array che ha quindi proprietà tipo length.
for(var i=0; i<obj.arr.length; i++) {
    var item = obj.arr[i];
    alert(item);
}
Un modo alternativo per definire un singleton, e che io personalmente preferisco è questo:
var obj = function() {
    var me = {};
    me.myPublicProperty = "hello";
     me.myPublicMethod = function(myparam) {
         //.....
    }
    var myPrivateMethod = function(){
          //....
    } 
    var myPrivateProperty = "world":
    return me;
}();
Notate che mettendo le parentesi tonde alla fine la funzione viene subito eseguita. La funzione restituisce un'instanza di un oggetto con metodi e proprietà.


Classe
Passiamo ora a come definire una classe.
Proviamo a creare una semplice classe che conta il numero di click su un elemento:
var ClickCounter = function(id) {
    var el = document.getElementById(id);
    this.counter = 0;
    var me = this;
    el.onclick = function(){
          me.counter++;
    };
    this.show = function() {
          alert( this.counter );
    }
}
In questa classe abbiamo definito una proprietà count e un metodo show.
Si rimanda alla sezione successiva per un chiarimento sullo scope (contesto) e la visibilità delle variabili.
Possiamo definire una classe anche con questa forma:
function ClickCounter(id) {
    var el = document.getElementById(id);
    this.count = 0;
    var me = this;
    el.onclick = function(){
          me.count++;
    };

    this.show = function() {
          alert( this.counter );
    }
}
Come in altri linguaggi l'oggetto si instanzia con "new":
var cc = new ClickCounter("myButton1");
Ma allora vi chiederete a cosa si riferisce this se  ci limitiamo a chiamare i costruttore senza new.
Si riferisce all'oggetto contenitore.
Proviamo a fare un test;
function ShowCiao() {
     this.alert("ciao");
}
Se chiamamo la funzione:
ShowCiao(); 
ci viene mostrato un alert perchè this si riferisce all'oggetto window che è il contenitore di tutti gli oggetti creati nell'ambito di una pagina web.
Mentre con
new ShowCiao(); 
non viene mostrato l'alert perchè this si riferisce all'istanza di ShowCiao che non ha il metodo alert. Questo genererebbe un errore javascript.
Un'altro modo per creare un istanza di un oggetto è questo:
var myObjFactory = function(msg) {
     var me = {};
    me.myPublicProperty = msg;
     me.myPublicMethod = function(myparam) {
         //.....
    }
    var myPrivateMethod = function(){
          //....
    } 
    var myPrivateMethod = "world":
    return me;
}
Praticamente è la stessa funzione che abbiamo visto nella sezione "Singleton", ma senza le parentesi tonde.
Per creare un'istanza è quindi sufficiente eseguire la funzione:
var myObj1 = myObjFactory("hello");
var myObj2 = myObjFactory("ciao");

Visibilità e scope della variabili
Riferiamoci sempre all'esempio precedente, la classe ClickCounter.
All'interno del costruttore abbiamo dichiarato due variabili:
this.count = 0
e
var el = document.getElementBy(id);
La differenza è che anteponendo this alla variabile questa è accessibile all'esterno, mentre con var è visibile solo all'interno del contenitore comprese sotto classi/funzioni. Praticamente è come dichiararla private
Inoltre abbiamo creato una terza variabile private:
var me = this;
A questo punto vi chiederete perchè nella funzione di onclick ho usato me mentre per la funzione show ho potuto utilizzare this per riferirmi all'instanza della classe ClickCounter.
Nell'assegnazione
el.onclick = function(){
          me.counter++;
};
se avessimo usato this ci saremmo riferiti all'oggetto contenitore el che possiede appunto la proprietà onclick. Lo scope della funzione quando invocata dal bowser è el, non il mio oggetto ClickCounter. Quindi this all'interno della funzione handler di onclick si riferisce ad el.
Mentre show è una proprietà di ClickCounter, quindi this si riferisce ad una sua istanza.
Possiamo utilizzare me all'interno della funzione di onclick perchè  ogni variabile dichiarata con var a livello superiore è visibile a livello più interno.
Per esempio:
var a = 1;
alert( a ); //show "1"
function TestClass() {
     var b = 2;
     alert( a ); //show "1"
     alert( b ); //show "2"
     function innerFunc() {
        var c = 3;
        alert( a ); //show "1"
        alert( b ); //show "2" 
        alert( c ); //show "3"
     }
      alert( c ); //show "undefined"
}
alert( b ); //show "undefined"
alert( c ); //show "undefined"
Inoltre in ogni sotto funzione sono visibili anche i parametri passati come argomento al costruttore di ClickCounter.
Per esempio  aggiungiamo  un alert che mostra il parametro id passato al costruttore:
function ClickCounter(id) {
    var el = document.getElementById(id);
    this.count = 0;
    var me = this;
    el.onclick = function(){
          me.count++;
          alert(id);
    };

    this.show = function() {
          alert( this.counter );
    }
}
Questo ci permette un trucco per passare parametri ad una funzione che per esempio non ne prevede.
Mi spiego meglio con un esempio pratico.
Assegno un handler all'evento onclick di un elemento DOM:
var el = document.getElementById("id);
el.onclick = function(event){
      document.getElementById("showContainer").innerHTML = "clicked";
}
La mia funzione verrà chiamata dal browser sul click del mio elemento el e mostrerà il messaggio all'interno di un div con id="showContainer";
Ma se usassi la stessa funzione come handler da assegnare a più elementi, potrei avere la necessita di passare altri parametri da visualizzare nel div mentre l'unico parametro che il browser mi passerà è solo l'oggetto event.
Dunque è possibile risolvere la questione creando un factory createClickHandler e sfruttando la visibilità dei parametri passati.
var createClickHandler = function(message) {
       return function(event) {
              document.getElementById("showContainer").innerHTML = message;
      }
}
document.getElementById("id1").onclick = createClickHandler("clicked on element 1");
document.getElementById("id2").onclick = createClickHandler("clicked on element 2");





Variabili static
Utilizzo il termine static in analogia con la programmazione JAVA intendendo variabili accessibili senza utilizzare un instanza.
var MyClass = function(prop) {
    this.prop = prop;  
};
Definisco così una proprietà static:
MyClass.staticProp = "static proprerty";
Attenzione però, questa proprietà non è accessibile da una instanza (per un chiarimento vedere la sezione "approfondimento" alla fine di questo tutorial):
var o = new MyClass(prop);
alert( o.staticProp ); //show undefined
Mentre è accessibile in questo modo:
alert( MyClass.staticProp );

Prototype
Precedentemente per aggiungere proprietà e motodi alla nostre classi, abbiamo usato il riferimento this all'interno del nostro costruttore.
In alternativa avremmo potuto usare il metaoggetto prototype che contiene tutti i riferimenti a proprietà e metodi precedentemente definiti e consente di aggiungerne di nuovi.
var MyClass = functon(prop) { 
    this.prop = prop;  
    var privateProp = prop;
}
MyClass.prototype.showProp = function(){ 
    alert(this.prop);
    alert(privateProp);  


}
Notate che nel metodo showProp possiamo accedere alla proprietà prop tramite this ma non possiamo accedere a privateProp. (Neanche con this.privateProp).
Con prototype possiamo anche sovrascrivere un metodo esistente.


Ereditarietà
Infine concludiamo il discorso prototype per ereditare proprietà e metodi da un'altra classe:
var BaseClass = function() { 
     this.counter = 0; 
     this.incr10 = function() {
        this.counter +=10
   }
}
var ExtClass = function() {
    this.incr20 = function() {
        this.counter += 20;
   }
}
ExtClass.prototype = new BaseClass(); //eredita metodi e proprietà di BaseClass
Se vi sembra un po' strano passare una nuova istanza piuttosto che il nome della classe, riguardate la sezione approfondimenti. Almeno intuitivamente dovrebbe esser chiaro che non ha senso passare solo ExtClass che è un riferimento ad un oggetto di tipo function. Significherebbe ereditare proprietà e metodi di un oggetto Function.
Se al posto della classe BaseExt avessimo definito un singleton:
var baseObj = {
    count: 0,
    incr10: function() { this.count +=10; }
}
avremmo potuto scrivere:
ExtClass.prototype = baseObj;

Se vogliamo utilizzare il costruttore di ExtClass al posto di quello di BaseClass.
ExtClass.prototype.constructor = ExtClass; 
In questo caso ha senso passare come costruttore il riferimento ad una instanza di una funzione.


Estendere una classe
Abbiamo gia visto con "prototype" come far ereditare metodi e proprietà di un'altra classe.
E' possibile farlo anche in questo modo:
var Class1 = function() {
    this.method1 = function() { alert("method class 1") }
    this.prop1 = "p1";
}
var Class2 = function() {
    Class1.call(this); //extends class1
    this.method2 = function () { 
          //.... 
    }
}
var obj = new Class2();
obj.method1(); //utilizziamo il metodo ereditato dal Class1.


Cenni sull'oggetto window
E' un oggetto che viene instanziato automaticamente dal browser quando viene caricata una nuova pagina.
E' l'oggetto contenitore di tutti i nostri oggetti, infatti se create una nuova proprietà di window:
window.myprop = "property";
Questa sarà visibile in ogni sottofunzione e oggetto da noi creato.

Per questo se creiamo una funzione:
function show(message){
     this.alert(message);
}
show("hello");
this si riferisce all'oggetto window, in quanto lo scope della funzione show.

L'oggetto window ci consente di accedere al DOM (document object model) per poter interagire con la nostra pagina via javascript:
window.document.getElementById("id");
ma possiamo accedervi direttamente senza utilizzare il riferimento window:
document.getElementById("id");
perchè esiste una variabile implicita
var document = window.document;
Anche la funzione alert è un metodo di window
window.alert("hello");
con il riferimento diretto implicito:
var alert = window.alert;
Ci sono tanti altri oggetti importanti che sono proprietà di window come per esempio historylocation.



Approfondimento
Il concetto di classe non è propriamente lo stesso dei linguaggi come Java, perchè non possiamo definire una classe, ma semmai un oggetto costruttore che esegue istruzioni che vanno ad arricchire di proprietà e metodi un oggetto vuoto, quello che stiamo istanziando.
Possiamo comunque testare se una certo oggetto è stato generato tramite una cerca funzione mediante l'operatore instanceof:
function Test(){
}
var t = new Test();
alert( t instanceof Test );
Dato che Object è la classe di base di ogni oggetto, verrà visualizzato true anche per :
alert( t instanceof Object );
Se avessimo usato la funzione typeof, avremmo ottenuto sempre "object":
alert( typeof(t) );
Ma per chiarire il concetto di classe in javascript, mi riferirò all'esempio della  sezione variabili static.
La proprietà  staticProp non è una variabile statica di una classe MyClass  ma è una proprietà dell'oggetto MyClass.
infatti con l'istruzione:
alert( typeof(MyClass) );
vi verrà mostrato "function".
Se vi ricordate quanto visto nella sezione function, la variabile MyClass è un riferimento ad un istanza di function, quindi è un oggetto di tipo function.
A questo oggetto ho aggiunto una proprietà che ho chiamato staticProp .
Per questo non esiste  la proprietà o.staticProp perche è la proprietà di un altro oggetto appunto.
In altre parole tramite il termine "new" viene creato un oggetto invocando l'esecuzione di un oggetto function. Ma questi due oggetti non condividono proprietà e metodi.
Quindi ricapitolando la creazione di un oggetto può avvenire in due maniere.
Tramite sintassi
var obj = { pro1:val1, prop2:val2, .... }
oppure
var obj = new ( new Function(params, body)).call(this=refNewObj,myParams); 
La seconda versione ci consente di utilizzare lo stesso oggetto function per creare più oggetti con uguali proprietà e metodi tramite l'invocazione implicita del suo metodo call. Il riferimento this si riferisce all'oggetto contenitore, in questo caso all'oggetto che stiamo creando.
La sintassi
var obj = new MyObj();
potremmo interpretarla come se il termine new instanziasse un oggetto vuoto {} e come se il termine MyObj() eseguisse la funzione che arricchisce di metodi e proprietà il nostro oggetto {} il cui riferimento viene assegnato alla variabile obj.
Infatti è equivalente a:
var obj = {};
MyObj.call(obj);
nell'argomento del metodo call abbiamo passato il riferimento all'oggetto obj come contesto(scope) per il riferimento this.
Questo ci fa capire anche che una funzione può essere il costruttore/inizializzatore di diversi oggetti, basta passargli lo scope (il riferimento all'istanza) diverso:
var f = function(){ this.prop3 = "p3"; }
var obj1 = {prop1:"p1"};
f.call(obj1);
var obj2 = {prop2:"p2"}
f.call(obj2);