Cos'è JavaScript
JavaScript è il linguaggio di programmazione del web. Nato nel 1995 per aggiungere interattività alle pagine HTML, oggi è utilizzato ovunque: frontend, backend (Node.js), app mobile, desktop e persino machine learning. Insieme a HTML e CSS, forma la triade fondamentale dello sviluppo web.
JavaScript è un linguaggio interpretato, dinamicamente tipizzato e multi-paradigma: supporta programmazione imperativa, funzionale e orientata agli oggetti. La specifica ufficiale si chiama ECMAScript e viene aggiornata annualmente.
"Qualsiasi applicazione che può essere scritta in JavaScript, alla fine verrà scritta in JavaScript." — Jeff Atwood (Legge di Atwood)
Variabili e tipi di dato
In JavaScript moderno si dichiarano le variabili con let e const. La keyword var è ormai sconsigliata per via del suo scope funzionale e dell'hoisting imprevedibile.
const PI = 3.14159; // costante, non riassegnabile
let contatore = 0; // variabile, riassegnabile
contatore = contatore + 1;
// Tipi primitivi
const stringa = "Ciao mondo"; // String
const numero = 42; // Number
const decimale = 3.14; // Number (no int/float separati)
const booleano = true; // Boolean
const nullo = null; // Null
const indefinito = undefined; // Undefined
const simbolo = Symbol("id"); // Symbol
const grande = 9007199254740991n; // BigInt
const come scelta predefinita. Passa a let solo quando sai che il valore dovrà cambiare. Questo rende il codice più prevedibile e riduce i bug.
Funzioni
Le funzioni sono blocchi di codice riutilizzabili. JavaScript offre diverse sintassi per dichiararle:
// Function declaration (hoisted)
function somma(a, b) {
return a + b;
}
// Function expression
const moltiplica = function(a, b) {
return a * b;
};
// Arrow function (ES6+)
const dividi = (a, b) => a / b;
// Parametri di default
const saluta = (nome = "Visitatore") => `Ciao, ${nome}!`;
// Destructuring nei parametri
const mostraUtente = ({ nome, email }) => {
console.log(`${nome} - ${email}`);
};
Le arrow function hanno una sintassi più compatta e non creano un proprio this, rendendole ideali come callback e per la programmazione funzionale.
Manipolazione del DOM
Il DOM (Document Object Model) è la rappresentazione ad albero della pagina HTML che JavaScript può leggere e modificare in tempo reale.
// Selezionare elementi
const titolo = document.querySelector("h1");
const cards = document.querySelectorAll(".card");
const menu = document.getElementById("menu");
// Modificare contenuto e stili
titolo.textContent = "Nuovo titolo";
titolo.style.color = "#2563eb";
titolo.classList.add("evidenziato");
// Creare e inserire elementi
const paragrafo = document.createElement("p");
paragrafo.textContent = "Paragrafo aggiunto dinamicamente";
document.querySelector("main").appendChild(paragrafo);
Il metodo querySelector accetta qualsiasi selettore CSS valido, rendendolo estremamente flessibile. Per manipolazioni massive del DOM, è consigliabile usare un DocumentFragment per ridurre i reflow del browser.
Gestione degli eventi
Gli eventi permettono a JavaScript di reagire alle azioni dell'utente: click, scroll, input, submit e molti altri.
// addEventListener (metodo raccomandato)
const bottone = document.querySelector("#invia");
bottone.addEventListener("click", (event) => {
event.preventDefault();
console.log("Bottone cliccato!");
});
// Eventi comuni: click, submit, input, keydown, scroll, load
// Event delegation (gestire eventi su elementi dinamici)
document.querySelector(".lista").addEventListener("click", (e) => {
if (e.target.matches(".item")) {
console.log("Item cliccato:", e.target.textContent);
}
});
L'event delegation è una tecnica fondamentale: invece di assegnare un listener a ogni elemento figlio, si ascolta l'evento sul genitore e si filtra con e.target. Questo migliora le prestazioni e funziona anche con elementi aggiunti dinamicamente.
Array methods
I metodi degli array sono tra gli strumenti più potenti di JavaScript. Permettono di trasformare, filtrare e ridurre collezioni di dati in modo dichiarativo.
| Metodo | Scopo | Restituisce |
|---|---|---|
.map() | Trasforma ogni elemento | Nuovo array |
.filter() | Filtra per condizione | Nuovo array |
.reduce() | Riduce a un singolo valore | Valore singolo |
.find() | Trova il primo match | Elemento o undefined |
.some() | Almeno uno soddisfa? | Boolean |
.every() | Tutti soddisfano? | Boolean |
.forEach() | Itera senza restituire | undefined |
const prodotti = [
{ nome: "Laptop", prezzo: 999 },
{ nome: "Mouse", prezzo: 29 },
{ nome: "Monitor", prezzo: 449 }
];
const costosi = prodotti
.filter(p => p.prezzo > 100)
.map(p => p.nome);
// ["Laptop", "Monitor"]
const totale = prodotti.reduce((acc, p) => acc + p.prezzo, 0);
// 1477
Async/Await e Promises
JavaScript è single-threaded ma gestisce operazioni asincrone (richieste di rete, timer, lettura file) grazie all'event loop. Le Promise rappresentano il risultato futuro di un'operazione asincrona.
// Promise
const caricaDati = () => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Dati caricati!"), 1000);
});
};
// Async/Await (sintassi moderna e leggibile)
async function inizializza() {
try {
const risultato = await caricaDati();
console.log(risultato);
} catch (errore) {
console.error("Errore:", errore.message);
}
}
async/await è zucchero sintattico sulle Promise: rende il codice asincrono leggibile come se fosse sincrono, senza i callback annidati (il cosiddetto callback hell).
Fetch API
La Fetch API è l'interfaccia nativa per effettuare richieste HTTP dal browser, sostituendo il vecchio XMLHttpRequest.
// GET request
async function getUtenti() {
const response = await fetch("https://api.esempio.it/utenti");
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const dati = await response.json();
return dati;
}
// POST request
async function creaUtente(utente) {
const response = await fetch("https://api.esempio.it/utenti", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(utente)
});
return response.json();
}
Per approfondire il funzionamento delle API lato server e i diversi paradigmi (REST, GraphQL), consulta la guida su API e Web Services.
Novità ES6+
A partire da ES6 (2015), JavaScript ha ricevuto aggiornamenti annuali che hanno modernizzato profondamente il linguaggio:
- Template literals:
`Ciao ${nome}`— stringhe interpolate con backtick. - Destructuring:
const { nome, email } = utente;— estrazione di valori da oggetti e array. - Spread/Rest:
const nuovo = { ...vecchio, campo: "valore" };— copia e merge di oggetti. - Optional chaining:
utente?.indirizzo?.citta— accesso sicuro a proprietà annidate. - Nullish coalescing:
const val = input ?? "default";— fallback solo per null/undefined. - Moduli:
import/export— organizzazione del codice in file separati.
Per gestire il codice JavaScript in modo professionale e collaborativo, è fondamentale padroneggiare Git e il version control.