Tutorial JavaScript – Parte I

JavaScript è un linguaggio di programmazione che a prima vista sembra facile da imparare, soprattutto per chi conosce Java o un altro linguaggio con la stessa sintassi. In realtà non è così semplice come può sembrare e sicuramente non è un Java in miniatura che gira all’interno di una pagina web!
In questo tutorial vedremo come entrare nel mondo JavaScript (avendo comunque un background di programmazione) per poterlo usare in modo strutturato (anche object oriented) e per avere una base per utilizzare i vari framework tipo jQuery, extJs/Sencha Touch, Dojo, Prototype e script.aculo.us.

JavaScript è un linguaggio di programmazione con una storia abbastanza particolare: è nato per aggiungere dinamicità alle pagine html, ma inizialmente veniva usato solo per cose semplici. Con l’avvento di Ajax è diventato fondamentale per tutto il web 2.0: la “j” di Ajax sta proprio per JavaScript. Dopo qualche anno è diventato “scomodo” per le incompatibilità fra i vari browser e sono nati vari framework (per esempio GWT sviluppato da google) per scrivere rich internet application evitando di usarlo. Quando in molti erano contenti di essersi liberati di JavaScript è tornato di moda e alcune librerie di nuova generazione lo usano, per esempio:

  • MongoDB e CouchDB lo usano come sostituto del linguaggio sql
  • node.js permette di scrivere codice lato server in JavaScript
  • Titanium Appcelerator permette di scrivere applicazioni mobile multipiattaforma in JavaScript

Iniziamo con un esempio che contiene 3 function JavaScript:

String.prototype.r = function() {
    return this.split("").reverse().join('')
}

function a(b) {
    if (arguments.length == 1) {
        return b.slice(1, 3) + b[1];
    } else if (arguments.length == 2) {
        b = arguments[0] + arguments[1];
    }
    return (b || this).r();
}

(function b() {
    alert(a.apply(" esoc") + a("mnopqrs") + a("ets", "ivaj "));
})()

L’alert nell’ultima function quando viene eseguito? E che cosa mostra? Se questo pezzo di codice vi sembra scritto in arabo (ve l’avevo detto che non è Java in miniatura!) continuate a leggere questo post!
Per provare i vari esempi di questo tutorial è consigliata l’installazione del plugin di Firefox firebug che, oltre a un debugger JavaScript e a tante altre funzionalità utilissime, mette a disposizione una shell interattiva in cui è possibile eseguire codice JavaScript. Nelle ultime release anche gli altri browser (per esempio internet explorer 8, chrome e safari) hanno un tool simile, alcuni sono plugin aggiuntivi altri sono già nell’installazione standard del browser.


tutorial javascript

I tipi di dato primitivi

JavaScript definisce nativamente 3 tipi di dato primitivi:

  • numeri: non c’è distinzione fra interi e numeri con virgola, esiste solo un tipo number simile al double Java
  • boolean: può assumere i valori true e false
  • stringhe: possono essere usati come delimitatori sia l’apice singolo che il doppio apice

Tutto il resto è un oggetto, anche una data, una function e un array sono oggetti e non tipi primitivi.

Gli oggetti

Un oggetto JavaScript può essere visto come una map: a una chiave (il nome del campo) corrisponde un valore, che può essere a sua volta un tipo primivo o un oggetto. Un oggetto può essere creato in stile Java con una new o può essere creato al volo usando le parentesi graffe. Per accedere al valore di un campo può essere usata sia la notazione con il punto che quella con le parentesi quadre. La definizione di una variabile avviene con la keyword var: JavaScript è non tipato quindi non è possibile usare il tipo di dato nella definizione. Se si omette la keyword var l’oggetto risulta definito nella variabile globale window.

var intero = 5;  
var stringa = 'abc' + "def";  
var booleano = true;  
//creazione con una new  
var oggetto = new Object();  
//aggiungo campi runtime  
oggetto.campoIntero = intero;  
//aggiungo il campo abcdef  
oggetto[stringa] = booleano;  
//creazione al volo  
var oggetto2 = {  
    campoIntero: intero,  
    campoStringa: stringa + "g"  
};  
oggetto.campoIntero == oggetto2['campoIntero']

E’ possibile usare l’istruzione for del JavaScript per iterare su tutti i campi di un oggetto:

var o = {  
    a: 5,  
    b: 'xy',  
    c: true  
}  
var chiavi = '', valori = '';  
for (var c in o) {  
    chiavi += c;  
    valori += o[/c];  
}  
chiavi == 'abc'  
valori == '5xytrue'

Se si cerca di accedere a un campo non definito viene ritornato il valore undefined, in JavaScript esiste anche il classico valore null. Se si usa l’operatore == i valori null e undefined sono uguali, per fare un controllo che li distingue è necessario usare gli operatori === e !== che effettuano un controllo anche del tipo.

null == undefined  
null !== undefined  
5 == '5'  
5 !== '5'  
0 == false  
0 !== false

Per valutare le condizioni JavaScript utilizza un approccio in stile linguaggio C: i valori false, null, undefined, 0 e la stringa vuota sono interpretati come false, tutto il resto è true. Sfruttando questo e il fatto che la valutazione dell’or ritorna il primo valore non valutato come false si ha un costrutto tipico del JavaScript che permette di impostare valori di default in modo veloce:

var a = null;  
var b = 0;  
var c = a || b || 10;  
var d;  
if (a)  
    d = a;  
else if (b)  
    d = b;  
else  
    d = 10;  
c == d  

L’and viene invece sfruttato per evitare di scrivere un if (ad esempio per controllare che più variabili siano non null):

var a = 10;  
var b = 5;  
var c = a && b;  
var d;  
if (a)  
    d = b;  
else  
    d = a;  
c == d

Gli array

Un array è un oggetto generico che viene usato come contenitore di dati indicizzati, il campo length contiene il valore dell’indice più grande più uno. Un array può essere creato sia con una new che con una notazione con le parentesi quadre:

var a1 = new Array();  
var a2 = [1, 2, 3, 4, 5];  
a1[4] = 'abc'  
a1.length == a2.length

Oltre a length su un array possono essere invocate anche alcune function predefinite: vediamo le principali con alcuni esempi:

var a1 = ['a', 'b', 'c'];  
//push aggiunge un elemento in coda all'array  
a1.push('d');  
//pop rimuove e ritorna l'ultimo elemento  
a1.pop() == 'd'  
//concat concatena più array senza modificarli  
var a2 = ['d', 'e', 'f'];  
var a3 = a1.concat(a2);  
a3.length == 6  
//slice copia e ritorna una porzione di elementi  
var s = a3.slice(3, 5) ;  
s[0] == 'd'  
s[1] == 'e'  
//splice rimuove o sostituisce alcuni elementi, ritorna gli elementi
//rimossi, prende come parametri l'indice da cui iniziare, il numero
//di elementi da rimuovere e gli elementi da aggiungere  
var rim = a3.splice(1, 4, 'x', 'y')  
rim.length == 4  
rim[0] == 'b'  
rim[1] == 'c'  
rim[2] == 'd'  
rim[3] == 'e'  
a3.length == 4  
a3[0] == 'a'  
a3[1] == 'x'  
a3[2] == 'y'  
a3[3] == 'f'  
//passando 0 come secondo parametro di splice si ha un metodo
//che inserisce alla posizione passata  
var a4 = ['a', 'b'];  
a4.splice(1, 0, 'c', 'd');  
a4[0] == 'a'  
a4[1] == 'c'  
a4[2] == 'd'  
a4[3] == 'b'

La notazione json

  1. diminuzione della larghezza di banda necessaria per il traferimento: la notazione json è più compatta rispetto all’xml
  2. semplificazione nella lettura: basta interpretare la stringa invece di eseguire un parsing di xml

Un esempio di oggetto json è il seguente:

{  
    type: "menu",  
    value: "File",  
    items: [  
        {"value": "New", "action": "CreateNewDoc"},  
        {"value": "Open", "action": "OpenDoc"},  
        {"value": "Close", "action": "CloseDoc"}  
    ]  
}

Le function

Una function è considerata in JavaScript come un qualsiasi oggetto, può quindi essere aggiunta come valore di un campo di un oggetto e può essere passata e ritornata da altre function. Vediamo la sintassi con un esempio:

function somma(n1, n2) {  
    return n1 + n2;  
}

Essendo un oggetto come gli altri possiamo creare una function anche come una normale variabile:

var somma = function(n1, n2) {  
    return n1 + n2;  
};

In JavaScript non esiste l’overloading: una function è definita univocamente dal nome e se due function hanno lo stesso nome la seconda sovrascrive la prima. Una function può essere invocata con un numero di parametri diverso da quelli della definizione: all’interno della function i parametri non passati sono undefined; infine si può accedere all’array di parametri tramite la variabile arguments:

function sommaGenerica() {  
    var s = 0;  
    for (var j = 0; j < arguments.length; j++) {  
        s += arguments[j];  
    }  
    return s;  
}  
sommaGenerica(1, 2, 3) == 6

Per adesso ci fermiamo qui: abbiamo visto la base del JavaScript, ma ancora mancano i costrutti più evoluti. Se provate a riguardare l'esempio all'inizio del post probabilmente alcune cose rimangono ancora oscure! Vedremo di svelarle nella seconda parte di questa guida Javascript.

Nel frattempo se volete approfondire l'argomento vi consiglio il libro Javascript: The good parts. In questo libro l'autore Douglas Crockford descrive sola una parte del linguaggio Javascript (quella "buona") e descrive anche la parte che, nonostante sia presente nel linguaggio, sarebbe meglio non usare.



A presto!

Fabio Collini

Software Architect con esperienza su piattaforma J2EE e attualmente focalizzato principalmente in progetti di sviluppo di applicazioni Android. Attualmente sono nel team Android di Cynny, ci stiamo occupando dello sviluppo dell'app Morphcast. Coautore della seconda edizione di Android Programmazione Avanzata e docente di corsi di sviluppo su piattaforma Android. Follow me on Twitter - LinkedIn profile - Google+