Le basi del linguaggio JavaScript
←
→
Trascrizione del contenuto della pagina
Se il tuo browser non visualizza correttamente la pagina, ti preghiamo di leggere il contenuto della pagina quaggiù
Le basi del linguaggio JavaScript Presentazione dell'opera Usare JavaScript significa conoscere le istruzioni che si possono scrivere, capirne il significato e imparare a creare programmi che risolvano i problemi iniziali. In questo tutorial, tratto dal libro Programmare con JavaScript, di Ivan Venuti, impariamo a conoscere questa tecnologia e ad utilizzarla per le nostre applicazioni. • Introduzione Introduzione a JavaScript , Script e HTML • Istruzioni e dati Istruzioni e dati , Numeri , Valori di verità • Variabili Dichiarare le variabili , Conversioni tra tipi diversi • Il flusso di esecuzione Modifiche al flusso , Il blocco switch , I cicli for e while • Funzioni Introduzione alle funzioni , Funzioni predefinite • Vettori Introduzione ai vettori , Vettori a più dimensioni
Introduzione a JavaScript Come tutti i linguaggi di programmazione, JavaScript ha una sintassi ben definita. Per sintassi si intende come scrivere istruzioni valide, ovvero riconosciute nel linguaggio e correttamente interpretate da un programma in grado di eseguire codice JavaScript (per esempio un browser come Internet Explorer o Mozilla Firefox). La sintassi di JavaScript si basa su poche e semplici regole e su un certo insieme di parole riservate e di funzioni predefi nite. Anziché enumerare tutte le regole ed elencare in maniera prolissa tutte le funzioni e parole chiave, verranno presentati semplici e signifi cativi esempi d’uso, al fine di rendere subito chiaro il modo in cui applicare ai casi più ricorrenti i “mattoncini” base del linguaggio. Che fare di questi “mattoncini”? Un programma non è un’accozzaglia di istruzioni elementari di per sé sensate (e quindi semanticamente corrette): è necessario imparare a metterle in ordine in modo che l’esecuzione di tutte le istruzioni dia il risultato voluto. Questa parte verrà meglio compresa analizzando gli esempi riportati, ma sarà sempre compito del programmatore scrivere programmi corretti secondo le regole sintattiche e, soprattutto, che facciano le cose per cui sono stati pensati. Chi è nuovo alla programmazione può trovare utili i riferimenti in Tabella 2.1, che aiutano a comprendere come, a partire da un’idea astratta, questa si possa scomporre in passi elementari fino a definire un algoritmo, base di partenza per la scrittura di un programma vero e proprio con un linguaggio specifico, come può essere, appunto, JavaScript. Tabella 2.1 • Nozione di algoritmo • Algoritmi e Flow chart • Definizioni e link ad algoritmi • Da un master di introduzione alla programmazione, con lucidi e link
Script e HTML Il primo problema è: dove si può salvare un programma scritto in JavaScript? Una volta salvato, con che cosa lo si può eseguire? Per fortuna, per scrivere il primo programma JavaScript è necessario solo un editor di testo (vanno bene anche Blocco note o WordPad, presenti nelle distribuzioni standard di Windows). In un nuovo documento di testo, scrivere le seguenti righe: ? 1 2 alert("Benvenuto!"); 3 Una volta salvato il file, assegnandogli un nome a piacere e un’estensione che può essere .htm oppure .htm oppure .htm .html (si usi, per esempio, primo_programma.htm) lo si può aprire con un qualsiasi browser (negli esempi si farà quasi sempre riferimento a Internet Explorer e Mozilla Firefox; la mag- gior parte degli esempi funzionano anche su altri browser). In Figura 2.1 si può osservare l’esecuzione del primo programma. Come si può osservare, gli strumenti da usare per scrivere programmi JavaScript possono essere molto semplici. In questo capitolo tutti gli esempi possono essere scritti all’interno dei tag del file appena salvato o su un nuovo file (per comodità i tag non saranno più scritti, ma è importante mantenerli anche negli esempi successivi). Più avanti nel tutorial si mostreranno strumenti più evoluti adatti a scrivere (o verificare) programmi complessi.
Istruzioni e dati Ogni programma JavaScript può essere costituito da una o più istruzioni (dette anche “comandi”). Ogni istruzione è separata da quella successiva mediante il carattere “;” (punto e virgola). In realtà è possibile scrivere le istruzioni anche su righe diverse (separate quindi da un carattere di “a capo”), ma è bene abituarsi a inserire sempre e comunque il punto e virgola. Ogni programma che si rispetti ha dei dati su cui operare. I dati che JavaScript considera in modo differente sono di tre tipi: stringhe di caratteri, numeri e valori di verità; sono poi definite anche delle operazioni per manipolare ciascun tipo di dato. Stringhe di caratteri Le stringhe di caratteri (d’ora in poi chiamate semplicemente stringhe) altro non sono che uno o più caratteri racchiusi tra apici (singoli o doppi). Già il primo esempio del libro ne ha usata una: “Benvenuto!” è proprio una stringa di 10 caratteri (infatti gli apici non fanno parte della stringa, ma sono solo un modo per delimitarla). L’operazione principale è la concatenazione. Essa si indica con il segno “+” (più); per esempio: alert(“mi chiamo” + “ Ivan Venuti”); concatena la prima stringa con la seconda e mostra un messaggio con la scritta “mi chiamo Ivan Venuti” In maniera del tutto equivalente, JavaScript permette di usare gli apici singoli per racchiudere una stringa. Questo può essere utile se, all’interno di una stringa, si vuol rappresentare il carattere doppio apice; infatti, non lo si può scrivere come un qualsiasi altro carattere: “Michele disse:”che bella giornata!”” In questo modo, infatti, i doppi apici dopo i due punti chiuderebbero la stringa e quel che segue ne sarebbe fuori. Una soluzione è appunto quella di usare l’apice singolo come delimitatore: ʻMichele disse:”che bella giornata!”ʼ Ma cosa accade se una stringa racchiude, al suo interno, sia apici singoli sia doppi? Evidentemente non basta più avere a disposizione due tipi di delimitatori! In questi casi si deve ricorrere all’escape dei caratteri. Con questo termine si indica il fatto che il carattere è preceduto da un simbolo speciale (simbolo di escape, per l’appunto). In JavaScript tale simbolo è la barra rovesciata (o backslash): “\”; questo carattere sta a indicare che quello che segue deve essere trattato come un carattere speciale e non più per il carattere che rappresenta; in questo modo \’ e \” non sono più delimitatori di stringhe, ma proprio il carattere apice singolo e, rispettivamente, apice doppio. Pertanto, potremmo scrivere la seguente stringa: ʻAll\ʼuna, Michele disse:”che bella giornata\”ʼ senza far sì che l’apice dopo All chiuda la stringa. In modo analogo si possono usare i caratteri in Tabella 2.2 per indicare dei caratteri non rap- presentabili (anche per essi si fa uso del carattere speciale di escape).
Tabella 2.2 – Alcuni caratteri speciali esprimibili in JavaScript. Carattere Significato \b Carattere di backspace \t Tab orizzontale \n New line (nuova linea) \r Carriage return (a capo) \\ Backslash \” Doppio apice \’ Apice singolo Numeri In JavaScript è possibile rappresentare valori interi come pure valori con cifre decimali. Entrambi sono rappresentabili anche con l'usuale notazione scientifica, che fa uso dell'esponente. Ecco esempi di numeri validi: 10 12.234 12e+02 Il primo è l'usuale numero intero dieci, il secondo è il numero dodici se- guito da tre cifre decimali e il terzo è il dodici con esponente due (12 x 102), ovvero 1200. I calcolatori hanno risorse (di memoria RAM o su disco) finite. Pertanto anche i tipi di dato che possono rappresentare sono finiti. Di solito, anziché permettere di rappresentare numeri (o altri dati!) arbitrariamente grandi, viene posto un limite allo spazio che il linguaggio utilizza per ciascun dato. Per JavaScript questo limite è dato da 64 bit. Senza scendere troppo nei dettagli "interni", basti sapere che questo pone un vincolo su quali numeri possono essere rappresentati. Per gli interi è possibile rappresentare qual- siasi numero nell'intervallo -9007199254740992 e +9007199254740992. Questo vincolo non rappresenta quasi mai un problema, a meno di ope- razioni matematiche su cifre astronomiche. Anche i numeri con decimali hanno una limitazione, sia sul numero minimo/massimo sia sul numero di cifre decimali rappresentabili. Questo problema si presenta nelle usuali operazioni tra numeri. Per esempio, la moltiplicazione è espressa con un asterisco (*), la divisione con la barra verticale (/). Si provi a eseguire il seguente codice: alert(32/3/1.1*3*1.1); Benché le regole matematiche ci dicano che le operazioni di divisione e moltiplicazione dovrebbero "annullarsi" e dare come risultato il numero originario (cioè 32), si scopre che, a causa degli errori di rappresentazione, il risultato è diverso (Figura 2.2). Però, se non si ha intenzione di scrivere programmi matematici, questi vincoli per ora possono essere ignorati. Invece, è il caso di approfondire le altre operazioni disponibili sui numeri. In Tabella 2.3 è mostrata una prima sintesi.
Tabella 2.3 - Operazioni matematiche. Esempio Operazione Significato (risultato) + Usuale somma tra numeri 5+2 (=7) - Se usato tra due numeri, rappresenta 5-2 (=3) l'operazione di differenza; se usato da solo davanti al numero, cambia il suo segno -2 (=-2) * Moltiplicazione tra numeri 5*2 (=10) / Divisione tra numeri 5/2 (=2.5) % Modulo (resto della divisione intera) 5%2 (=1) Un esempio dell'applicazione dell'operazione di modulo è la verifica se un numero è pari; lo è quando: numero % 2 restituisce 0; ma come si "confronta" il risultato dell'operazione con un numero che, come in questo caso, è una costante? Valori di verità Domande come "7 è più grande di 5?", a cui si può rispondere sì o no, possono anche essere espresse come affermazioni: "7 è più grande di 5!". In questo caso l'affermazione può essere o vera o falsa. Questi due valori sono detti anche valori di verità. JavaScript li rappresenta con un tipo di dato chiamato anche "booleano" (in onore di Bool, un celebre matemati- co che per primo studiò i valori di verità e le operazioni su tali valori). Un booleano si rappresenta con due costanti: True False (chi conosce l'inglese vi può riconoscere la traduzione di "Vero" e "Falso"). Un siffatto valore è usato per le operazioni di confronto. Per esempio: alert(7>5); alert(5==3); mostrano come risultato, rispettivamente, True False. Infatti, è vero che il 7 è maggiore di 5, mentre non è vero che 5 è uguale a 3 (si noti il doppio segno di uguaglianza, per distinguere dall'operazione di assegnamento). In Tabella 2.4 sono riportati gli operatori di confronto. Tabella 2.4 - Operatori di confronto. Operazione Significato Esempio Uguaglianza 1 == = Diverso da (contrario di uguaglianza) 1 != 2 Minore 1
Maggiore 2>0 Minore o uguale 1 = Esistono poi degli operatori, chiamati operatori logici, che permettono di comporre più espressioni logiche elementari per scriverne di complesse. Per esempio, per esprimere il confronto "5 è maggiore di 4 e 3 è maggio- re di 1", si usa l'operatore alert(5>4 && 3>1); Si noti che la frase è vera solo quando entrambe le condizioni lo sono. Per esemplificare questo fatto si è soliti rappresentare l'operatore facendo tutti gli incroci delle diverse possibilità, come mostrato in Tabella 2.5. Tale tabella si chiama tabella di verità, un analogo delle tabelle pitagoriche per le operazioni aritmetiche. Tabella 2.5 - Tabella di verità per l'operatore && (AND logico). Primo argomento Secondo argomento Risultato False False False False True False True False False True True True In maniera analoga si può definire l'OR ("oppure") logico, dove il risultato è vero purché sia vero almeno uno degli argomenti; la Tabella 2.6 mostra la tabella di verità di OR. Tabella 2.6 - Tabella di verità per l'operatore || (OR logico). Primo argomento Secondo argomento Risultato False False False False True True True False True True True True Infine, si segnala l'operatore di negazione logica (NOT) che si esprime con il segno di punto esclamativo: !. Esso si applica a un solo argomento e lo trasforma nel suo opposto: True diventa False False diviene True Precedenza degli operatori Gli operatori booleani hanno il seguente ordine di precedenza: dapprima si applica il NOT (!), poi eventuali AND (&&) e infine gli OR (!!). Un'espressione viene valutata fin quando si è certi del risultato dell'operazione; per esempio, se valutando (espressione1 && espressione2) l'interprete verifica che espressione1 vale false, non serve che valuti espressione2, perché si sa già che il risultato dell'AND è False.
Dichiarare le variabili Fino a ora si sono visti dei dati, di diverso tipo, e delle espressioni. Ma usare solo dati ed espressioni è come ragionare senza avere memoria del passato. Ogni nuovo dato (o espressione calcolata) fa dimenticare quello precedente. Chiaramente, questo impedisce di creare programmi di una certa complessità. Per fortuna esiste il concetto di "variabile", che può essere pensato come un contenitore a cui si dà un nome. Riferendosi al nome si può sia reperire il contenuto sia impostarlo. In JavaScript qualsiasi nome che non è una parola chiave è una variabile. Per esempio: pippo = 3; indica una variabile, chiamata pippo, al cui interno memorizziamo il valo- re (in questo caso numerico) . Come si è detto è anche possibile leggere il contenuto di una variabile; basta che la variabile sia specificata in un po- sto che non si trovi a sinistra di un assegnamento; vediamo due esempi: alert(pippo); pluto = pippo; Nella prima istruzione si mostrerà il valore contenuto nella variabile pippo in una finestra del browser; nella seconda si assegna alla variabile pluto o stesso contenuto della variabile pippo Se si prova a leggere il contenuto di una variabile a cui non è stato asse- gnato alcun valore, JavaScript segnalerà un errore. Dichiarare le variabili Benché non sia strettamente necessario, è bene abituarsi a dichiarare ogni variabile che si usa. Per farlo basta far precedere la parola al nome della variabile: var pippo; Si vedrà nel seguito perché questo è importante. Una cosa che può stu- pire chi è abituato a usare altri linguaggi è che non c'è indicazione sul tipo di dati che la variabile può contenere. Infatti, le variabili in JavaScript possono contenere qualsiasi tipo di dato e anche dati di tipo diverso; per esempio, è corretto scrivere: var pippo; pippo = 3; pippo = "del testo"; Esiste anche una forma compatta per gli operatori matematici di Tabella 2.3, in particolare nei casi in cui il valore di una variabile, dopo aver appli- cato l'operazione, viene riassegnato alla stessa variabile: pippo = pippo * 2; Per questi casi (che sono molto frequenti) si può usare la notazione compatta, che prevede di specificare l'operatore prima del segno di assegnamento: pippo *= 2;
Un'altra operazione molto comune è l'incremento di un'unità e il decre- mento di un'unità; per questi due casi si usano, rispettivamente, gli ope- ratori pippo--; pippo++; che equivalgono a: pippo = pippo - 1; pippo = pippo + 1; C'è da prestare attenzione alle forme compatte di somma e sottrazione, nel caso esse vengano usate in espressioni; si consideri il seguente caso: a = 1; b = 1+ a++; Quanto valgono le variabili b al termine delle due istruzioni? Facendo una semplice prova si verifica che sia sia b valgono 2. Ovvero la seconda istruzione ha fatto prima la somma tra 1 e il valore precedente di , poi è stata incrementata di uno. Per questa caratteristica le operazioni a++ si chiamano, rispettivamente, post-incremento e post-decremento (perché l'operazione viene effettuata dopo l'uso del valore contenuto nel- la variabile se questa è usata in espressioni). In maniera analoga, esistono le operazioni di pre-incremento (++a) e pre-decremento (--a). Ecco al- ora che se si scrive: a = 1; b = 1+ ++a; si può verificare che vale sempre 2, mentre b ora vale 3. Occorre fare attenzione quando si utilizzano gli operatori di pre- o post- incremento in espressioni booleane complesse; si consideri, per esempio, questo caso: var a = 0; var b = 0; var bool1 = (a++>0 || b++>0); var bool2 = (a++
Valutando bool1, l'interprete valuta la prima espressione: a++>0. Per far- lo, il valore attuale di (che è 0) viene valutato e quindi confrontato. Il confronto dà il risultato False e poi (attenzione, poi) è incrementato di 1. Visto che poi c'è un OR logico, e la prima parte è stata valutata False, l'interprete valuta anche la seconda parte per decidere il valore comples- sivo dell'espressione. Lo fa in maniera analoga alla prima parte, per cui il risultato complessivo è False e anche b viene incrementato di uno. A questo punto si valuta bool2. La prima espressione è a++
Il risultato è uguale in entrambi i casi. Qual è il motivo per cui ora non ser- vono più le parentesi tonde? La risposta è che gli operatori hanno diverse regole di precedenza: prima viene applicato l'operatore , poi il (come d'altro canto ci è stato insegnato fin dall'introduzione delle ope- razioni elementari: prima si eseguono le moltiplicazioni e le divisioni, poi eventuali somme e differenze). Se si vuol trasformare una stringa in un numero si può usare la funzione parseInt() per ottenere un numero intero, oppure parseFloat() per ottenere un numero con la virgola. Si faccia attenzione perché il parsing su una stringa che non è un numero fa restituire NaN (valore particolare che indica "Not A Number", ovvero "non è un numero"). Nel caso la stringa abbia un numero come prima parte, e poi una qualsiasi stringa, restituisce comunque il valore di tale numero. Per esempio, le seguenti istruzioni restituiscono tutte il valore 12: parseInt(ʻ12ʼ) parseInt(ʻ12pippoʼ) parseInt(ʻ12 12 12ʼ) parseInt ha un secondo parametro (opzionale) che rappresenta la base da usare nel parsing del numero. Tale base può essere un numero da 2 a 36. Ecco, per esempio, come eseguire il parsing di una stringa in base 16 (il risultato, anche per queste istruzioni, è il numero 12): parseInt(ʻcʼ,16) parseInt(ʻ0x0cʼ,16) Attenzione Chi ha poca dimestichezza con i numeri in base diversa dal 10, può far riferimento alla pagina http://it.wikibooks.org/wiki/Esercitazioni_pratiche_ di_elettronica/I_sistemi_di_numerazione per un’ampia introduzione e utili esempi. Modifiche al flusso Fino a ora sono stati mostrati insiemi di istruzioni che vengono eseguite una alla volta, una di seguito all'altra. Non c'è modo di "evitare" l'esecuzione di un'istruzione o di ripeterne una (o diverse). Tuttavia, spesso vi è proprio la necessità di eseguire un'istruzione solo sotto certe condizioni, oppure bisogna eseguire una porzione di programma un numero di volte non noto a priori. In questi casi, è necessario ricorrere alle istruzioni che modificano il flusso del programma. Istruzioni if/else Si supponga, per esempio, di voler stampare il messaggio "numero pari" se il numero è divisibile per 2, altrimenti "numero dispari". Un modo è usare l'istruzione if/else in questo modo: if (numero%2==0) alert("numero pari"); else alert("numero dispari"); In pratica, dopo l'istruzione if va specificata un'espressione booleana (racchiusa tra parentesi tonde)
e, se essa restituisce il valore di verità True, esegue l'istruzione successiva; se invece vale False esegue l'istru- zione specificata nel ramo else. Si noti che il ramo else potrebbe an- che non essere presente. Talvolta si potrebbe avere la necessità di spe- cificare condizioni ulteriori nel caso in cui la prima non sia soddisfatta. In queste situazioni si possono inserire anche altre condizioni "in cascata", grazie al costrutto else if if (numero%2==0) alert("numero pari"); else if (numero%3==0) alert("numero dispari e divisibile per 3"); else alert("numero dispari e non divisibile per 3"); Blocchi di istruzioni Nel caso di condizioni if/else, ma anche in altre situazioni, si potrebbe voler eseguire più di una istruzione in un caso o nell'altro. L'unico modo per raggruppare un certo numero di istruzioni è racchiuderle in blocchi, ossia insiemi di istruzioni racchiuse tra parentesi graffe. Per esempio: if (numero%10==0){ alert("numero divisibile per 10"); alert("esso vale:"+numero); Il blocco switch Nel caso vi siano molte condizioni da verificare, l'uso del costrutto if/ then/else può risultare noioso; in questi casi si preferisce ricorrere allo switch. Esso ha la seguente forma: switch(numero){ case 1: alert("Lunedì"); break; case 2: alert("Martedì"); break; case 3: alert("Mercoledì"); break; case 4: alert("Giovedì"); break; case 5: alert("Venerdì"); break; case 6: alert("Sabato"); break; case 7: alert("Domenica"); break;
default: alert("Giorno non valido"); In pratica, tra parentesi si trova la variabile (o il valore) da testare. Seguono tanti in cui viene usato il valore da confrontare; se uno di questi è uguale al valore da testare, vengono eseguite le istruzioni che seguono. Se non c'è un break vengono eseguite tutte le istruzioni dal punto di en- trata fino alla fine dello switch. Se nessuno dei valori confrontati è uguale, allora vengono eseguite le istruzioni della clausola default A differenza di altri linguaggi, JavaScript permette di usare anche espres- sioni all'interno della clausola case da testare: altro=88; test=1322; fine=11; msg = "numero "; switch(1322){ case altro: msg +=" uguale ad altro"; break; case test : msg +=" uguale a test"; break; case fine : msg += " uguale a fine"; break; Ci si potrebbe chiedere come mai i progettisti del linguaggio abbiano scelto di usare le etichette come punti di ingresso, lasciando al program- matore l'onere di inserire un break se non vuole continuare con l'esecuzio- ne delle istruzioni successive; c'è da dire che è una scelta condivisa anche da altri linguaggi (quindi ha, con tutta probabilità, delle origini storiche). In ogni caso, a volte questa scelta permette di realizzare degli algoritmi che, altrimenti, sarebbero molto più complessi. Si consideri il seguente scenario: in input c'è il giorno della settimana, che rappresenta il primo giorno di lavoro. Data una paga giornaliera, si vuole conoscere la paga della settimana in base al giorno di inizio; si potrebbe fare così: var giorno = "Lunedì"; var pagaGg = 100; var pagaTot = 0; switch(giorno){ case "Lunedì" : pagaTot += pagaGg; case "Martedì": pagaTot += pagaGg; case "Mercoledì": pagaTot += pagaGg; case "Giovedì": pagaTot += pagaGg; case "Venerdì": pagaTot += pagaGg; case "Sabato" : pagaTot += pagaGg; I cicli for e while Il ciclo for Spesso vi è la necessità di eseguire una o più istruzioni per un certo nume- ro di volte. Per farlo si usa un ciclo. In JavaScript esistono tre tipi di ciclo: for while do/while Il primo, che è anche il più usato, va scritto in questo modo: for(inizio; condizione; fine)
istruzione/i n inizio si deve inizializzare la variabile che viene detta anche "conta- tore del ciclo". La condizione serve a indicare quando si deve ripetere il ciclo (in pratica, il ciclo viene ripetuto se la condizione risulta vera); fine indica l'istruzione da effettuarsi a fine ciclo. Per esempio: msg = ""; for(i=1; i
msg = ""; i=1; do{ msg = msg+i; i++; } while(i
break; case 6: alert("Sabato"); break; case 7: alert("Domenica"); break; default: alert("Giorno non valido"); } Se si prova a scrivere questo codice all'interno di un documento HTML, si noterà che non accade nulla. Infatti, quella che è stata scritta è la de- finizione di una funzione. La funzione si deve invocare: per farlo, occorre scrivere il nome della funzione, mentre tra le parentesi tonde vanno pas- sati i parametri. Per esempio, scrivendo le seguenti istruzioni dopo aver inserito la funzione: nomeGiorno(2); nomeGiorno(5); nomeGiorno(15); si ottengono, in successione, le scritte "Martedì", "Venerdì" e "Giorno non valido". Si noti che se vengono scritte prima le istruzioni e poi la definizione della funzione, il risultato non cambia. A questo punto si può intuire l'utilità della definizione delle funzioni: esse permettono di racchiudere pezzi di codice con una logica "unitaria" e di riutilizzare quindi in più punti la stessa logica senza dover duplicare il codice. Spesso si preferisce far restituire dalla funzione un valore e lasciare a chi la invoca il compito di usare il risultato come meglio crede: per farlo, si usa la parola chiave return seguita dal valore da restituire. La funzione precedente può essere riscritta così: function nomeGiorno(numero) { switch(numero){ case 1: return "Lunedì"; case 2: return "Martedì"; case 3: return "Mercoledì"; case 4: return "Giovedì"; case 5: return "Venerdì"; case 6: return "Sabato"; case 7: return "Domenica"; default: return "Giorno non valido"; } Si può osservare che sono state eliminate le istruzioni break; infatti il return restituisce il controllo a chi ha invocato la funzione; per questo il break è divenuto, in questo esempio, superfluo. Chi chiama la funzione può decidere cosa fare del valore. Se, come prima, lo si vuole mostrare, si deve invocare la funzione in questo modo: alert(nomeGiorno(2)); alert(nomeGiorno(5)); alert(nomeGiorno(15)); Nel corso del libro si farà un uso frequente delle funzioni, fino a creare vere e proprie librerie di funzioni utilizzabili in più contesti. Funzioni predefinite JavaScript possiede già alcune funzioni di utilità; esse sono chiamate predefinite, per distinguerle da
quelle che può definire un qualsiasi programmatore. Si è già avuto modo di usare la funzione alert, che mostra a video, in una finestra a sé stante, il parametro passatole. La sua utilità è unicamente quella di presentare dei valori; se accanto a un messaggio si vuol chiedere all'utente di fare una scelta (del tipo sì/no o conferma/an- nulla), si può usare la funzione predefinita confirm (Figura 2.6): var scelta = confirm("Sei sicuro di voler procedere?"); Se si visualizza il valore restituito si noterà che, quando l'utente preme sul pulsante Annulla, la funzione restituisce False; quando l'utente preme su OK essa restituisce True Esiste anche un'ulteriore funzione predefinita, chiamata prompt ve per chiedere all'utente di inserire un valore qualsiasi (Figura 2.7): var val = prompt("Valore:"); EVAL Un'altra funzione estremamente potente (e per questo utile) è eval. Essa valuta una qualsiasi stringa e tenta di interpretarla come codice JavaScript. Un esempio: eval("alert(ʻun testʼ)"); ha lo stesso effetto di scrivere la seguente istruzione JavaScript: alert(ʻun testʼ); Ecco, per esempio, come creare una funzione utile per scrivere gli esempi di questo libro: function mostra(cosa){ alert(cosa+ " = "+ eval(cosa)); Nella sua semplicità consente, per esempio, di mostrare delle maschere in cui la parte sinistra è una stringa che descrive cosa si valuta, la parte destra il risultato della valutazione. Per esempio: mostra("Math.PI"); mostra il risultato di Figura 2.8 (si vedrà nel prossimo capitolo il significato di Math, anche se, fin d'ora, si intuisce che con P si indica la costante PI greco).
Introduzione ai vettori Spesso si ha la necessità di memorizzare collezioni di oggetti. Si supponga di voler leggere 10 valori diversi e di volerne trovare il valore maggiore. Chi inizia a programmare potrebbe pensare di creare 10 variabili diverse e di trovare il valore maggiore mediante una sequenza molto lunga di if Ma si supponga che il numero di valori da leggere sia 100. A questo punto diventa praticamente impossibile creare le 100 variabili e usare una serie di if in cascata per la soluzione del problema. Cosa dire poi se si permet- te all'utente di decidere il numero di elementi da inserire? A questo punto non si saprebbe davvero come fare. Per fortuna esistono i vettori (chiamati anche array): li si può pensare come dei contenitori (come le variabili) ma con tanti scomparti; ogni scomparto può contenere un valore distinto ed è identificato da un numero, che indica la sua posizione all'interno del vet- tore (Figura 2.9). Come si può notare dalla figura gli elementi di un vettore possono essere di qualsiasi tipo e non essere necessariamente contigui. Si noti anche che l'indice (o posizione) del vettore parte da 0 (ovvero, lo zero identifica la prima posizione del vettore). Il modo più semplice per creare un vettore è usare le parentesi quadre: var vettore = []; Un vettore simile è senza elementi. Se si vuol creare un vettore con degli elementi si possono scrivere gli elementi stessi, separati da virgole, all'in- terno delle parentesi: var vettore = [ "elem 1", 3, 5, , "Test"]; Quest'ultimo vettore è quello a cui si riferisce la Figura 2.10. Accedere agli elementi del vettore Si può accedere a un qualsiasi elemento del vettore usando il nome del vettore stesso, seguito da parentesi quadre con, al loro interno, la po- sizione del vettore a cui si vuole accedere. Ecco come aggiungere due elementi a vett e poi stampare il primo: var vett = []; vett[0] = "Nuovo elem"; vett[1] = "Altro elem"; alert(vett[0]); La vera "forza" dei vettori, ovvero l'accesso ai loro elementi con gli indici numerici, viene apprezzata adoperandoli con i cicli. Ecco, per esempio, come leggere un numero qualsiasi di elementi e assegnarli agli elementi di un vettore (Figura 2.11): var v = []; var numero = prompt("quanti elementi vuoi inserire?"); for(i=0; i
Attenzione Quando si legge un valore con prompt si ottiene sempre e comunque una stringa. Se si ha bisogno di usare numeri, è necessario eseguirne il parsing con una delle funzioni predefinite (per esempio parseInt() per ottenere un intero e parseFloat() per ottenere un numero con virgola). Ora si è in grado di risolvere, per esempio, anche il problema iniziale, ov- vero trovare il minimo e il massimo valore tra gli elementi inseriti (Figura 2.12): var v = []; var numero = prompt("quanti numeri vuoi inserire?"); for(i=0; iv[i]) min=v[i]; if (max
seguito da un punto e dalla parola chiave length In realtà questa notazione è usata per accedere a particolari proprietà di una struttura dati che è tra le più flessibili di JavaScript: gli oggetti. Il prossimo capitolo li approfondirà e non mancheranno le sorprese anche sul modo in cui JavaScript tratta i vettori. Basti sapere che per creare un array a una certa dimensione si potrebbe anche scrivere: var v = new Array(dimensione); Vettori a più dimensioni Un vettore può avere anche più di una dimensione; infatti, il linguaggio permette di creare vettori a un numero qualsiasi di dimensioni. Tuttavia, a differenza di altri linguaggi, questa possibilità non è utilizzabile con un costrutto standard in fase di definizione. Si consideri il seguente proble- ma: per un'ipotetica azienda, si vorrebbe un vettore venditeOra che usi come prima dimensione quella dei giorni (365 giorni in un anno) e come seconda quella delle ore (24 ore per ogni giorno). Dati un giorno e un'ora qualsiasi, il vettore memorizza le merci vendute per quell'ora di quello specifico giorno. In alcuni linguaggi è possibile usare una notazione come questa: var venditeOra[365][24]; In JavaScript una simile istruzione genererebbe un errore. Infatti, è pos- sibile creare solo una dimensione per volta. Come realizzare, allora, la seconda? Si deve accedere a un elemento per volta e creare, su ogni elemento, un nuovo array: var venditeOra = new Array(365); for(i=0; i
Puoi anche leggere