Lezione 1
Filippo Matteo Riggio
CTO @ Kaleidoscope Srl
Full Stack Developer
JavaScript è uno dei linguaggi di programmazione più popolari al mondo.
E' ormai lo standard de-facto per moltissime applicazioni, dal mobile, al web, passando per l'IOT.
E' un linguaggio di scripting orientato agli oggetti.
Standardizzato dalla ECMA per la prima volta nel 1997, lo troverete anche sotto forma di ECMAscript.
Quando sentite parlare di ECMAscript, stiamo comunque parlare di JavaScript.
Il nome JavaScript deriva dalla similitudine del linguaggio con Java.
Un'altra potenzialità è quella di poter essere eseguito sia lato server (con Node.JS), sia lato client.
JavaScript è un linguaggio:
Il primo strumento di lavoro è ovviamente il browser; il più utilizzato per lo sviluppo JS è Chrome; in particolare lo strumento denominato DevTools.
Il secondo strumento di lavoro è l'editor Visual Studio Code (o WebStorm).
Il terzo strumento sarà il Terminale, dove potere eseguire i comandi per installare i pacchetti di NodeJS e tante altre operazioni.
Come detto prima, JS può essere eseguito lato server, tramite Node.JS.
Node è una runtime derivata dal motore V8 di Google, che funge da Web Server.
Di solito viene usato in abbinata con MongoDB / Express / Angular, andando a creare lo stack MEAN.
NPM è il Node Package Manager, un registro con tutti i pacchetti disponibili per JavaScript.
Pacchetti utili sia lato server, sia lato client.
JavaScript viene aggiornato ogni anno con nuove funzionalità del linguaggio.
C'è però un problema di compatibilità tra le versioni nuove del linguaggio, supportate dai browser più moderni, ma non dai browser più datati.
Vengono in aiuto i transpiler.
I transpiler sono dei compilatori/traduttori, che prendono le istruzioni in versione ES6/ES7/ES8/ES9 (indiecato anche come ES6+) e le converte in ES5.
ES5 è supportato da Internet Explorer 10 e precedenti.
I transpiler più comuni sono:
Babel, prima noto come 6to5, è un pacchetto di NPM che prende tutto il codice ES6+ e lo converte in ES5.
TypeScript è un linguaggio creato da Microsoft, che potenzia JavaScript attraverso l'implementazione della tipizzazione.
Quindi oltre ad avere il supporto a tutte le istruzioni e funzioni di ES6+, permette il supporto ai tipi di variabili, per poi compilare tutto in ES5.
JavaScript lato client, viene eseguito sul browser.
Per poterlo eseguire, prima va inserito un riferimento in una pagina HTML.
// index.html
<html>
<head>
<title>Esempio esecuzione JavaScript</title>
</head>
<body>
<h1>La nostra pagina</h1>
<script src="./js/main.js"></script>
</body>
</html>
JavaScript è composto da una sequenza di istruzioni.
Ogni istruzione è delimitata dal ;
Il linguaggio è case sensitive, quindi c'è differenza tra minuscole e maiuscole.
I commenti possono essere su una sola riga, con l'uso del doppio slash (//), oppure su più righe, delimitate da ( /* ... */ ).
var x = 5 // !!! SBAGLIATO !!!
var x = 5; // !!! CORRETTO !!!
var A = 10;
var a = 5; // A ed a sono due variabili diverse !!!
// COMMENTO SU UNA RIGA
/*
COMMENTO
SU PIU'
RIGHE
*/
La dichiarazione di variabili in JavaScript, si esegue in 2 modi.
// ES5
var x = 5;
// ES6+
let a = 10;
for ( var i = 0; i < 10; i++ ) {
console.log(i); // 0,1,2...9
}
console.log(i); // 10
for ( let i = 0; i < 10; i++ ) {
console.log(i); // 0,1,2...9
}
console.log(i); // Uncaught Reference Error: i is not defined
La differenza tra var e let, è la differenza di contesto (leggasi gruppo di istruzioni raggruppate).
Una variabile dichiarata con let all'interno delle parentesi non è accessibile all'esterno del contesto.
La dichiarazione di costanti in JavaScript è possibile solo da ES6+.
// ES6+
const a = 10;
a = 5; // ERRORE !!! NON SI PUO' RIASSEGNARE IL VALORE DI UNA COSTANTE
La dichiarazione delle stringhe si può fare attraverso gli apici o i doppi apici.
let testo = 'Questo è una stringa';
let altro = "Anche questa è una stringa";
L'uso del singolo apice è previsto all'interno dei doppi apici, oppure attraverso l'escaping.
let testo = "Testo con l'apice.";
let testo = 'Testo con l\'apice';
E' possibile l'uso dei caratteri speciali dentro le stringhe con i doppi apici.
let testo = "Testo che va \n a capo.";
let altro = "Testo con un \t TAB.";
La dichiarazione dei numeri avviene come segue:
let interoNegativo = -10;
let zero = 0;
let interoPositivo = 123;
let numeroDecimale = 0.52;
let altroNumeroDecimale = 12.34;
let decimaleNegativo = -1.2;
let decimaleZero = 1.0;
let primoNumero = 12e3; // equivalente a 12 x 10 alla terza cioè 12.000
let secondoNumero = 3.5e-4; // equivalente a 3.5 x 10 alla -4 cioè 0,00035
let numeroOttale = 0123; //equivalente a 83
let numeroEsadecimale = 0x123; //equivalente a 291
I numeri rappresentabili sono racchiusi nell'insieme:
-1.79769*10308 e 1.79769*10308
I numeri fuori dall'intervallo vengono rappresentati dal valore -Infinity o Infinity.
Un altro valore speciale è NaN (Not a Number), che indica un valore numerico non definitivo.
Il tipo di dato null prevede il solo valore null, che rappresenta un valore che non rientra tra i tipi di dato del linguaggio, cioè non è un valore numerico valido, né una stringa, né un oggetto.
Il tipo di dato undefined rappresenta un valore che non esiste. Anche questo tipo di dato contiene un solo valore: undefined.
Questo è il valore di una variabile non inizializzata, a cui non è stato assegnato nessun valore, nemmeno null.
Il tipo di dato booleano prevede due soli valori: true o false.
let myVar; // myVar è di tipo "undefined"
myVar = 1;
myVar = null;
myVar = true;
Gli array permettono di associare più valori ad una sola variabile.
let frutta = [
"mela",
"pera",
"banana"
];
let pera = frutta[1];
let generico = [ 123, "test", 0.34 ];
let [ frutto1,,frutto3 ] = frutta; // DESTRUTTURAZIONE DELL'ARRAY
Gli oggetti sono simili agli array, ma usano una chiave per la definizione degli indici.
let persona = {
nome: 'Filippo Matteo',
cognome: 'Riggio',
eta: 30
};
Il nome di una variabile:
non deve coincidere con una delle parole chiave del linguaggio
non può iniziare con un numero
non può contenere caratteri speciali come ad esempio: spazio, trattino, punto interrogativo, punto, ecc.
sono ammessi: il dollaro e l'underscore ( $, _ )
Gli operatori aritmetici sono:
Valgono il resto delle espressioni aritmetiche come le conosciamo (precedenza sulle parentesi, ecc.)
Gli operatori relazionali sono:
Gli operatori logici sono:
Gli operatori di assegnazione sono:
Gli operatori di concatenazione stringhe sono:
Attraverso il costrutto if, oppure if...else, possiamo eseguire blocchi di istruzioni.
if ( eta == 30 ) {
alert('Hai 30 anni!');
}
if ( eta > 30 ) {
alert('Più di 30 anni!');
} else {
alert('Fino a 30 anni!');
}
if ( eta > 30 ) {
alert('Più di 30 anni!');
} else if ( eta > 15 && eta <= 30) {
alert('Da 15 a a 30 anni!');
} else {
alert('Sotto i 15 anni!');
}
Quando siamo di fronte a diverse alternative, anche un if a cascata può risultare difficile da leggere. In questi casi possiamo ricorrere all’istruzione switch.
switch ( nazione ) {
case 'italia':
alert('Italia!');
break;
case 'uk':
alert('United Kingdom!');
break;
}
JavaScript prevede le classiche istruzioni di iterazione come while e for.
let y = 1;
let i = 1;
while (i <= 4) {
y = y * i;
i++;
}
do {
y = y * i;
i++;
}
while (i <= 4)
Questa istruzione è generalmente intesa per l’esecuzione di un blocco di codice un numero determinato di volte.
// CICLO FOR STANDARD
let y = 1;
let i;
for (i = 1; i <=4; i++) {
y = y * i;
}
// CICLO FOR...IN
// Questa variante del for permette di non specificare la lunghezza dell’array,
// nè l’istruzione di modifica della condizione.
let quantita = [12, 34, 45, 7, 19];
let totale = 0;
let indice;
for (indice in quantita) {
totale = totale + quantita[indice];
}
// CICLO FOR...OF
// Ad ogni iterazione JavaScript assegna alla variabile valore il contenuto di ciascun elemento dell’array.
let quantita = [12, 34, 45, 7, 19];
let totale = 0;
let valore;
for (valore of quantita) {
totale = totale + valore;
}
Una funzione è un insieme di istruzioni racchiuse in un blocco di codice, che può essere contraddistinto da un nome, può accettare argomenti o parametri di ingresso e restituire valori
// DEFINIZIONE FUNZIONE SOMMA
function somma( addendoA, addendoB ) {
return addendoA + addendoB;
}
// INVOCAZIONE DI FUNZIONE
let totale = sommma( 5, 4 );
Una funzione è un insieme di istruzioni racchiuse in un blocco di codice, che può essere contraddistinto da un nome, può accettare argomenti o parametri di ingresso e restituire valori
let risultato1 = somma(11); // addendo1 = 11, addendo2 = undefined
let risultato2 = somma(); // addendo1 = undefined, addendo2 = undefined
let risultato3 = somma(11, 5, 7, 9); // addendo1 = 11, addendo2 = 5, 7 e 9 vengono ignorati
Possiamo non definire alcun argomento nella definizione di somma() ed accedere ai valori passati in fase di chiamata tramite un array speciale predefinito: arguments.
function somma() {
return arguments[0] + arguments[1];
}
// OPPURE
function somma() {
let z = 0;
let i;
for (i in arguments) {
z = z + arguments[i];
}
return z;
}
somma(2, 78);
somma(17, 32, 4, 19, 52);
Il parametro di tipo rest, è stato introdotto con ES6+.
Si tratta di una notazione speciale per indicare un elenco indefinito di argomenti aggiuntivi.
function eseguiOperazione(x, ...y) {
let z = 0;
switch (x) {
case "somma":
for (i in y) {
z = z + y[i];
}
break;
case "moltiplica":
for (i in y) {
z = z * y[i];
}
break;
case "dividi":
z = y[0]/y[1];
break;
default:
z = NaN;
break;
}
return z;
}
eseguiOperazione("somma", 12, 54, 2, 7, 12);
eseguiOperazione("moltiplica", 4, 11, 32);
eseguiOperazione("dividi", 45, 9, 6, 17);
// ES 5
var multiply = function(x, y) {
return x * y;
};
// ES 6
var multiply = (x, y) => { return x * y };
// Un caso con gli array
var missions = [
{ name: 'Mercury', flights: 6 },
{ name: 'Gemini', flights: 3 },
{ name: 'Apollo', flights: 11 },
{ name: 'ASTP', flights: 17 },
];
// ES 5
console.log(
missions.map( function(mission) {
return mission.flights;
});
); // [ 6, 3, 11, 17]
// ES 6
console.log(
missions.map(
mission => mission.flights
)
); // [ 6, 3, 11, 17]
ES6+ permette di scrivere le funzioni in un modo nuovo.
let persona = {
nome: "Mario",
cognome: "Rossi",
indirizzo: {
via: "Via Garibaldi",
numero: 15,
CAP: "00100",
citta: "Roma"
},
visualizzaNomeCognome: function() {
return this.nome + ' ' + this.cognome;
}
};
// ACCEDERE ALLE PROPRIETA'
let nome = persona.nome;
// ACCEDERE AI METODI
let nomeCognome = persona.visualizzaNomeCognome();
La parola chiave this permette di accedere al contesto dell'oggetto.
Attraverso il punto (.), possiamo accedere alle proprietà e ai metodi dell'oggetto.
class Rocket {
public landing(location) {
// [...]
}
}
class Falcon extends Rocket {
public constructor() {
super();
this.manufacturer = 'SpaceX';
this.stages = 2;
}
public landing(location) {
console.log('On land');
}
}
class Antares extends Rocket {
public constructor() {
super();
this.manufacturer = 'OrbitalATK';
this.stages = 2;
}
public landing(location) {
console.log('In the ocean');
}
}
ES6+ ha introdotto il concetto di classe e di ereditarietà.
1) Scrivi un programma che dati 5 numeri restituisca in output la somma e la media.
Esempio:
Input: a = 1, b = 2, c = 3, d = 4, e = 5
Output: somma = 15, media = 3
2) Scrivi un programma che dato l'anno corrente e un anno di nascita determini:
- l'età della persona,
- quanti anni sono necessari per raggiungere i 100
Esempio:
Input: anno corrente = 2019, anno di nascita = 1989
Ouput: età = 30, anni mancanti = 70
3) Scrivi un programma che dato un numero di secondi, calcoli la quantità di ore, minuti e secondi corrispondenti e poi stampi il risultato. L'output avrà solo numeri interi.
Esempio:
Input: 12560
Output: 3 ore, 29 minuti e 20 secondi.
4) Scrivi un programma che dato un numero N, generi un array di N numeri casuali e stampi sia l'array ottenuto che quello invertito.
Esempio:
Input: N = 5
Output: array ottenuto = [3, 5, 10, 2, 8], array invertito = [8, 2, 10, 5, 3]
5) Scrivi un programma che dato array di numeri, calcoli la media dei valori e restituisca in output la media e tutti i valori minori della media.
Esempio:
Input: a = [3, 5, 10, 2, 8]
Output: media = 5.6, valori minori = [3, 5, 2]
6) Scrivi un programma che dati:
- 2 array di 10 elementi interi casuali compresi tra 1 e 10,
- il tipo di operazione aritmetica da effettuare, una delle seguenti: addizione, sottrazione, moltiplicazione, divisione
Esegua il calcolo tra ogni elemento dei due array, salvando ciascun risultato in un terzo array di appoggio.
Esempio:
Input:
a = [3, 7, 2, 5, 8, 1, 2, 5, 6, 4],
b = [9, 3, 1, 4, 7, 6, 5, 10, 1, 5],
operazione = "addizione"
Output:
c = [12, 10, 3, 9, 15, 7, 7, 15, 7, 9]