JavaScript — Basi & Variabili

Inserimento in HTML · var · let · const · tipi di dato · typeof · 2026 · Marco Consiglio
Volta Institute · Napoli
A.A. 2026
🔌 Tre modi per inserire JavaScript in una pagina HTML
JavaScript può entrare in una pagina HTML in tre posizioni diverse: inline (dentro un tag HTML), interno (dentro un tag <script> nel file HTML) ed esterno (in un file .js separato, collegato con <script src="">).
① JavaScript Inline — direttamente nell'attributo HTML
<!-- JS inline: dentro l'attributo di un tag --> <button onclick="alert('Ciao da Volta!')">Cliccami</button> <a href="#" onclick="console.log('link cliccato')">Link</a>
⚠️ Inline è sconsigliato per qualsiasi cosa oltre al test rapido: mescola struttura (HTML) e comportamento (JS), rende il codice difficile da manutenere e viola la separazione delle responsabilità.
② JavaScript Interno — tag <script> nel file HTML
<!DOCTYPE html> <html lang="it"> <head> <meta charset="UTF-8"> <title>Pagina</title> </head> <body> <h1>Titolo</h1> <!-- script PRIMA della chiusura </body> --> <script> const nome = "Marco"; console.log("Ciao, " + nome); </script> </body> </html>
③ JavaScript Esterno — file .js separato (metodo consigliato)
<!-- Nel file HTML: collega il file esterno --> <script src="script.js" defer></script> <!-- nella <head> con defer --> /* Nel file script.js — separato dall'HTML */ const titolo = document.querySelector('h1'); titolo.textContent = "Pagina caricata con JS esterno";
📍 Dove posizionare il tag <script> — e perché conta
La posizione del tag <script> influenza quando il JS viene eseguito rispetto al caricamento dell'HTML.
PosizioneComportamentoQuando usare
<head> senza attributi❌ Blocca il parsing HTML. Il DOM non è ancora prontoMai — evitare
<head defer>✅ Scarica in parallelo, esegue dopo il DOM. Mantiene l'ordineScript che dipendono dal DOM — metodo consigliato
<head async>⚠️ Scarica in parallelo, esegue appena pronto (ordine non garantito)Script indipendenti: analytics, ads
Prima di </body>✅ DOM già pronto quando esegue. Nessun attributo necessarioCompatibilità con browser vecchi
<head> <!-- defer: scarica subito, esegue dopo che il DOM è pronto --> <script src="app.js" defer></script> <!-- async: per script indipendenti come Google Analytics --> <script src="analytics.js" async></script> </head>
✅ Regola d'oro 2026: metti sempre i file .js nella <head> con l'attributo defer. È più pulito del metodo "prima di " e garantisce che il DOM sia pronto senza bloccare il parsing.
🖥️ La Console del browser — il tuo primo strumento
La console è lo strumento principale per testare e debuggare JavaScript. Si apre con F12 → scheda "Console" in qualsiasi browser.
console.log("Messaggio normale"); // output standard console.warn("Attenzione!"); // warning in giallo console.error("Errore critico"); // errore in rosso console.log(42, true, [1,2,3]); // più valori console.table([{nome:"Marco", eta:30}]); // tabella
›Messaggio normale
›⚠ Attenzione!
›✖ Errore critico
›42 true [1, 2, 3]
📦 Dichiarazione di variabili — var, let, const
In JavaScript esistono tre parole chiave per dichiarare variabili. Ognuna ha regole diverse su scope (visibilità), hoisting (sollevamento) e riassegnazione.
// ─── CONST: valore non riassegnabile (usa questa per default) ─── const nome = "Marco"; const eta = 30; const PI = 3.14159; // nome = "Luca"; ← ERRORE: const non può essere riassegnata // ─── LET: valore modificabile, scope a blocco ─── let contatore = 0; contatore = 1; // ✅ riassegnazione permessa contatore++; // ✅ incremento // ─── VAR: vecchia sintassi, evitare nel 2026 ─── var vecchio = "non usare più"; // var ha scope di funzione (non di blocco) e hoisting: problemi!
KeywordScopeRiassegnabileHoistingUsare?
constBlocco { }❌ NoNo (TDZ)✅ Sempre, per default
letBlocco { }✅ SìNo (TDZ)✅ Quando il valore cambia
varFunzione✅ Sì✅ Sì (bug)❌ Mai in codice moderno
✅ Regola pratica 2026: usa sempre const di default. Passa a let solo quando sai che il valore cambierà (cicli, contatori, accumulatori). Non usare mai var.
🔭 Scope — dove vive una variabile
Lo scope definisce in quale parte del codice una variabile è accessibile. let e const hanno scope a blocco (dentro le { } dove sono dichiarate). var ha scope di funzione — comportamento spesso controintuitivo.
// scope a BLOCCO con let/const if (true) { const dentro = "solo qui"; let anche = "solo qui"; console.log(dentro); // ✅ "solo qui" } // console.log(dentro); ← ReferenceError: dentro non esiste fuori // scope di FUNZIONE con var (comportamento sorprendente!) if (true) { var fuori = "mi vedono tutti!"; } console.log(fuori); // ✅ funziona — ma è un problema di design // scope GLOBALE: dichiarata fuori da qualsiasi blocco const globale = "visibile ovunque"; function miaFunzione() { console.log(globale); // ✅ accessibile }
⬆️ Hoisting — le variabili "sollevate"
L'hoisting è il comportamento di JavaScript che "solleva" le dichiarazioni in cima allo scope prima dell'esecuzione. var viene hoistata (con valore undefined). let e const entrano nella Temporal Dead Zone (TDZ) — esistono ma non sono accessibili prima della dichiarazione.
// var: hoistata con valore undefined console.log(x); // undefined (non errore!) var x = 5; console.log(x); // 5 // let/const: TDZ — errore se usate prima della dichiarazione // console.log(y); ← ReferenceError: Cannot access 'y' before init let y = 10; console.log(y); // 10 // Le funzioni dichiarate con function sono hoistate complete: saluta(); // ✅ funziona prima della dichiarazione! function saluta() { console.log("Ciao!"); }
💡 Mnemonica: TDZ = "zona morta temporale". Con let e const è come una stanza chiusa a chiave — la variabile esiste ma non ci puoi entrare prima di averla dichiarata.
🔢 I 7 tipi primitivi di JavaScript
JavaScript ha 7 tipi primitivi (valori semplici, non oggetti) e il tipo Object (che include array, funzioni, Date, ecc.).
// 1. STRING — testo const nome = "Marco"; // doppi apici const citta = 'Napoli'; // apici singoli (equivalente) const frase = `Ciao, ${nome}!`; // template literal (backtick) // 2. NUMBER — numeri interi e decimali (un solo tipo) const intero = 42; const decimale = 3.14; const negativo = -7; const infinito = Infinity; // 1/0 const nonNumero = NaN; // "testo" * 2 // 3. BOOLEAN — true o false const attivo = true; const loggato = false; // 4. UNDEFINED — variabile dichiarata ma senza valore let nondefinita; console.log(nondefinita); // undefined // 5. NULL — assenza intenzionale di valore const utente = null; // "nessun utente" (scelta del developer) // 6. BIGINT — interi molto grandi const grande = 9007199254740991n; // la n finale indica BigInt // 7. SYMBOL — identificatore unico (avanzato) const id = Symbol("id"); // ogni Symbol è unico
📊 Tipo Object — array, funzioni, oggetti letterali
Tutto ciò che non è un tipo primitivo è un Object in JavaScript. Array, funzioni, Date, Map, Set — sono tutti oggetti.
// OBJECT LETTERALE — coppia chiave:valore const studente = { nome: "Giulia", eta: 22, attiva: true }; console.log(studente.nome); // "Giulia" (notazione punto) console.log(studente["eta"]); // 22 (notazione parentesi) // ARRAY — lista ordinata const voti = [28, 30, 25, 29]; console.log(voti[0]); // 28 (indice parte da 0) console.log(voti.length); // 4 // FUNCTION — è un oggetto di tipo Function function somma(a, b) { return a + b; } console.log(somma(3, 4)); // 7 // NULL è primitivo ma typeof dice "object" — bug storico di JS console.log(typeof null); // "object" ← bug noto, non corretto
⚠️ Bug storico: typeof null restituisce "object" invece di "null". È un errore della prima versione di JavaScript rimasto per compatibilità. Per verificare se un valore è null, usa === null (non typeof).
🎯 Valori Falsy e Truthy
In JavaScript ogni valore può essere usato in un contesto booleano (come in un if). I valori falsy vengono trattati come false, tutti gli altri come true.
Falsy — si comportano come falseTruthy — si comportano come true
falseQualsiasi stringa non vuota: "ciao", "0", " "
0 e -0Qualsiasi numero diverso da 0: 1, -1, 0.5
"" (stringa vuota)Array (anche vuoto): []
nullOggetto (anche vuoto): {}
undefinedInfinity
NaNQualsiasi funzione
if ("") console.log("A"); // non stampa — "" è falsy if ("0") console.log("B"); // stampa "B" — "0" è truthy (stringa non vuota!) if (0) console.log("C"); // non stampa — 0 è falsy if ([]) console.log("D"); // stampa "D" — array vuoto è truthy!
💡 Mnemonica falsy: sono solo 6 — false, 0, "", null, undefined, NaN. Tutto il resto è truthy. L'errore più comune: "0" è truthy (è una stringa), mentre 0 è falsy (è un numero).
🔍 typeof — riconoscere il tipo a runtime
L'operatore typeof restituisce una stringa con il tipo del valore. Utile per validare input e debuggare.
console.log(typeof "Marco"); // "string" console.log(typeof 42); // "number" console.log(typeof 3.14); // "number" (stesso tipo!) console.log(typeof true); // "boolean" console.log(typeof undefined); // "undefined" console.log(typeof null); // "object" ← bug storico! console.log(typeof {}); // "object" console.log(typeof []); // "object" ← array è oggetto console.log(typeof function(){}); // "function" console.log(typeof 42n); // "bigint" console.log(typeof Symbol()); // "symbol"
💡 Per distinguere un array da un oggetto comune usa Array.isArray(valore) — typeof [] restituisce "object" per entrambi.
🔄 Type coercion — conversioni implicite ed esplicite
JavaScript converte automaticamente i tipi in alcune situazioni (coercion implicita). Questo può creare comportamenti sorprendenti. La conversione esplicita è sempre preferibile.
// ── COERCION IMPLICITA (automatica — attenzione!) ── console.log("5" + 3); // "53" — + con stringa fa concatenazione console.log("5" - 3); // 2 — - converte la stringa in numero console.log("5" * 2); // 10 — * converte la stringa console.log(true + 1); // 2 — true vale 1 console.log(false + 1); // 1 — false vale 0 // ── CONVERSIONE ESPLICITA (sempre preferibile) ── console.log(Number("42")); // 42 string → number console.log(Number("abc")); // NaN non convertibile console.log(Number(true)); // 1 console.log(Number(false)); // 0 console.log(String(42)); // "42" number → string console.log(Boolean(0)); // false falsy → false console.log(Boolean("ciao")); // true truthy → true console.log(parseInt("42px")); // 42 estrae numero da stringa console.log(parseFloat("3.14m")); // 3.14
⚖️ Uguaglianza: == vs === (sempre usa ===)
// == (uguaglianza debole) — converte i tipi prima di confrontare console.log(5 == "5"); // true ← pericoloso! console.log(0 == false); // true ← pericoloso! console.log(null == undefined); // true! // === (uguaglianza stretta) — confronta valore E tipo console.log(5 === "5"); // false ← corretto console.log(0 === false); // false ← corretto console.log(5 === 5); // true ✅
⚠️ Regola assoluta: usa sempre === (triplo uguale). L'unica eccezione comune è value == null che verifica sia null che undefined in una sola condizione — ma solo se lo fai consapevolmente.
✏️ Metodi fondamentali delle stringhe
Le stringhe in JavaScript sono immutabili (non si modificano sul posto) ma hanno decine di metodi che restituiscono nuove stringhe. I più usati:
const s = " Volta Institute Napoli "; // lunghezza console.log(s.length); // 26 // rimozione spazi console.log(s.trim()); // "Volta Institute Napoli" // maiuscole / minuscole console.log(s.toUpperCase()); // " VOLTA INSTITUTE NAPOLI " console.log(s.toLowerCase()); // " volta institute napoli " // ricerca console.log(s.includes("Napoli")); // true console.log(s.indexOf("Volta")); // 2 console.log(s.startsWith(" V")); // true console.log(s.endsWith(" ")); // true // estrazione console.log(s.slice(2, 7)); // "Volta" console.log(s.slice(-6)); // "oli " (da destra) // sostituzione console.log(s.replace("Napoli", "Roma")); // " Volta Institute Roma " // divisione in array const parole = s.trim().split(" "); console.log(parole); // ["Volta", "Institute", "Napoli"]
🧩 Template Literals — stringhe dinamiche con backtick
I template literal (con il backtick `) permettono di inserire variabili ed espressioni dentro una stringa con la sintassi ${espressione}, e di scrivere stringhe multiriga.
const nome = "Marco"; const corso = "Web Design"; const voto = 28; // vecchio metodo — concatenazione con + const msg1 = "Ciao " + nome + ", hai preso " + voto + " in " + corso; // template literal — molto più leggibile const msg2 = `Ciao ${nome}, hai preso ${voto} in ${corso}`; // espressioni calcolate dentro ${ } console.log(`Il doppio del voto è ${voto * 2}`); // 56 console.log(`Promosso: ${voto >= 18 ? "Sì" : "No"}`); // multiriga — nessun \n necessario const html = ` <div class="card"> <h2>${nome}</h2> <p>Corso: ${corso}</p> </div> `;
✅ Usa sempre i template literal per stringhe che contengono variabili. Sono più leggibili, evitano errori di concatenazione e supportano espressioni arbitrarie dentro ${ }.
🧪 Playground — esegui codice JavaScript direttamente qui
Scrivi codice JavaScript nell'area sotto e clicca Esegui. L'output di console.log() apparirà nel riquadro in basso.
▸ Editor JS
// l'output appare qui...
💡 Snippet da testare nel playground
Copia questi esempi nell'editor sopra e studia i risultati:
// ── Test 1: coercion implicita ── console.log("5" + 3); // "53" o 8? console.log("5" - 3); // "53" o 2? // ── Test 2: falsy ── console.log(Boolean("")); // false console.log(Boolean("0")); // true (stringa!) console.log(Boolean([])); // true (array) // ── Test 3: === vs == ── console.log(0 == false); // true console.log(0 === false); // false // ── Test 4: template literal ── const x = 10; console.log(`x al quadrato: ${x ** 2}`);