JavaScript Real World Vademecum
JavaScript Cheat Sheet Completo
Una guida di riferimento rapido completa che contiene tutta la sintassi, i metodi e i pattern trattati nei capitoli precedenti.
| Categoria | Strumento/Concetto | Analogia/Scopo | Esempio/Sintassi |
|---|---|---|---|
| FONDAMENTI - VARIABILI | |||
let | La Lavagna: valore modificabile | let counter = 0;counter = 1; | |
const | La Cassaforte: riferimento immutabile | const USER_ID = 123;const user = {nome: 'Mario'}; user.nome = 'Luigi'; (OK) | |
var | Il Vecchio Modo (evitare!) | Ha function scope e hoisting problematico | |
null vs undefined | Vuoto intenzionale vs. Vuoto accidentale | let x = null; (scelto da te)let y; (il valore di y è undefined) | |
| FONDAMENTI - TIPI DI DATI | |||
| String | Testo con metodi | const s = "Ciao"; | |
| Template Literals (` ) | Stringhe con "buchi" per variabili | Ciao ${nome} Totale: ${prezzo * 1.22} \` | |
| Escape chars | Caratteri speciali | \n (a capo)`\t` (tab) `"` (virgoletta) `\` (backslash) | |
| `.split()` | Affettatrice di stringhe | `"a-b-c".split('-')` → `['a', 'b', 'c']` `"ciao".split('')` → `['c', 'i', 'a', 'o']` | |
| `.charCodeAt()` | Carattere → Numero (Vecchio) | `"A".charCodeAt(0)` → `65` (si rompe con emoji "🎉") | |
| `.codePointAt()` | Carattere → Numero (Moderno) | `"🎉".codePointAt(0)` → `127881` (corretto) | |
| `String.fromCharCode()` | Numero → Carattere (Vecchio) | `String.fromCharCode(65)` → `"A"` (non gestisce emoji) | |
| `String.fromCodePoint()` | Numero → Carattere (Moderno) | `String.fromCodePoint(127881)` → `"🎉"` | |
| `.startsWith()` | Controllo Inizio Stringa (Intento) | `file.startsWith("doc")` → `true` `"Ciao".startsWith("C")` → `true` | |
| Number | IEEE 754, interi e decimali | `const n = 3.14;` | |
| Valori Speciali | Non-numeri e infiniti | `Infinity`, `-Infinity` `NaN` (non è uguale a se stesso) | |
| `isNaN()` | Doganiere confuso: "È... NaN?" | `isNaN("ciao")` → `true` (converte prima) `isNaN(null)` → `false` (perché `Number(null)` è 0) | |
| `Number.isNaN()` | Doganiere rigoroso: "È già NaN?" | `Number.isNaN("ciao")` → `false` `Number.isNaN(NaN)` → `true` | |
| `Number()` | Conversione "tutto o niente" (rigorosa) | `Number("42px")` → `NaN` `Number("123")` → `123` | |
| `parseInt()` | Estrattore di interi (tollerante) | `parseInt("42.5px", 10)` → `42` `parseInt("1010", 2)` → `10` (binario) | |
| `parseFloat()` | Estrattore di decimali (tollerante) | `parseFloat("42.5px")` → `42.5`<br`parseFloat("3.14.15")` → `3.14` | |
| `Math` | Calcolatrice scientifica integrata | Oggetto statico, es. `Math.PI` | |
| `Math.floor()` | Arrotonda al pavimento | `Math.floor(4.9)` → `4` | |
| `Math.ceil()` | Arrotonda al soffitto | `Math.ceil(4.1)` → `5` `Math.ceil(0.1)` → `1` | |
| `Math.round()` | Arrotonda al più vicino | `Math.round(4.5)` → `5` `Math.round(4.4)` → `4` | |
| `Math.random()` | Generatore di casualità (0 - 0.99...) | `Math.random()` `Math.floor(Math.random() * 10) + 1` (da 1 a 10) | |
| `Math.pow()` vs `**` | Elevamento a potenza | `Math.pow(2, 3)` → `8` `2 ** 3` → `8` (moderno) | |
| `Math.sqrt()` | Radice quadrata (Leggibilità) | `Math.sqrt(9)` → `3` (meglio di `9 ** 0.5`) | |
| Problema (IEEE-754) | Calcoli decimali "sbagliati" | `0.1 + 0.2` → `0.30000000000000004` | |
| `.toFixed()` | Soluzione per visualizzare (stringa!) | `(0.1 + 0.2).toFixed(2)` → `"0.30"` | |
| `parseFloat()` (con `toFixed`) | Soluzione per calcolare (numero) | `parseFloat((0.1 + 0.2).toFixed(2))` → `0.30` | |
| `new Date()` | Crea un oggetto data | `new Date()` (ora) `new Date("2025-01-15")` | |
| Metodi Tricky (Date) | Attenzione ai bug! | `getMonth()` → `0-11` (Gennaio è 0!) `getDay()` → `0-6` (Domenica è 0!) | |
| `Date.now()` | Timestamp (millisecondi) | `Date.now()` (per misurare performance o ID unici) | |
| Boolean | Vero o Falso | `true` / `false` | |
| Truthy/Falsy | La "zona grigia" della verità | 6 falsy: `false, 0, "", null, undefined, NaN` Tutto il resto è truthy (anche `[]` e `{}`) | |
| Creazione `[]` vs `Array()` | Scatola per uova vuota | `Array(5)` → `[ <5 empty items> ]` (non `[5]`) | |
| `.length` | Quanti elementi (proprietà) | `arr[arr.length - 1]` (ultimo elemento) `arr.length = 0` (svuota array) | |
| `Set` e `.size` | Collezione di unici | `new Set([1,1,2]).size` → `2` `[...new Set([1,1,2])]` → `[1, 2]` | |
| `.push()` / `.pop()` | Modifica la fine (Distruttivo) | `arr.push(3)` (aggiunge) `arr.pop()` (rimuove) | |
| `.unshift()` / `.shift()` | Modifica l'inizio (Distruttivo) | `arr.unshift(1)` (aggiunge) `arr.shift()` (rimuove) | |
| `.splice()` | Coltellino svizzero (Distruttivo) | `arr.splice(1, 2, 'X')` (da indice 1, rimuovi 2, aggiungi 'X') | |
| `.sort()` | Ordina (Distruttivo!) | `arr.sort()` (alfabetico!) `arr.sort((a, b) => a - b)` (numerico) | |
| `.filter()` | Setaccio (Crea nuovo array) | `arr.filter(n => n > 2)` `arr.filter(u => u.attivo)` | |
| `.find()` | Detective (Trova il primo) | `arr.find(n => n > 2)` → `3` (o `undefined`) | |
| `.findIndex()` | Detective (Trova l'indice) | `arr.findIndex(n => n > 2)` → `2` (o `-1`) | |
| `.includes()` | Verificatore (C'è?) | `arr.includes(3)` → `true` | |
| `.indexOf()` | Cercatore (Dov'è?) | `arr.indexOf(3)` → `2` (o `-1`) | |
| `.join()` | Incollatore (Array → Stringa) | `['a','b'].join('-')` → `"a-b"` `['c','i','a','o'].join('')` → `"ciao"` | |
| `.slice()` | Fotocopiatrice (Crea nuovo array) | `arr.slice()` (copia) `arr.slice(1, 3)` (da indice 1 a 3 escluso) | |
| `.map()` | Fabbrica di trasformazione | `arr.map(n => n * 2)` `arr.map(u => u.nome)` | |
.reduce() | Caldaia (Array → Valore singolo) | arr.reduce((acc, n) => acc + n, 0) (somma)arr.reduce((obj, k) => ({...obj, [k]: true}), {}) | |
| `.some()` | Almeno uno? (true/false) | `arr.some(n => n > 2)` → `true` | |
| `.every()` | Tutti? (true/false) | `arr.every(n => n > 0)` → `true` | |
| `.fill()` | Ponte per `.map()` su `Array(N)` | `Array(3).fill(0)` → `[0, 0, 0]` `Array(3).fill().map((*, i) => i)` → `[0, 1, 2]` | |
| Pattern: Creare Range | Unisce `Array(N)`, `.fill`, `.map` | `Array(5).fill().map((*, i) => i + 1)` → `[1, 2, 3, 4, 5]` | |
| Logica: Mediana | Trova il centro (richiede sort) | Gestire `length % 2 === 0` (pari) vs `else` (dispari) | |
| Creazione Oggetti `{}` | Contenitore `chiave: valore` | `const user = { nome: "Mario" }` | |
| Oggetti Annidati | Oggetti dentro oggetti (Organizzazione) | `user.indirizzo = { citta: "Roma" }` `user.keys = { right: false }` | |
| Accesso `.` vs `[]` vs `?.` | Punto (statico) vs Parentesi (dinamico) vs Safe | `obj.nome` vs `obj[miaVar]` `obj.lavoro?.stipendio` (safe) | |
| Shorthand Properties | Scorciatoia ES6 | `const user = { nome, eta }` (se `nome` e `eta` esistono) | |
| Destructuring | "Spacchettare" oggetti | `const { nome, eta } = user;` `const { nome: nomeUtente } = user;` | |
| `Object.keys()` | Array di sole chiavi | `Object.keys(user)` → `['nome', 'eta']` | |
| `Object.values()` | Array di soli valori | `Object.values(user)` → `['Mario', 30]` | |
| `Object.entries()` | Array di coppie `[k, v]` | `Object.entries(user).forEach(([key, val]) => ...)` | |
| `hasOwnProperty()` | Controllo proprietà (Vecchio) | `user.hasOwnProperty('nome')` → `true` | |
| `Object.hasOwn()` | Controllo proprietà (Moderno) | `Object.hasOwn(user, 'nome')` → `true` | |
| Pattern: Mappa Frequenza | Contare occorrenze | `counts[item] = (counts[item] | |
| FONDAMENTI - OPERATORI | |||
| ` | ` (OR) | ||
| `!` (NOT) e "Toggle" | Invertitore Booleano | `isMenuOpen = !isMenuOpen;` `if (!user) { ... }` | |
| `...` (Spread) | "Svuota" scatola (Array/Oggetti) | `const copia = [...arr];` `const o2 = {...o1, b: 2};` | |
| `**` (Esponenziazione) | Elevamento a potenza (Moderno) | `2 ** 3` → `8` `9 ** 0.5` → `3` | |
| Assegnazione a Catena | Inizializzazione multipla (rischiosa) | `a = b = c = 10;` (Evitare se possibile) | |
| CONTROLLO - OUTPUT E COMMENTI | |||
| `console` | Cabina di pilotaggio (Debug) | `console.log(variabile)` `console.error("Errore!")` | |
| `console.table()` | Visualizza array/oggetti | `console.table(arrayDiOggetti)` | |
| Commenti `//` `/* */` | Note (Perché, non Cosa) | `// Contatore tentativi falliti` | |
| JSDoc `/** */` | Documentazione formale | `/** @param {string} nome ... */` | |
| Tag `TODO` `FIXME` `NOTE` | Organizzazione lavoro | `// FIXME: Non gestisce numeri negativi` | |
| CONTROLLO - FLUSSO | |||
| `if/else if/else` | Bivio decisionale | `if (x > 10) { ... } else { ... }` | |
| Operatore Ternario | `if/else` compatto (per assegnazioni) | `const stato = eta >= 18 ? "Adulto" : "Minore"` `el.style.display = isVisible ? "block" : "none"` | |
| `switch` | Centralino (per valori statici) | `switch (azione) { case 'salva': ... break; default: ... }` | |
| Return Early (Guard Clauses) | Buttafuori (Valida e esci subito) | `function f(user) { if (!user) return; ... }` | |
| CONTROLLO - CICLI | |||
| `for` | Robot industriale (sai n. giri) | `for (let i = 0; i < 10; i++) { ... }` | |
| `while` | Guardia notturna (condizione) | `while (x < 10) { x++; }` | |
| `do...while` | Prima fai, poi chiedi (almeno 1 giro) | `do { ... } while (cond);` (per menu) | |
| `for...of` | Esploratore elegante (per valori) | `for (const el of array) { ... }` `for (const char of "ciao") { ... }` | |
| `forEach` | Caposquadra (solo per Array) | `arr.forEach((el, i) => console.log(i, el))` | |
| `break` | Stop di emergenza (Esci dal ciclo) | `if (x === 5) break;` | |
| `continue` | Salta al prossimo giro | `if (x % 2 === 0) continue;` | |
| FUNZIONI E SCOPE | |||
| Dichiarazione vs Arrow `=>` | `function` (ha `this`) vs `=>` (eredita `this`) | `function f() {}` vs `const f = () => {}` | |
| Return Implicito (Arrow) | One-liner (senza `{}`) | `n => n * 2` | |
| Return Oggetto (Arrow) | Richiede `()` attorno a `{}` | `() => ({ nome: "Mario" })` (NON `() => { nome: "Mario" }`) | |
| Parametri di Default | Valori di fallback | `function f(n = 10) { ... }` | |
| Destrutturazione (Parametri) | "Spacchetta" argomenti | `function f({ id, nome }) { ... }` `function g([primo, secondo]) { ... }` | |
| Callback | Ricetta passata come argomento | `arr.map(n => n * 2)` (`n => n*2` è la callback) `btn.addEventListener('click', () => ...)` | |
| Currying | Fabbrica di funzioni specializzate | `const add = a => b => a + b;` `const add10 = add(10); add10(5);` → `15` | |
| Convenzione Underscore `_` | Parametro ignorato | `arr.map((_el, index) => index)` `btn.addEventListener('click', _ => console.log('click'))` | |
| Global Scope | Piazza pubblica (visibile a tutti) | Variabile fuori da tutto | |
| Local/Function Scope | Salotto privato (visibile solo in `function`) | `function f() { let x = 5; }` | |
| Block Scope | Ripostiglio (visibile solo in `{}`) | `let` e `const` in `if`, `for`, `while` | |
| Scope Chain | Ricerca chiavi (Tasca → Stanza → Casa) | Cerca da interno a esterno | |
| CLASSI (OOP) | |||
| `class` | Stampo per biscotti (Progetto) | `class Giocatore { ... }` | |
| Zucchero Sintattico | Maschera moderna per `prototype` | `typeof Giocatore` → `"function"` | |
| `constructor()` | Reparto assemblaggio (chiamato da `new`) | `constructor(x, y) { this.x = x; }` | |
| `new` | Comando "Crea" (I 4 passaggi) | `const p = new Giocatore(10, 20)` | |
| `this` | Contesto ("questo specifico biscotto") | `this.vite = 3;` | |
| Proprietà di Classe | Impostazioni di fabbrica | `class G { vite = 3; }` (fuori dal constructor) | |
| Metodi (nel `prototype`) | Zaino condiviso (Abilità) | `salta() { this.y -= 10; }` | |
| Pattern: `claim()` | Metodo per "disattivare" un'istanza | `this.width = 0; this.y = Infinity; this.claimed = true;` | |
| DOM - CARICAMENTO | |||
| Posizionamento `<script>` | `head` vs `body` | `<script>` prima di `</body>` (vecchio ma sicuro) | |
| `defer` (Best Practice) | Scarica in parallelo, esegui dopo | `<script src="..." defer></script>` (in `head`) | |
| `window.onload` | Aspetta tutto (immagini incluse) | Lento, da evitare se non serve | |
| `DOMContentLoaded` | Aspetta solo HTML/DOM (Veloce) | `window.addEventListener('DOMContentLoaded', () => ...)` | |
| DOM - MANIPOLAZIONE | |||
| `querySelector` / `All` | GPS Moderno (Usa selettori CSS) | `document.querySelector(".btn-primario")` `document.querySelectorAll("ul > li")` | |
| `getElementById` | Veloce per ID | `document.getElementById("header-principale")` | |
| `getElementsByClassName` | Vecchio modo (Restituisce `HTMLCollection` live) | `document.getElementsByClassName("nota")` | |
| Convertire `NodeList`/`Coll.` | Trasforma in vero Array | `[...nodelist]` `Array.from(nodelist)` | |
| Proprietà vs Metodi | Sostantivi (dati) vs Verbi (azioni) | `el.id = "..."` (Prop) vs `el.remove()` (Metodo) | |
| Attributi HTML vs Prop. DOM | Progetto vs Casa reale | `input.value` (realtà) vs `input.getAttribute('value')` (progetto) | |
| `document.createElement()` | Fabbrica (Crea in memoria) | `const p = document.createElement("p")` | |
| `container.appendChild()` | Installazione (Aggiungi alla pagina) | `container.appendChild(p)` | |
| `textContent` (Sicuro) | Pennarello (Solo testo, no HTML) | `el.textContent = "Ciao <strong>"` → `Ciao <strong>` | |
| `innerHTML` (Pericoloso) | Penna magica (Interpreta HTML) | `el.innerHTML = "<strong>Ciao</strong>"` → Ciao (Rischio XSS) | |
| `style.property` | Stile inline (sporco) | `el.style.backgroundColor = "red"` (usa camelCase) | |
| `classList` (Best Practice) | Etichetta (JS stato, CSS aspetto) | `el.classList.add('is-hidden')` `el.classList.toggle('active')` | |
| `disabled` | Attributo Booleano (On/Off) | `btn.disabled = true;` (non cliccabile) `btn.disabled = false;` (riabilita) | |
| `disabled` vs `readonly` | Porta sbarrata vs Vetro chiuso | `readonly` è visibile e viene inviato col form | |
| Child Combinator `>` | Selettore "Figlio Diretto" | `div > p` (solo figli, non nipoti) | |
| DOM - EVENTI | |||
| `onclick` vs `addEventListener` | Linea singola vs Centralino | `addEventListener` (moderno, multipli listener) | |
| Riferimento (`fn`) vs Esecuzione (`fn()`) | Manuale vs Torta (Passa il manuale!) | `el.addEventListener('click', miaFunzione)` ✅ `el.addEventListener('click', miaFunzione())` ❌ | |
| Oggetto `event` | Report dettagliato | `e.target` (chi ha scatenato) `e.key` (tasto premuto) | |
| `e.preventDefault()` | Freno di emergenza (Stop azione default) | `form.addEventListener('submit', e => e.preventDefault())` (stop refresh) | |
| Event Delegation | Buttafuori (1 listener sul genitore) | `ul.addEventListener('click', e => { if(e.target.tagName === 'LI') ... })` | |
| Problema: `this` e listener | `this` diventa il bottone, non la classe | `btn.addEventListener('click', this.metodo)` ❌ | |
| Soluzione: `.bind(this)` | Incolla `this` con supercolla | `btn.addEventListener('click', this.metodo.bind(this))` ✅ | |
| Soluzione: Arrow Function | Eredita `this` (Moderno) | `btn.addEventListener('click', () => this.metodo())` ✅ | |
| `keydown` vs `keyup` | Tasto giù vs Tasto su (Usa questi) | `e.key === "ArrowUp"` | |
| `keypress` (Deprecato) | Carattere digitato (Ignora frecce, ecc) | Non usare | |
| `change` vs `input` | "Finito" (blur) vs "Tempo Reale" (ogni tasto) | `input` per UX reattiva (es. ricerca live) `change` per validazione finale | |
| `submit` | Evento del `<form>` | Usare `e.preventDefault()` | |
| `confirm()` | Dialogo bloccante (Vecchio) | `const sì = confirm("Sicuro?")` (Evitare se possibile) | |
| DOM - DIALOG E MODALI | |||
| `<dialog>` | Palco portatile (Nativo HTML) | `<dialog id="modale">...</dialog>` | |
| `showModal()` | Faro (Blocca pagina, backdrop, Esc) | `dialog.showModal()` (Quello che vuoi 99%) | |
| `show()` | Pannello info (Non-modale) | `dialog.show()` (Pagina ancora attiva) | |
| `close()` | Uscita di scena | `dialog.close("valore")` `dialog.addEventListener('close', () => ...)` | |
| API CANVAS E GIOCHI | |||
| `getContext("2d")` | Aprire l'astuccio (Penne, pennarelli) | `const ctx = canvas.getContext("2d")` | |
| Coordinate (0,0) | Alto a sinistra | `Y` aumenta scendendo (`ctx.fillRect(0, 10, ...)` è 10px dall'alto) | |
| `fill` vs `stroke` | Pennarello (pieno) vs Penna (bordo) | `ctx.fillStyle = "red"` `ctx.strokeStyle = "blue"` | |
| Forme (Rettangoli, Percorsi) | Scorciatoie (`fillRect`) vs Ricetta (`beginPath`) | `ctx.fillRect(10, 10, 50, 50)` `ctx.beginPath(); ctx.arc(...); ctx.fill();` | |
| Risoluzione vs Dimensione | Pixel (JS) vs Dimensione (CSS) | `canvas.width = 1920` vs `canvas.style.width = "100%"` | |
| Problema: Effetto Sfocato | Risoluzione 300x150 "stirata" | Se JS `width` non combacia con CSS `width` | |
| Soluzione: Sincronizzare | Imposta JS `width` uguale a `innerWidth` | `canvas.width = window.innerWidth` (cancella il canvas!) | |
| `requestAnimationFrame` | Motore del gioco (Loop 60 FPS) | `function loop() { ...; requestAnimationFrame(loop); }` | |
| Vantaggi vs `setInterval` | Sincronizzato, Pausa automatica, Fluido | `rAF` è il re delle animazioni (non consuma batteria in background) | |
| Logica: Gravità | Accel. modifica Velocità, Velocità modifica Posizione | `velY += grav; posY += velY;` | |
| Logica: Flag Debouncing | Tornello (Evita 60 trigger/sec) | `if (coll && !isHit) { isHit = true; ... }` | |
| Logica: Responsive | Zoom automatico (Adatta al viewport) | `player.width = proportionalSize(100)` | |
| PATTERN E BEST PRACTICE | |||
| Pattern di Accumulo | Riempire il secchio (loop) | `let total = 0; arr.forEach(n => total += n)` `let html = ""; arr.forEach(s => html += `<li>${s}</li>`)` | |
| Flag Booleane | Interruttori di stato (On/Off) | `let isLoading = true;` `let hasError = false;` | |
| Variabili di Stato | Semaforo (Stati multipli) | `let formState = "submitting"` (vs `"editing"`, `"error"`) | |
| Configuration Objects | Pannello di controllo (No "numeri magici") | `const CONFIG = { MAX_RETRIES: 3 }` | |
| `try-catch` | Rete di sicurezza (Gestione errori) | `try { JSON.parse(str) } catch (e) { ... }` `async function f() { try { await fetch(...) } catch(e) { ... } }` | |
| Naming Convention | Nomi parlanti (Codice leggibile) | `isVisible` (bool) `fetchUsers` (funz) `users` (array) | |
| Testing Incrementale | Assaggiare il sugo (Debug con `console.log`) | Scrivi-testa-scrivi-testa | |
| Separazione Responsabilità | Una funzione = un compito (SoC) | Logica (JS) vs Presentazione (CSS) | |
| `style.display` vs `classList` | Vernice a mano (sporco) vs Etichetta (pulito) | Usa `classList` (JS stato, CSS aspetto) `el.classList.toggle("is-hidden")` | |
| `innerHTML =` vs `+=` | Sostituisci (OK) vs Ricrea (LENTO!) | `+=` distrugge e ricrea tutto il DOM (usa `appendChild`!) | |
| `.className` vs `.classList` | Stringa intera vs Kit chirurgico | Usa `classList` (`.add`, `.remove`) | |
| `.textContent` vs `innerHTML` | Pennarello (Sicuro) vs Penna Magica (Pericoloso) | Usa `textContent` per dati utente (previene XSS) | |
| Immutabilità | Fare fotocopie, non modificare originali | `const copia = [...arr, 4]` (Evita "Side Effects") | |
| `.sort()` vs `.toSorted()` | Distruttivo (muta) vs Immutabile (copia) | `.toSorted()` (moderno, non modifica l'originale) `.slice().sort()` (classico) | |
| Stile: Leggibilità vs Concisa | Raccontare storia vs Essere furbi | Leggibilità > Concisa (per debug) `const doppi = arr.map(n => n * 2)` (conciso ok) | |
| Algoritmo di Scambio (Swap) | Giostra (`temp`) vs Magia (Destructuring) | `[a, b] = [b, a]` (moderno) `let temp = a; a = b; b = temp;` (classico) | |
| Evoluzione Codice | Da Hardcoded a DRY a Event-Driven | `DRY` = Don't Repeat Yourself (usa funzioni) | |
| STORAGE (localStorage) | |||
| localStorage | Cassetto (Memoria a lungo termine) | `localStorage.setItem('chiave', 'valore')` `localStorage.getItem('chiave')` | |
| Problema: Muro delle Stringhe | Il fax (Salva solo stringhe) | `localStorage.setItem('user', {nome: 'a'})` → `"[object Object]"` | |
| `JSON.stringify()` | Smontatore (Oggetto → Stringa) | `localStorage.setItem('user', JSON.stringify(user))` | |
| `JSON.parse()` | Rimontatore (Stringa → Oggetto) | `const user = JSON.parse(localStorage.getItem('user'))` | |
| Gestire il Primo Avvio | Fallback (Piano B) | `const data = JSON.parse(localStorage.getItem('k')) | |
| Ispezionare (DevTools) | Visione a Raggi X (Tab Application) | Debug, modifica, cancella | |
| Limiti | 5MB, Sincrono (lento), Non sicuro (post-it) | Non salvare password! | |
| Pattern Avanzati | Versionamento, Scadenza, Namespace | `const k = "miaApp_user"` (namespace) `setWithExpiry(key, val, ttl)` | |
| Comandamenti | Le 10 regole del localStorage | "Salverai solo stringhe", "Non ti fiderai mai", ... | |
| ALGORITMI - REGEX | |||
| `/pattern/flags` | Metal detector per testo | `/ciao/gi` (globale, case-insensitive) | |
`.` `^` `$ | ` | Jolly, Inizio, Fine, OR | |
| `[]` (Character Class) | Club (Uno di questi) | `[aeiou]` (vocali) `[a-z0-9]` (range) | |
| `\d` `\w` `\s` `\b` | Scorciatoie (Cifra, Parola, Spazio, Confine) | `/\bcat\b/` (parola "cat" intera) | |
| `?` `+` `*` `{n,m}` | Quantificatori (Quanti?) | `\d+` (uno o più cifre) `colou?r` (opzionale) | |
| `` (Escape) | Disattivatore poteri speciali | `.` (punto letterale) `\` (backslash letterale) | |
| `()` vs `(?:...)` | Pullman (Raggruppa) vs Foto (Cattura) | `(?:http | |
| Lookahead `(?=...)` | "Seguito da..." (non consuma) | `\d+(?=€)` (numero prima di €)<br`\d+(?![a-z])` (numero non seguito da lettera) | |
| Lookbehind `(?<=...)` | "Preceduto da..." (non consuma) | `(?<=€)\d+` (numero dopo €) | |
| Pattern Reali | Email, URL, Password | `emailRegex.test(email)` | |
| ALGORITMI - RICORSIONE | |||
| Call Stack (LIFO) | Pila di piatti (Last In, First Out) | Gestisce l'ordine di esecuzione delle funzioni | |
| Stack Overflow | Troppi piatti, la pila crolla | Ricorsione infinita | |
| Ricorsione | Matrioske (Funzione chiama se stessa) | `return n * fattoriale(n - 1)` | |
| Caso Base | Matrioska solida (Condizione di stop) | `if (n <= 1) return 1;` | |
| Memoization | Post-it (Cache per risultati) | Evita ricalcoli (es. Fibonacci) `if (cache[n]) return cache[n];` | |
| ALGORITMI - TIMING | |||
| `setTimeout(fn, ms)` | Sveglia (Esegui dopo ms) | `const t = setTimeout(() => ..., 1000)` | |
| `setInterval(fn, ms)` | Metronomo (Esegui ogni ms) | `const i = setInterval(() => ..., 1000)` | |
| `clearTimeout/Interval` | Cancella timer | `clearTimeout(t)` `clearInterval(i)` | |
| `setTimeout` vs `setInterval` | Orologio stupido (può accavallarsi) | `setTimeout` ricorsivo è più sicuro per animazioni | |
| Debounce | "Esegui dopo che l'utente ha finito" | `onkeyup` in una barra di ricerca | |
| Throttle | "Esegui al massimo ogni X ms" | `onscroll` per non sovraccaricare | |
| ALGORITMI - PRATICI | |||
| Decimale → Binario | Divisione per 2, leggi resti | `binary = (num % 2) + binary; num = Math.floor(num / 2);` | |
| Bubble Sort | Bolle (Semplice ma lento) | `if (arr[j] > arr[j+1]) [arr[j], arr[j+1]] = [arr[j+1], arr[j]]` | |
| Quick Sort | Divide et Impera (Veloce) | Scegli `pivot`, dividi in `left`/`right`, ricorsione | |
| Binary Search | Ricerca dizionario (Richiede sort) | Taglia la ricerca a metà a ogni giro (`mid = floor((l+r)/2)`) | |
| Palindromo | `str === str.reverse()` | `const c = str.toLowerCase().replace(...)` `return c === c.split('').reverse().join('')` | |
| Anagrammi | Stesse lettere | `const c1 = str1.split('').sort().join('')` `return c1 === c2;` | |
| Numeri Primi (Test) | Controlla divisori fino a `sqrt(n)` | `for (let i = 2; i * i <= n; i++) ...` | |
| Fibonacci (Iterativo) | Somma i due precedenti | `[prev, curr] = [curr, prev + curr]` | |
| MCD (Euclide) | Massimo Comun Divisore | `gcd(a, b) = gcd(b, a % b)` | |
| PATTERN - VALIDAZIONE E STATO | |||
| Guard Clauses | Buttafuori (Return early) | `if (!data) return;` `if (num < 0) return;` (pulisce il codice) | |
| Sanitizzazione | Pulizia (Rimuovi/Escapa) | `str.replace(/[^a-z0-9]/g, '')` `el.textContent = str` (sanitizza per HTML) | |
| Validazione | Controllo (Accetta/Rifiuta) | `emailRegex.test(email)` | |
| Single Source of Truth (SSOT) | Libro mastro (Unico stato centrale) | Previene dati non sincronizzati (es. `const state = { ... }`) | |
| CRUD | Create, Read, Update, Delete | Pattern per gestire liste (es. TaskManager) | |
| Pattern di Reset | Fabbrica di stato | `state = createInitialState()` (evita reset manuale) |