Object oriented programming

Ebbene sì anche javascript ha supporto per la programmazione ad oggetti!

Abbiamo già utilizzato degli oggetti: pensate a document o xmlHttp.

I tre strumenti più importanti dell' OOP

Javascript OOP

Javascript ha alcune pecularietà per quanto riguarda l'OOP:

In Javascript gli oggetti sono collezioni di coppie nome / valore:

// definisci un semplice array associativo
var bookNames =
{
	"ASP_AJAX" : "Microsoft AJAX Library Essentials",
	"SEO_PHP" : "Professional Search Engine Optimization with PHP"
};
// visualizza SEO PHP
alert(bookNames.SEO_PHP);
        

Una funzione javascript:

// explicit function call
ShowHelloWorld();
// "Hello, World" function
function ShowHelloWorld() {
	// dichiaro le variabili
	var date = new Date();
	var hour = date.getHours();
	// un costrutto condizionale
	if (hour >= 22 && hour <= 5) {
		document.write("You should go to sleep.");
	} else {
    	document.write("Hello, world!");  
    }
}

Le funzioni Javascript sono oggetti:

// funzione per restituire l'ora
function GetCurrentHour() { // ottieni l'ora var date = new Date(); var hour = date.getHours(); // restituisci l'ora return hour; } // funzione per salutare
function DisplayGreeting(hourFunc) { // trova l'ora usando la funzione come parametro hour = hourFunc(); // saluta if (hour >= 22 || hour <= 5) { document.write("Goodnight, world!"); } else { document.write("Hello, world!");
} } // chiama DisplayGreeting DisplayGreeting(GetCurrentHour);

Le funzioni Javascript possono essere annidate (in questo caso usiamo una chiusura, cioè una funzione interna che ha accesso alle variabili private della funzione contenitore):

// crea un riferimento alla funzione di saluto
var funcDisplayGreeting = ShowHelloWorld();

// chiama la funzione
funcDisplayGreeting();

// definisci la funzione di saluto
function ShowHelloWorld () {
    // dichiara le variabili
    var date = new Date();
    var hour = date.getHours();
    // definisci una funzione interna
    function DisplayGreeting() {
        if (hour >= 22 || hour <= 5) {
            document.write("Goodnight, world!");
        } else {
            document.write("Hello, world!");
        }
    }
// restituisci la funzione come una chiusura
return DisplayGreeting;
}

Creare una classe in javascript

// il costruttore
function Table (rows, columns) {
    //proprietà di questa istanza
	this.rows = rows;
	this.columns = columns;
	// getCellCount "metodo"
	this.getCellCount = getCellCount;
}

// funzione che restituisce il numero delle celle
function getCellCount() {
	return this.rows * this.columns;
}

var t = new Table(3,5);
var cellCount = t.getCellCount();
document.write("I just created a table of " + cellCount +  " cells");

Prototyping è una feature di javascript che consente di aggiungere proprietà e metodi ad una classe al volo.

    // classe Table
function Table (rows, columns) {
	// proprietà di istanza
	this.rows = rows;
	this.columns = columns;
}

// Table.getCellCount restituisce il numero di celle
Table.prototype.getCellCount = function() {
	return this.rows * this.columns;
};

var t1 = new Table(2,3);
var t2 = new Table(3,5);

// prima tabella (6 celle)
document.write("celle della prima tabella: " + t1.getCellCount());

// seconda tabella (15 celle)
document.write("celle della seconda tabella: " + t2.getCellCount());
    

Una classe può avere metodi e proprietà statiche:

    // classe Table
function Table (rows, columns) {
    // proprietà d'istanza
    this.rows = rows;
    this.columns = columns;
}

// Table.getCellCount restituisce il numero di celle
Table.prototype.getCellCount = function() {
	return this.rows * this.columns;
};

// proprietà statiche
Table.SQUARESIZE = 2;
// static method
Table.getSquareTable = function() {
	return new Table(Table.SQUARESIZE, Table.SQUARESIZE);
}

// chiamo un metodo statico per ottenere un'istanza di una tabella quadrata
var t3 = Table.getSquareTable();

// eseguo il metodo d'istanza
document.write("L'istanza della tabella quadrata ha " + t3.getCellCount() + "celle");
    

In javascript non esistono membri privati ma si può simularne la funzionalità usando le così dette funzioni closure:

    function Table (rows, columns) {
    // save parameter values to local variables
    var _rows = rows;
    var _columns = columns;
    // return the number of table cells
    this.getCellCount = function() {
        return _rows * _columns;
    };
}

// crea una tabella
var t = new Table(3,5);
// visualizza le proprietà
document.write("Your table has " + t._rows + " rows" +
" and " + t._columns + " columns<br />");
// chiama le funzioni
document.write("The table has " + t.getCellCount() + " cells<br />");
    

Nelle applicazioni javascript i linguaggi di interscambio dati sono due: XML e JSON (Javascript object notation)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
	<response>
		<clear>false</clear>
		<messages>
			<message>
			<id>1</id>
			<color>#000000</color>
			<time>2006-01-17 09:07:31</time>
			<name>Guest550</name>
			<text>Hello there! What's up?</text>
			</message>
			<message>
			<id>2</id>
			<color>#000000</color>
			<time>2006-01-17 09:21:34</time>
			<name>Guest499</name>
			<text>This is a test message</text>
			</message>
		</messages>
	</response>  
    
[
  {"clear":"false"},
  "messages":
  [
    {"message":
      {"id":"1",
      "color":"#000000",
      "time":"2006-01-17 09:07:31",
      "name":"Guest550",
      "text":"Hello there! What's up?"}
    },
    {"message":
      {"id":"2",
      "color":"#000000",
      "time":"2006-01-17 09:21:34",
      "name":"Guest499",
      "text":"This is a test message"}
    }
  ]
]    
    

Perché usare JSON?

books.txt
    
{books:[
 {title:"Beginning PHP and MySQL E-Commerce, 2nd Edition",
  isbn:"978-1590598641"},
 {title:"Professional Search Engine Optimization with PHP",
  isbn:"978-0470100929"}
]}   
    
index.js
    
// contiene il riferimento all'oggetto XMLHttpRequest 
var xmlHttp = createXmlHttpRequestObject(); 

// ritrova l'oggetto XMLHttpRequest 
function createXmlHttpRequestObject() { 
	// contiene il riferimento all'oggetto XMLHttpRequest 
	var xmlHttp;
	// se il browser è Internet Explorer 6 o più vecchio
	if(window.ActiveXObject) {
        try {
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {
            xmlHttp = false;
        }
	}
	// se è Mozilla o altri
  	else {
		try {
			xmlHttp = new XMLHttpRequest();
		} catch (e) {
			xmlHttp = false;
		}
	}
	// ritorna l'oggetto o errore
	if (!xmlHttp) {
		alert("Error creating the XMLHttpRequest object.");
	} else {
		return xmlHttp;
	}
}

function process() {
	// se esiste l'oggetto
	if (xmlHttp) {
	// cerca di connetterti al server
        try {
            // leggo il file sul server
            xmlHttp.open("GET", "books.txt", true);
            xmlHttp.onreadystatechange = handleRequestStateChange;
            xmlHttp.send(null);
        }
        // messaggio di errore
        catch (e) {
            alert("Can't connect to server:\n" + e.toString());
        }
	}
}

// funzione chiamata al variare di onreadystatechange
function handleRequestStateChange() {
	// quando readyState è 4, la risposta è completata 
	if (xmlHttp.readyState == 4) {
	// controllo che lo stato della richiesta sia OK
        if (xmlHttp.status == 200) {
            try {
                // fai qualcosa con la risposta del server
                handleServerResponse();
            } catch(e) {
                // display error message
                alert("Error reading the response: " + e.toString());
            }
        } else {
            // display status message
            alert("There was a problem retrieving the data:\n" + xmlHttp.statusText);
        }
		}
}


// gestisce la risposta del server
function handleServerResponse() {
	// trasforma in json
	// (va bene solo per una demo, va fatto lato server)
	var jsonResponse = eval ('(' + xmlHttp.responseText + ')');
	// genera l'HTML
	var html = "";
	// itera sulla struttura
	for (var i=0; i<jsonResponse.books.length; i++) {
		html += jsonResponse.books[i].title + ", " + 
        jsonResponse.books[i].isbn + "<br />";
	}
	// ottieni un riferimento all'elemento HTML contenitore nella pagina
	myDiv = document.getElementById("myDivElement");
	// inserisci l'HTML
	myDiv.innerHTML = "<p>Server says: </p>" + html;
}