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 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:[
{title:"Beginning PHP and MySQL E-Commerce, 2nd Edition",
isbn:"978-1590598641"},
{title:"Professional Search Engine Optimization with PHP",
isbn:"978-0470100929"}
]}
// 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;
}