Cos'è JavaScript
JavaScript è il linguaggio del web. È nato nel 1995 per far muovere qualcosa nelle pagine HTML e oggi sta dappertutto: frontend, backend con Node.js, app per telefono, applicazioni desktop, perfino modelli di machine learning nel browser. Insieme a HTML e CSS è il terzo pezzo con cui è fatto tutto quello che apri in un browser.
Punti chiave
- JavaScript è l'unico linguaggio che gira nativamente in ogni browser e rende le pagine dinamiche e interattive.
- Le variabili si dichiarano con const per impostazione predefinita e con let quando devono cambiare; var lascialo ai siti vecchi.
- Con la manipolazione del DOM e la gestione degli eventi la pagina reagisce a quello che fa la persona, mentre lo fa.
- I metodi degli array (
map,filter,reduce) trasformano i dati in modo dichiarativo e leggibile. async/awaite la Fetch API rendono semplice lavorare con dati remoti e operazioni asincrone.
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. Conoscere bene i suoi fondamenti è oggi una competenza trasversale: serve per costruire siti, automatizzare attività di marketing, integrare strumenti di AI e leggere dati da servizi esterni.
"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 pezzi di codice che chiami quando ti servono. JavaScript ne offre tre sintassi, e in giro le trovi tutte e tre:
// 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. Nel lavoro quotidiano questo significa poter scrivere automazioni leggibili: per esempio elaborare una lista di contatti, calcolare metriche di marketing o preparare i dati da inviare a un servizio di AI. Scrivere funzioni piccole e con un solo compito (single responsibility) rende il codice più facile da testare e da riutilizzare in progetti diversi.
Manipolazione del DOM
Il DOM (Document Object Model) è la pagina HTML vista come un albero di oggetti che JavaScript può leggere e cambiare mentre la pagina è aperta. È il punto in cui il codice smette di essere teoria: cambi una riga e vedi muoversi qualcosa sullo schermo.
// 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);
}
});
La delega degli eventi è la tecnica che conviene imparare subito: invece di mettere un ascoltatore su ogni elemento figlio, lo metti sul genitore e filtri con e.target. Consuma meno e continua a funzionare sugli elementi aggiunti dopo, che è il caso in cui il codice ingenuo si rompe.
Array methods
I metodi degli array sono la parte di JavaScript che ti fa scrivere meno codice: trasformano, filtrano e riducono una lista dicendo cosa vuoi ottenere invece di come ciclare.
| 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 esegue una cosa per volta, e nonostante questo gestisce richieste di rete, timer e letture di file senza bloccarsi: il merito è dell'event loop. Le Promise sono il modo di dire «questo risultato arriverà, quando arriva fai così».
// 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+
Da ES6 (2015) il linguaggio riceve aggiornamenti ogni anno, e la differenza con il JavaScript di dieci anni fa è enorme:
- 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.
Queste funzionalità riducono il codice da scrivere, prevengono interi gruppi di errori (come l'accesso a proprietà inesistenti grazie all'optional chaining) e rendono il codice più sicuro e manutenibile. Imparare a usarle è il primo passo per leggere e adattare gli esempi che si trovano nella documentazione, negli snippet condivisi online e nelle risposte generate dagli assistenti AI.
Un consiglio su come studiarlo: le basi qui sopra si leggono in un'ora e si imparano in un mese, scrivendo cose piccole che funzionano. Prendi una pagina che hai già fatto e aggiungici una cosa per volta, un pulsante che apre un pannello, un form che valida i campi, una chiamata che legge dei dati. E metti sotto Git anche gli esercizi: quando romperai qualcosa senza capire come, tornare indietro sarà l'unica cosa che ti salva.
Vuoi imparare ad applicarlo davvero?
Scopri i corsi e la formazione di Federico Boggia su AI, dati e digitale.