CHI HA PAURA DELL’INTELLIGENZA ARTIFICIALE?
let, const, var (approfondimento)const: riferimento immutabile di binding. Non si può riassegnare il nome a un altro valore. Se il valore è un oggetto/array, le sue proprietà/elementi possono comunque cambiare.
let: variabile riassegnabile con scope di blocco ( { ... } ). Usare per valori che cambiano.
var: scope di funzione (o globale se dichiarato fuori funzione), soggetto a hoisting (dichiarazione "spostata" in cima), comportamento problematico — evitare salvo comprensione storica.
// constconst PI = 3.14159;PI = 3; // TypeError: Assignment to constant variable.// letlet counter = 0;if (true) {let counter = 10; // scope diverso: non sovrascrive l'esternoconsole.log(counter); // 10}console.log(counter); // 0// var (evitare)function f() {if (true) {var x = 1; // scope di funzione}console.log(x); // 1}
var x; è "hoisted" (dichiarazione spostata all'inizio), quindi console.log(x) prima della dichiarazione stampa undefined.
let/const sono anch’essi "visibili" ma non utilizzabili prima della dichiarazione — questo causa ReferenceError se provi ad accedervi nella TDZ.
Best practice: preferire const per valori che non cambiano, let quando serve riassegnare. Evitare var.
Rappresentazione in virgola mobile → attenzioni a precisione.
Esempi: 42, 3.14, -0 (significato particolare), NaN, Infinity.
typeof 123; // "number"typeof 3.14; // "number"Number.isNaN(NaN); // true1 / 0; // Infinity
Nota su NaN: NaN !== NaN. Usare Number.isNaN() per verificare.
Per interi molto grandi: 123n è un BigInt (JS moderno).
const big = 9007199254740993n; // oltre MAX_SAFE_INTEGER
Testo: concatenazione con +, template literal con backticks `... ${expr} ...`.
"ciao" + " mondo"; // "ciao mondo"`2 + 3 = ${2 + 3}`; // "2 + 3 = 5"
true / false. Molte operazioni e valori sono truthy o falsy (es. 0, "", null, undefined, NaN sono falsy).
"2" + 3 → "23" (concatenazione).
+"3" o Number("3") converte a numero.
Preferire conversioni esplicite.
Aritmetici: +, -, *, /, % (modulo), ** (potenza)
Incremento/decremento: ++, --
Assegnazione composta: +=, -=, *=, /=
()
**
*, /, %
+, -
assegnazioni
Esempio noto: 0.1 + 0.2 in JavaScript restituisce 0.30000000000000004 (perché i numeri sono rappresentati in base 2 e non tutte le frazioni decimali sono esatte).
Dimostrazione semplice (metodo stabile): se vuoi sommare 0.1 e 0.2 con esattezza decimale di 1 cifra:
moltiplica per 10: 0.1 * 10 = 1, 0.2 * 10 = 2
somma intera: 1 + 2 = 3
riporta a scala decimale: 3 / 10 = 0.3
Esempio pratico in codice (soluzione semplice):
function preciseAdd(a, b) {const sA = a.toString();const sB = b.toString();const dA = (sA.split('.')[1] || '').length;const dB = (sB.split('.')[1] || '').length;const factor = 10 ** Math.max(dA, dB);return (Math.round(a * factor) + Math.round(b * factor)) / factor;}preciseAdd(0.1, 0.2); // 0.3
Nota: per applicazioni finanziarie reali usare librerie per aritmetica decimale (es.
decimal.js) o tipi specifici.
1 / 0 → Infinity
0 / 0 → NaN
% restituisce il resto, ma il segno segue il dividendo in JS: -5 % 3 === -2.
== (uguaglianza non rigorosa): effettua coercizioni.
=== (uguaglianza stretta): no coercione — preferire ===.
!= vs !== analoghi.
Esempi insidiosi
0 == false; // true0 === false; // false"" == 0; // truenull == undefined; // truenull === undefined; // false
Regola: usare === a meno di esplicita necessità di coercizione.
&&, ||, !)Valutano operandi e short-circuit:
a && b: restituisce a se falsy, altrimenti b.
a || b: restituisce a se truthy, altrimenti b.
Utile per default: const name = input || "Anonimo" (ma attenzione se input === "").
Esempio:
function getDefault(input) {return input || "default";}getDefault(""); // "default"getDefault("ciao"); // "ciao"
Se vuoi distinguere "" da null/undefined, usa ?? (nullish coalescing) in JS moderno:
input ?? "default"; // ritorna input se non null/undefined; altrimenti default
Scrivi espressioni che valutino a true:
0 == false? (spiegare il perché)
0 === false? (spiegare perché no)
Soluzione (spiegata):
0 == false è true perché == converte false in 0 prima del confronto.
0 === false è false perché il tipo number non è uguale al tipo boolean.
Dato l'input utente a = "3.5", b = "2", calcola la somma numerica corretta.
Soluzione:
const a = "3.5";const b = "2";const sum = parseFloat(a) + parseFloat(b); // 5.5
Dimostrare il comportamento di 0.1 + 0.2 e risolverlo con scaling:
console.log(0.1 + 0.2); // 0.30000000000000004console.log( (0.1*10 + 0.2*10) / 10 ); // 0.3
Discussione: spiegare perché accade e come risolvere per casi didattici.
Accetta due numeri (decimali possibili).
Opera le quattro funzioni di base: +, -, *, /.
Controlla input non numerico e divisione per zero.
Mostra risultato in modo leggibile (es. 2 decimali opzionali).
function calc(a, b, op) {const x = parseFloat(a);const y = parseFloat(b);if (Number.isNaN(x) || Number.isNaN(y)) {return 'Errore: input non numerico';}switch(op) {case '+': return x + y;case '-': return x - y;case '*': return x * y;case '/':if (y === 0) return 'Errore: divisione per zero';return x / y;default:return 'Operatore non supportato';}}console.log(calc("2.5", "1.2", "+")); // 3.7
Copiare questo file .html e aprirlo con un browser:
<!doctype html><html lang="it"><head><meta charset="utf-8" /><title>Calcolatrice Base</title><style>body { font-family: Arial, sans-serif; padding: 20px; }.box { max-width: 420px; margin: auto; background:#f7f7f7; padding:16px; border-radius:8px; }input, select, button { font-size:1rem; padding:8px; margin:6px 0; width:100%; box-sizing:border-box; }.result { margin-top:12px; padding:10px; background:#222; color:#fff; border-radius:6px; text-align:center; }</style></head><body><div class="box"><h2>Calcolatrice Base</h2><label>Primo numero<input id="a" type="text" placeholder="es. 3.5" /></label><label>Secondo numero<input id="b" type="text" placeholder="es. 2" /></label><label>Operazione<select id="op"><option value="+">Addizione (+)</option><option value="-">Sottrazione (-)</option><option value="*">Moltiplicazione (*)</option><option value="/">Divisione (/)</option></select></label><button id="calcBtn">Calcola</button><div id="result" class="result" aria-live="polite">Risultato: —</div></div><script>function safeParseNumber(s) {if (s === null || s === undefined) return NaN;// rimuove spazi e usa la virgola come possibile separatores = s.trim().replace(',', '.');return Number(s);}function calc(aRaw, bRaw, op) {const a = safeParseNumber(aRaw);const b = safeParseNumber(bRaw);if (Number.isNaN(a) || Number.isNaN(b)) {return { ok: false, msg: 'Errore: uno dei due input non è un numero valido' };}if (op === '/' && b === 0) {return { ok: false, msg: 'Errore: divisione per zero' };}// operazione: usiamo parseFloat-style, ma per risultati precisi usare preciseAdd ecc.let res;switch (op) {case '+': res = a + b; break;case '-': res = a - b; break;case '*': res = a * b; break;case '/': res = a / b; break;default: return { ok: false, msg: 'Operatore non supportato' };}// formattazione: mostra fino a 10 cifre significative evitando notazione esponenziale per numeri piccoliconst display = Number.isFinite(res) ? Number(res.toPrecision(12)).toString() : String(res);return { ok: true, value: display };}document.getElementById('calcBtn').addEventListener('click', () => {const a = document.getElementById('a').value;const b = document.getElementById('b').value;const op = document.getElementById('op').value;const out = calc(a, b, op);const el = document.getElementById('result');if (!out.ok) {el.textContent = out.msg;el.style.background = '#c0392b';} else {el.textContent = 'Risultato: ' + out.value;el.style.background = '#2ecc71';}});</script></body></html>
Spiegazioni implementative:
safeParseNumber supporta la virgola come separatore decimale (utile per utenti italiani).
calc verifica input, protegge dalla divisione per zero e restituisce sempre oggetti {ok, value/msg} per gestire errori con chiarezza.
toPrecision(12) evita stampare la lunga 0.30000000000000004 in caso di somme come 0.1 + 0.2; si potrebbe usare la versione preciseAdd per risultati esatti quando necessario.
Estendere la calcolatrice per supportare la percentuale: es. a % → restituisce a / 100.
Memoria: aggiungere tasti M+, MC, MR (memoria).
Chain calc (intermedio): permettere insert di più operazioni in un array e ridurle (es. 3 + 4 * 2). Nota: valutare precedenza operazioni.
Precisione avanzata: implementare funzioni preciseAdd, preciseSub, preciseMul, preciseDiv che usano scaling intero per ottenere risultati corretti per numeri con molti decimali.
Unit tests: scrivere test (con Jest o simple assertions) per le funzioni della calcolatrice.
Dichiarazioni: const a = 1; let b = 2; var c = 3;
Convertire a numero: Number("3.14"), parseFloat("3,14".replace(',', '.'))
Verifica NaN: Number.isNaN(x)
Confronto corretto: usare === e !==
String template: `Risultato: ${x}`
Profilo virgola mobile: 0.1 + 0.2 === 0.3 → false in JS; usare scaling per precisione.
Commenti
Posta un commento