JavaScript

Transcript

JavaScript
Introduzione alle funzioni
Le funzioni sono un comodo contenitore in cui racchiudere il codice. Anziché “sporcare la pagina”
mischiando codice HTML e linguaggio JavaScript, è sufficiente inserire il codice in una funzione e
richiamare la funzione quando occorre.
La sintassi necessaria per creare una funzione è questa:
function nomeFunzione() {
// qui il nostro codice
}
Insomma tutto il codice da noi elaborato deve essere contenuto all’interno delle parentesi graffe, che
delimitano l’inizio e la chiusura della funzione (Con Windows per digitare le parentesi graffe
comporre la combinazione di tasti: AltGr+Shift+parentesi quadre. Lo “Shift” è il tasto
con la freccia necessario per scrivere le maiuscole, da non confondere con il “Caps Lock”).
La funzione che abbiamo appena creato si richiama poi con:
nomeFunzione();
da inserire nell’elemento <script>, all’interno dell’head, nel corpo della pagina, oppure all’interno
di un elemento, da richiamare tramite un evento. Con questo codice non facciamo che richiamare il
gruppo di istruzioni contenuti all’interno della funzione.
Per mantenere poi ordine all’interno della pagina, dobbiamo inserire tutte le nostre funzioni
all’interno della HEAD del documento, e richiamarle nella stessa HEAD o nel BODY (come detto –
facendovi riferimento tramite un evento oppure inserendole nel punto esatto in cui ci serve
richiamarle).
Vediamo un semplice esempio, per afferrare subito il concetto. Da inserire nel tag <script>:
function saluta() {
alert ("ciao");
}
saluta();
C’è una particolarità da notare che finora non abbiamo ancora espresso con chiarezza, ma che
dovrebbe essere emersa dai numerosi esempi presentati: ogni istruzione JavaScript deve essere
conclusa con un punto e virgola.
Se rielaboriamo alcuni degli esempi, esaminati nelle pagine precedenti, tramite l’utilizzo delle
funzioni otteniamo una sintassi molto più “pulita”:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Corso JavaScript ad esempi</title>
<script type="text/javascript">
/* prima funzione */
function saluta() {
alert("ciao");
}
/* seconda funzione */
function apriFinestra() {
/* creo una variabile contenente la larghezza della finestra */
larghFinestra=500;
/* creo una variabile contenente l'altezza della finestra */
altezFinestra=500;
/* creo una variabile e mi ricavo il valore della
* posizione della finestra a sinistra dello schermo */
sinistra=screen.width-larghFinestra+20;
/* creo una variabile e mi ricavo il valore della
* posizione della finestra dall'alto dello schermo */
alto=(screen.height-larghFinestra)/2;
window.open("http://www.html.it","", "left="+sinistra+",top="+alto+",
width="+larghFinestra+", height="+altezFinestra+", menubar, toolbar");
}
/* terza funzione */
function scriviRisoluzione(){
document.write("Stai navigando a una risoluzione di "+screen.width+" x
"+screen.height);
}
</script>
</head>
<body onLoad="apriFinestra();">
<a href="#" onClick="saluta();">clicca per ricevere un saluto</a> <br/><br/>
<script type="text/javascript">
scriviRisoluzione();
</script>
</body>
</html>
Nell’esempio che abbiamo esaminato or ora sono presenti tre funzioni, due delle quali vengono
richiamate attraverso l’utilizzo di eventi, mentre la terza viene richiamata all’interno della pagina.
Da notare inoltre che l’evento “onLoad” viene eseguito subito dopo il completamento della pagina,
dunque una funzione richiamata all’interno del BODY della pagina verrà “lanciata” prima della
funzione richiamata dall’evento onLoad. Nel nostro esempio la funzione “scriviRisoluzione()”
viene lanciata prima della funzione “aprifinestra()”.
È evidente che tramite un utilizzo oculato di funzioni ed eventi è possibile creare delle pagine molto
ordinate, con il codice JavaScript suddiviso in molteplici parti, “azionato” soltanto quando
richiamato.
Nota a margine
In realtà è possibile specificare che la funzione deve essere richiamata da un determinato evento
direttamente dal codice JavaScript.
Il codice è questo (da inserire nell’ <head>):
<script type="text/javascript">
function saluta() {
alert("ciao");
}
// assegnamo il gestore saluta all'evento onload
document.onload = saluta();
// la funzione viene lanciata non appena il documento è caricato
// notare che "onload" è scritto tutto minuscolo
</script>
Come si vede nell’esempio il collegamento tra l’evento “onload” e la funzione “saluta” viene creato
dalla stessa sintassi JavaScript, anziché essere specificato nel codice HTML.
Dove utilizzare le funzioni I
Prendiamo in considerazione questo esempio:
<script type=”text/javascript”>
scritta=”ciao”;
function saluta() {
alert(scritta);
}
saluta();
</script>
in questo primo esempio una variabile viene creata e inizializzata al di fuori della funzione ed è poi
richiamata all’interno della funzione stessa, senza che tutto ciò crei minimamente dei problemi.
Esaminiamo un altro esempio:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<title>Corso JavaScript ad esempi</title>
<script type=”text/javascript”>
function saluta() {
//inizalizzo le variabili all’interno delle funzioni
scritta2=”ciao”;
scritta3=”prova scrittura”
}
saluta(); //richiamo la funzione
alert(scritta2); //faccio riferimento alla variabile creata nella funzione
</script>
</head>
<body >
<script type=”text/javascript”>
document.write(scritta3);
</script>
</body>
</html>
In questo esempio due variabili vengono create all’interno delle funzioni e richiamate poi
dall’esterno: in un caso la variabile viene scritta addirittura in pagina senza che tutto ciò crei
minimamente dei problemi.
Molti linguaggi di programmazione creano una distinzione netta tra le variabili create all’interno del
programma (nel nostro caso all’interno della pagina) e le variabili create all’interno delle funzioni.
Le prime prendono il nome di variabili globali e sono valide in tutto il programma, le seconde
vengono dette variabili locali e sono valide soltanto all’interno della funzione. Per indicare il
contesto entro cui una variabile è valida si parla di solito di ambito delle variabili (in inglese
“scope”).
Per semplificare la vita del programmatore, in JavaScript questa distinzione è valida solo se
espressamente richiesta dal programmatore stesso. Visto che questi sono i nostri primi programmi,
possiamo evitare di distinguere tra variabili locali e variabili globali. Facciamo però attenzione a
non incappare in due tipici errori:
1. Evitiamo di sovrascrivere le variabili nei nostri programmi. Ad esempio:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<title>Corso JavaScript ad esempi</title>
<SCRIPT type=”text/javascript”>
function scriviNome() {
// inizalizzo le variabili all’interno delle funzioni
nome=prompt(“inserisci qui il tuo nome”,”il tuo nome”);
}
scriviNome(); // richiamo la funzione
nome=”Gianni”; // in questo modo sovrascrivo la variabile
</SCRIPT>
</head>
<body >
<SCRIPT TYPE=”text/javascript”>
document.write(nome);
</SCRIPT>
</body>
</html>
Nell’esempio, dato che la variabile “nome” viene inizializzata dopo la funzione, il contenuto
della variabile creata nella funzione viene sovrascritto.
2. Ricordiamoci di utilizzare gli eventi nel modo appropriato:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<title>Corso JavaScript ad esempi</title>
<script type=”text/javascript”>
function scriviNome() {
//inizalizzo le variabili all’interno delle funzioni
nome=prompt(“inserisci qui il tuo nome”,”il tuo nome”);
}
</script>
</head>
<body onLoad=”scriviNome()”>
<script type=”text/javascript”>
document.write(nome);
</script>
</body>
</html>
In questo caso siamo incappati un errore grossolano: la variabile “nome” viene richiamata
dal document.write (che si trova nel corpo della pagina) senza essere stata ancora creata,
infatti l’evento onLoad (che richiama la funzione che crea la variabile) viene lanciato dopo il
completamento della pagina.
Dove utilizzare le funzioni II
Abbiamo visto che, se vogliamo, possiamo fare a meno di distinguere tra variabili globali (quelle
valide in tutta la pagina) e variabili locali (quelle valide solamente all’interno delle funzioni).
Qualche lettore esperto, può però trovarsi più a suo agio mantenendo questa distinzione (gli altri
lettori possono passare oltre senza troppe preoccupazioni).
Per creare le variabili locali (valide solo nella funzione) è sufficiente premettere alla dichiarazione
di variabile il prefisso var.
Guardate cosa succede se modifichiamo l’esempio della lezione precedente con il prefisso var:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<title>Corso JavaScript ad esempi</title>
<script type=”text/javascript”>
function saluta() {
//inizializzo le variabili all’interno delle funzioni
var scritta2 = “ciao”; // variabile locale
var scritta3 = “prova scrittura”; //variabile locale
}
saluta(); //richiamo la funzione
alert(scritta2); //faccio riferimento alla variabile creata nella funzione
</script>
</head>
<body >
<SCRIPT TYPE=”text/javascript”>
document.write(scritta3);
</SCRIPT>
</body>
</html>
le variabili non vengono più “lette”, perché definite come “locali” all’interno della funzione.
Dunque il motore di scripting della pagina si dimentica di queste variabili appena uscito dalla
funzione.
Un ulteriore esempio chiarirà tutto:
<script type=”text/javascript”>
scritta2=”ciao globale”; // variabile globale
function saluta() {
// inizializzo le variabili all’interno delle funzioni
var scritta2=”ciao locale”; // variabile locale
}
// richiamo la funzione
saluta();
// faccio riferimento alla variabile
alert(scritta2);
</script>
Tra le due variabili “vince” la variabili globale, perché la variabile locale ha il suo ciclo di vita solo
all’interno della funzione.
Se utilizziamo variabili globali e variabili locali, le funzioni diventano una scatola chiusa, e il suo
interno non vede nulla di quanto avviene al di fuori. Avremo quindi bisogno di strumenti per
passare dei valori all’interno della funzione, e di altri strumenti per estrarre quello che abbiamo
elaborato dentro la funzione stessa: li vedremo nelle prossime lezioni.
Nota: per evitare problemi con variabili locali e variabili globali, semplicemente omettete “var”
quando create delle variabili.
I parametri delle funzioni
In molti casi può essere utile passare dei “valori variabili” a una funzione, in modo da poterla
utilizzare in molti contesti. In questo modo non siamo costretti a scrivere una funzione ogni volta
che dobbiamo cambiare qualcosa: basta scrivere il codice una sola volta e individuare delle porzioni
variabili.
Facciamo un esempio concreto. C’è una pagina in cui vogliamo aprire tre differenti finestre di
diverse dimensioni:
• la prima di 300×290 e deve contenere un link a www.html.it
• la seconda di 400×390 e deve contenere un link ad freeasp.html.it
• la terza di 500×490 e deve contenere un link a free.php.html.it
In questo caso non è necessario scrivere tre differenti funzioni: basta scrivere la funzione una volta
sola, specificando che ci sono delle parti della funzione che variano. Queste parti variabili si
chiamano argomenti o parametri e vanno espresse nella dichiarazione della funzione.
Così:
function nomeFunzione(arg1, arg2, arg3, arg4) { //codice }
I parametri vengono indicati all’interno del codice nel punto che ci occorre, e svolgono a tutti gli
effetti il ruolo di variabili.
Nella chiamata alla funzione dovremo poi indicare il valore che i parametri assumono nel caso
specifico. Ad esempio:
nomeFunzione(“finestraFreeAsp”,1 , 400, 390, “http://freeasp.html.it”);
Gli argomenti sono quindi una specie di “ponte” tra l’interno e l’esterno della funzione.
Vediamo un esempio semplice che ci permetta di afferrare subito il concetto:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<title>Esempio</title>
<script type=”text/javascript”>
function saluta(nome) { //nome è l’argomento
alert(“ciao “+nome);
}
</script>
</head>
<body>
<a href=”#” onClick=”saluta(‘Saibal’)”>Saluta Saibal</a><br/>
<a href=”#” onClick=”saluta(‘Phantom’)”>Saluta Phantom</a><br/>
<a href=”#” onClick=”saluta(‘Berenicebis’)”>Saluta Berenicebis</a><br/>
</body>
</html>
Come si vede nell’esempio la funzione è sempre la stessa, ma c’è un “punto” che cambia: quel
“punto variabile” è l’argomento che viene indicato nella dichiarazione della funzione, cioè qui:
function saluta(nome)
per poi essere applicato all’interno del codice al momento giusto. Cioè qui:
alert(“ciao “+nome);
Torniamo all’esempio delle finestre, e riprendiamo quanto visto in una lezione precedente:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<title>Esempio</title>
<script type=”text/javascript”>
/* nella funzione sottostante passiamo 4 argomenti:
il nome della finestra è necessario per aprire differenti finestre e non sempre la stessa */
function apriFinestra(nomeFinestra,larghezza,altezza,collegamento) {
/*assegno alla variabile il valore dell’argomento*/
larghFinestra=larghezza;
/* assegno alla variabile il valore dell’argomento*/
altezFinestra=altezza;
sinistra=screen.width-larghFinestra+20;
alto=(screen.height-larghFinestra)/2;
/*gli ultimi due argomenti sono nella stringa sottostante */
window.open(collegamento,nomeFinestra,”left=”+sinistra+”,top=”+alto+”,width=”
+larghFinestra+”,height=”+altezFinestra+”,menubar,toolbar,resizable”);
//NB la riga precedente non va a capo
}
</SCRIPT>
</head>
<body>
<a href=”#”
onClick=”apriFinestra(‘finestraHTML’,300,290,’http://www.html.it’)”>HTML.it</a><br/>
<a href=”#”
onClick=”apriFinestra(‘finestraASP’,400,390,’http://freeasp.html.it’)”>FREEASP</a><br/>
<a href=”#”
onClick=”apriFinestra(‘finestraPHP’,500,490,’http://freephp.html.it’)”>FREEPHP</a><br/>
</body>
</html>
come si vede la funzione che apre la finestra è sempre la medesima, cambiano invece le dimensioni,
il nome della finestra e il link: tutto questo viene passato alla funzione come argomento.
Restituire i valori di una funzione
Abbiamo visto che se utilizziamo un approccio rigoroso con variabili globali e locali (quelle create
con var) le funzioni diventano una scatola chiusa, e tutto quello che succede all’interno di una
funzione non ha nessuna validità al di fuori. Ma come fare per comunicare con l’esterno?
Se dobbiamo introdurre dei valori all’interno della funzione possiamo utilizzare gli argomenti, ma
finora non abbiamo visto ancora nulla che ci permetta di restituire all’esterno dei valori.
Vediamo un esempio.
Per comodità decidiamo di inserire in una funzione il prompt con la richiesta di nome (che abbiamo
esaminato in una precedente lezione) e decidiamo di utilizzare la dichiarazione di variabili locali.
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<title>Corso JavaScript ad esempi</title>
<script type=”text/javascript”>
function chiediNome() {
var nomeUtente=prompt(“Scrivi il tuo nome”,”il tuo nome”);
//ATTENZIONE!
//la variabile è definita come “locale”
//se non mettessimo “var” funzionerebbe tutto
}
</script>
</head>
<body>
<script type=”text/javascript”>
chiediNome(); // lancio la funzione
document.write(“Benvenuto “);
document.write(nomeUtente);
</script>
</body>
</html>
Come si vede lo script che abbiamo composto dà errore, semplicemente perché la variabile è
preceduta da var e quindi definita come locale: il browser (o più esattamente il motore di scripting
del browser) si scorda della variabile appena fuori dalla funzione.
Per risolvere questo problema dobbiamo utilizzare l’istruzione return, che serve per restituire i
valori e fa sì che una funzione comunichi con l’esterno. Il return va messo sempre alla fine della
porzione di codice che ci interessa, e si utilizza in due modi:
return seguito da una variabile
(o da un’espressione)
return da solo
restituisce il valore della variabile
(o dell’espressione)
fa terminare la porzione di codice
Basta poi catturare tutta quanta la funzione in una variabile, per aver catturato il valore restituito
dalla funzione stessa. Così:
miaVariabile = miaFunzione();
Vediamo l’esempio precedente adattato con l’uso di return.
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<title>Corso JavaScript ad esempi</title>
<script type=”text/javascript”>
function chiediNome() {
var nomeUtente=prompt(“Scrivi il tuo nome”,”il tuo nome”);
return nomeUtente; //la funzione restituisce ora il nome dell’utente
}
</script>
</head>
<body>
<script type=”text/javascript”>
valoreCatturato=chiediNome(); // lancio la funzione
document.write(“Benvenuto “);
document.write(valoreCatturato);
</script>
</body>
</html>
In JavaScript per lo più utilizzerete un approccio “soft” alle variabili, e spesso non distinguerete tra
variabili globali e locali, quindi non vi capiterà spesso di usare return. Infatti per avere a
disposizione nel resto della pagina un valore creato all’interno di una funzione, basta crearlo senza
usare var. Tutto funziona alla perfezione se scriviamo:
function chiediNome() {
nomeUtente=prompt(“Scrivi il tuo nome”,”il tuo nome”);
}
chiediNome();
alert(nomeUtente);
Come abbiamo visto però, il return serve anche per bloccare l’esecuzione del codice e ci sono
particolari contesti in cui può tornare particolarmente utile: lo vedremo nelle prossime lezioni.
Vediamo comunque un esempio per afferrare subito il concetto:
function saluta() {
alert(“primo ciao”);
return;
alert(“secondo ciao”);
}
saluta();
come si vede il secondo alert non viene eseguito, perché posto dopo il return.
Nota Bene
A scanso di equivoci, è opportuno specificare che né gli argomenti, né il return sono obbligatori: in
molti casi avremo funzioni che non hanno bisogno di nessun argomento, e che non restituiscono
alcunché.
Verificare una condizione: if
Il codice che abbiamo utilizzato fino a questa lezione è molto semplice: si è sempre trattato di
lavorare con le finestre, inserire dati in variabili e al massimo abbiamo sommato delle stringhe. Se
la programmazione fosse soltanto questo, avremmo la possibilità di compiere ben poche operazioni.
In realtà programmare è qualcosa di più complesso, dal momento che siamo in grado di porre delle
condizioni, impostare delle ripetizioni, e altro.
Possiamo ad esempio volere che il programma che stiamo scrivendo faccia qualche cosa soltanto a
una determinata condizione (ad esempio solo nel caso in cui il browser dell’utente sia Internet
Explorer). Potremmo schematizzare così:
• se una determinata condizione è verificata…
• fai questo
Più esattamente si tratta di prendere una determinata condizione, valutarla, e se è vera (cioè se
restituisce true), verranno eseguite le istruzioni indicate. Se la condizione non si verifica non verrà
fatto alcunché.
Ecco una rappresentazione grafica di quello che abbiamo appena detto:
Figura 1. Diagramma di flusso
Ed ecco il modo in cui JavaScript (in maniera del tutto analoga al C) esprime questo costrutto:
if (espressione da verificare) {
//istruzioni
}
La struttura della sintassi è chiara: la condizione da verificare viene indicata tra le parentesi tonde
che seguono l’if (in inglese “se”, appunto). Notare le parentesi graffe, che racchiudono il codice da
eseguire nel caso in cui la condizione sia valida. È bene inoltre ricordare, che ogni istruzione deve
essere seguita dal punto e virgola.
Per afferrare subito la sintassi per un po’ vedremo alcuni semplici esempi numerici. Non appena
saremo padroni dei concetti torneremo ad esaminare esempi pratici, inerenti il webpublishing.
Vediamo un esempio di if:
x = 5; // sostituite x con quello che volete
if (x == 5) {
alert(“la variabile x è uguale a 5″);
}
L’espressione (x == 5) risulta vera, dal momento che la variabile è stata creata appositamente con il
valore richiesto dalla condizione (ma d’ora in poi provate a sostituire il valore della variabile creata
all’inizio degli esempi per vedere i differenti risultati degli script). Infatti se invece abbiamo:
x = 6;
if (x == 5) {
alert(“la variabile x è uguale a 5″);
}
L’espressione dell’esempio viene valuta, ma dal momento che non è vera l’alert non viene
visualizzato.
Negli esempi appena esaminati, abbiamo incontrato per la prima volta l’operatore di uguaglianza,
cioè ==, che ci permette di verificare che le variabili (o le espressioni) a sinistra e a destra
dell’uguale abbiano lo stesso valore.
Nota a margine
Le parentesi graffe sono necessarie soltanto nel caso in cui le istruzioni da eseguire siano più di una,
altrimenti possono essere anche omesse. Infatti le parentesi graffe indicano sempre l’esistenza di un
blocco di istruzioni (le abbiamo già incontrate nelle funzioni con la medesima funzione). Ad
esempio:
x=5;
if (x==5)
alert(“la variabile x è uguale a 5″);
o anche tutto su una riga:
x=5;
if (x==5) alert(“la variabile x è uguale a 5″);
mettere le parentesi graffe in presenza di una sola istruzione tuttavia non costituisce errore e di
solito conferisce una maggior leggibilità al codice.
Operatori relazionali
Nella lezione precedente abbiamo introdotto il concetto intuitivo di “condizione da valutare”. In
realtà si tratta più esattamente di valutare che la relazione tra due valori (o espressioni) sia vera.
Nella lezione precedente abbiamo introdotto il concetto intuitivo di “condizione da valutare”. In
realtà si tratta più esattamente di valutare che la relazione tra due valori (o espressioni) sia vera.
<valore> <operatore di relazione> <valore>
Ad esempio:
x == 5
Ed ecco gli altri operatori:
Operatore
>
>=
<
Spiegazione
maggiore
maggiore uguale
minore
Esempio
x>7
x>=7
x<7
<=
minore uguale
x<=7
==
uguale
nome==”Mario”
!=
diverso
Nome!=”mario”
Un errore tipico dei principianti è quello di confondere l’operatore di uguaglianza, con il doppio
simbolo “=” (==) con l’operatore di assegnamento (=). Ad esempio questo:
x=8;
if (x=5) { //dovrebbe essere ==, non =
alert(“la variabile x è uguale a 5″);
}
risulterà sempre vero, perché all’interno delle parentesi viene assegnato un valore, e non viene
invece eseguito un confronto.
Inserire la relazione tra due valori in un alert è un metodo sbrigativo per sapere se la relazione è
vera oppure no:
x = 5;
alert(x >= 5);
alert(x < 5);
Finora abbiamo sempre assegnato il valore delle variabili all’interno della pagina: tuttavia non si
tratta di un procedimento molto utile, dal momento che la possibilità di valutare la veridicità di un
espressione ci interessa soprattutto quando non conosciamo i valori delle variabili.
Ci interessa sapere ad esempio se:
variabileUtente == variabileImpostataDaMe;
oppure
variabileAmbiente == variabileImpostataDaMe;
negli esempi delle prossime lezioni vedremo come “catturare” questi valori
Come funzionano else ed else if
Abbiamo visto che è possibile fare eseguire un’azione se una condizione è vera. Ma se volessimo
far eseguire un’altra azione nel caso in cui la condizione sia falsa?
Possiamo allora impostare un programma di questo tipo:
• se una determinata condizione è verificata…
fai questo
• in tutti gli altri casi…
fai quest’altro
Possiamo esprimere graficamente questo concetto con i diagrammi di flusso:
Figura 1. Diagramma di flusso II
e traducendolo in codice JavaScript:
if (condizione) {
// istruzione 1
}
else {
// istruzione 2
}
Ad esempio:
x = 9;
if (x < 7) {
alert(“x è minore di 7″);
}
else {
alert(“x non è minore di 7″);
}
Con una sintassi analoga si possono anche verificare l’esistenza di diverse condizioni. Si tratta di
impostare un programma di questo genere:
• se si verifica questa condizione…
fai questo
• altrimenti, se si verifica quest’altra condizione…
fai quest’altro
• in tutti gli altri casi…
fai quest’altro
che graficamente si può rappresentare così:
Figura 2. Diagramma di flusso III
Per esprimere l’else if, JavaScipt prevede una sintassi di questo genere:
if (prima condizione) {
//istruzioni
}
else if (seconda condizione) {
//istruzioni
}
else {
//istruzioni
}
Ed ecco un esempio:
nome=”Gianni”;
if (nome==”Mario”) {
alert(“ciao Mario”);
}
else if (nome==”Gianni”) {
alert(“ciao Gianni”);
}
else {
prompt (“identificati”,”inserisci il tuo nome”);
}
È possibile anche introdurre più di un else if all’interno dello stesso blocco di codice; è dunque
possibile verificare quante condizioni si desidera.
Esempio: individuare il browser
Abbiamo visto, quando abbiamo parlato del DOM che la difficoltà maggiore della programmazione
JavaScript consiste nel fatto che a browser differenti corrispondono differenti modelli di documenti.
JavaScript ci consente di verificare in un modo molto semplice se una proprietà di un oggetto esiste
oppure no, è sufficiente utilizzare la sintassi:
if (nomeOggetto.nomeProprietà) {
//istruzioni
}
se la proprietà esiste, nomeOggetto.nomeProprietà restituisce true e quindi la condizioni è
verificata (e dunque le istruzioni vengono eseguite). Se la proprietà non esiste
nomeOggetto.nomeProprietà restituisce false, e quindi la condizione non è verificata.
Questo accorgimento ci è molto utile nei molti casi in cui vogliamo adattare la pagina a seconda del
browser: ad esempio per spedire un foglio di stile differente a seconda del browser usato.
Abbiamo detto che internet Explorer (qualsiasi versione) viene identificato da document.all,
Netscape da document.layers, i browser di nuova generazione da document.getElmentById.
Per individuare il browser e far eseguire un codice differente a seconda del risultato, dovete allora
impostare un programma di questo genere:
• se è presente document.all
codice da eseguire (se entriamo in questa casistica, i successivi else if ed else non vengono
neanche valutati)
• se invece è presente document.layers
codice da eseguire
• se è presente document.getElementById
codice da eseguire
• in tutti gli altri casi
codice da eseguire
Traducendo quanto appena detto in codice JavaScript:
if (document.all) { alert(“stai usando Internet Explorer”);
}
else if (document.layers) {
alert(“stai usando Netscape 4″);
}
else if (document.getElementById) {
alert(“stai usando Netscape 6, o un browser di nuova generazione”);
}
else {
prompt (“stai usando un browser sconosciuto”); }
Attenzione però alle “proprietà mimetiche” di Opera, che è in grado di camuffarsi da Internet
Explorer o da Netscape. Se volete approfondire l’argomento, e vedere come spedire un differente
foglio di stile esterno a seconda del browser potete consultare due articoli su html.it: L`arte dello
sniffing: come riconoscere i browser e Riconosciamo i browser con Javascript.
Gli operatori logici
È possibile annidare un if dentro l’altro, in modo da poter valutare anche situazioni particolarmente
complesse. Ad esempio:
// provate a cambiare il valore, eventualmente
// indicando anche delle stringhe
valore = 5;
if (isNaN(valore) ) {
/* isNaN() vuol dire "not a number" e serve per
* vedere se il tipo di dati in esame è differente
* da un numero */
alert(valore + " non è un numero!");
} else {
}
if (valore >= 9) {
alert(valore + " è maggiore o uguale a 9")
} else {
alert(valore + " è minore di 9")
}
Ma oltre ad utilizzare annidamenti particolarmente complessi, possiamo usare gli operatori logici
per concatenare diverse espressioni e creare condizioni complesse.
La sintassi è questa:
( (<espressione 1>) <operatore logico> (<espressione 2>) )
dove (come abbiamo visto nelle precedenti lezioni) <espressione 1> ed <espressione
2> stanno per:
<valore1> <operatore relazionale> <valore 2>
Ad esempio:
x = 6;
if ( (x >= 5) && (x <= 7) ) {
alert ("x è compresa tra 5 e 7");
}
In questo modo possiamo valutare più condizioni contemporaneamente. Gli operatori logici che
utilizzerete maggiormente sono i seguenti:
Operatore
&&
||
Descrizione
“and logico”
Devono essere vere le espressioni a destra e
sinistra dell’uguale.
Esempio
x=6;
if ( (x>=5) && (x<=7) ){
alert (“x è compresa tra 5 e 7″);
}
nome=”Gianni”;
if ( (nome==”Gianni”) ||
“or logico”
(nome==”Marco”) ) {
Deve essere l’espressione a sinistra dell’uguale o
alert (“Sei Gianni oppure Marco”);
quella a destra
}
“not”
Viene posta di fronte all’espressione in questione
!
e la nega:
- se è false la cambia in true
- se è true la cambia in false
Gli operatori logici funzionano nel modo seguente:
nome=”Marco”;
if ( !(nome==”Marco”)) {
alert (“Non sei Marco”);
}
• viene esaminata l’espressione di sinistra (Questo significa che anche tutte le operazioni
previste dall’espressione di sinistra sono eseguite prima)
• se l’operatore è binario (“and” e “or” ad esempio) si passa ad esaminare l’espressione di
destra.
Nota: Se l’espressione di sinistra è sufficiente a determinare il risultato dell’operazione,
quella di destra viene ignorata.
Ad esempio: se l’operando è un or (||) e l’espressione di sinistra genera un true, non è
necessario valutare anche l’espressione destra, perché il risultato sarà comunque true, se
abbiamo un and (&&) invece, sarà ignorata l’espressione destra se a sinistra abbiamo già un
false.
• viene restituito il risultato
Avrete notato che la rappresentazione grafica di un operatore logico prevede il raddoppiamento del
simbolo corrispondente (es: &&). Nel caso in cui vi dimentichiate di raddoppiare il simbolo (es: &),
state in realtà utilizzando un operatore a livello di bit: il che non è scorretto, ma non sempre darà
luogo allo stesso risultato.
Uso del “not” e operatori di bit
Una menzione particolare la merita l’operatore di negazione(indicato con !), che serve a negare
un’espressione. Si tratta di un operatore unario: viene infatti posto di fronte all’espressione da
negare, senza essere confrontato con nient’altro.
Utilizzando l’operatore di diversità nel giusto modo possiamo scrivere:
• se la condizione è falsa…
• fai questo
La sintassi è la seguente:
if ( ! (espressione) ) {
//istruzioni
}
che significa:
• se nego l’espressione e così facendo ho un risultato vero…
• allora fai questo
Ad esempio:
x = 7;
if (! (x == 7) ) {
alert (“x non è 7″);
}
Ovviamente l’esempio che abbiamo appena esaminato non è di particolare utilità e in questo caso
non c’è una grossa differenza rispetto all’utilizzo dell’operatore di diversità (!=) che abbiamo visto
nelle lezioni precedenti:
x = 7;
if (x! = 7) {
alert (“x non è 7″);
}
Ma se teniamo conto che possiamo utilizzare gli operatori logici per creare situazioni molto
complesse, combinando fra loro le varie espressioni, allora appare evidente come l’utilizzo del not
sia particolarmente utile. Ad esempio:
nome=”Gianni”;
if ( ! ( (nome == “Gianni”) || (nome == “Marco”) ) ) {
alert (“Non sei né Gianni, né Marco”);
}
Nota a margine
Abbiamo accennato nella lezione precedente agli “operatori a livello di bit”. Nella programmazione
JavaScript non li userete quasi mai, ma è bene sapere che esistono. Perché se per errore scrivete:
(x >= 5) & (x <= 7)
in realtà state utilizzando un operatore a livello di bit e non un operatore logico.
La differenza sta nel fatto che gli operatore di bit convertono tutte le espressioni in valori binari,
prima di eseguire i confronti, e poi li confrontano bit a bit. Dal momento che – a volte – ciò
comporta delle approssimazioni, la valutazione delle espressioni può non dare adito allo stesso
risultato rispetto agli operatori logici.
Operatore
Spiegazione
Esempio
x=6;
&
“and a livello di bit”
if ( (x>=5) & (x<=7) ) {
alert (“x è compresa tra 5 e 7″);
}
nome=”Gianni”;
|
“or a livello di bit”
if ( (nome==”Gianni”) |
(nome==”Marco”) ) {
alert (“Sei Gianni oppure
Marco”);
}
nome=”Gianni”;
^
~
if ( (nome==”Gianni”) ^
“or esclusivo a livello (nome==”Marco”) ) {
di bit”
alert (“Sei Gianni oppure
Marco”);
}
“not a livello di bit”
x=7;
if (~ (x==7) ) {
alert (“x non è 7”);
}
Vediamo un esempio in cui operatori logici e operatori a livello di bit danno adito a risultati
differenti. Nell’esempio seguente l’operatore logico restituisce un risultato corretto:
if ( (document.all) && (navigator.platform.indexOf(“Win”)>-1) ) {
alert (“Stai usando Internet Explorer su Windows”);
} else {
alert (“Stai usando Internet Explorer su Mac”);
}
/* L’oggetto navigator.platform contiene le indicazioni sul
sistema operativo che l’utente sta usando. Nel caso di
Windows: alert(navigator.platform); restituisce “Win32″
indexOf serve per cercare del testo in una stringa: se
non lo trova restituisce “-1″, ecco perché abbiamo chiesto
di verificare che il risultato di indexOf sia maggiore
di -1. In pratica così facendo abbiamo chiesto di verificare
che navigator.platform contenga “Win”.
*/
Utilizzando l’operatore a livello di bit invece il risultato dello script non è corretto:
if ( (document.all) & (navigator.platform.indexOf(“Win”)!=-1) ) {
alert (“Stai usando Internet Explorer su Windows”);
} else {
alert (“Stai usando Internet Explorer su Mac”);
}