La classe `Number` in JavaScript
Questo articolo spiega la classe Number in JavaScript.
Spiegheremo attentamente le caratteristiche di Number, le insidie comuni, le API utili e degli esempi pratici passo dopo passo.
YouTube Video
La classe Number in JavaScript
Number è il tipo numerico fondamentale in JavaScript ed è rappresentato come un float a doppia precisione IEEE-754 (64 bit).
Nozioni di base: Rappresentazione dei numeri e controllo del tipo
In JavaScript, tutti i numeri sono rappresentati come tipo primitivo number.
1// Primitive numbers and Number object
2const a = 42; // primitive number
3const b = 3.14; // primitive float
4const c = Number(10); // primitive via constructor call (function form)
5const d = new Number(10); // Number object (wrapper)
6
7console.log(typeof a); // "number"
8console.log(typeof d); // "object"
9console.log(c == d); // true (value coerces)
10console.log(c === d); // false (different types)
- Questo codice dimostra la differenza tra un tipo primitivo
numbere l’oggetto wrapperNumber. Normalmente si usano i primitivi invece dei wrapper.
Valori speciali: NaN, Infinity e costanti
Number fornisce valori speciali (NaN, Infinity) e costanti.
1// Special numeric values and constants
2console.log(Number.NaN); // NaN
3console.log(Number.POSITIVE_INFINITY); // Infinity
4console.log(Number.NEGATIVE_INFINITY); // -Infinity
5
6console.log(Number.MAX_VALUE); // largest positive representable
7console.log(Number.MIN_VALUE); // smallest positive representable (closest to 0)
8console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
9console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
10console.log(Number.EPSILON); // smallest difference ~2.220446049250313e-16
- Gli interi maggiori o uguali a
MAX_SAFE_INTEGERpotrebbero non essere rappresentati accuratamente. Prendi in considerazione l'uso diBigIntse è richiesta precisione.EPSILONviene utilizzato per i confronti tra numeri in virgola mobile.
Conversione dei numeri: Number(), parseInt, parseFloat e operatore +
Esistono diversi modi per convertire una stringa in un numero, ognuno con comportamenti differenti.
1// Converting strings to numbers
2console.log(Number("42")); // 42
3console.log(Number(" 3.14 ")); // 3.14
4console.log(+ "7"); // 7 (unary +)
5
6console.log(parseInt("42px")); // 42
7console.log(parseFloat("3.14abc"));// 3.14
8
9// Careful with parseInt and radix
10console.log(parseInt("08")); // 8
11console.log(parseInt("08", 10)); // 8 (explicit radix is safer)
Number()restituisceNaNa meno che l'intera stringa non sia in formato numerico puro, mentreparseInteparseFloatanalizzano la parte numerica leggibile dall'inizio della stringa. È più sicuro specificare sempre esplicitamente la base quando si utilizzaparseInt.
Gestione e verifica di NaN: isNaN e Number.isNaN
NaN (Not-A-Number) è speciale perché NaN !== NaN. Ci sono differenze nel modo in cui controllano; la funzione globale isNaN esegue una conversione di tipo e può portare a falsi positivi, quindi si consiglia di usare Number.isNaN.
1// NaN detection differences
2console.log(NaN === NaN); // false
3
4console.log(isNaN("foo")); // true -> because "foo" coerces to NaN
5console.log(Number.isNaN("foo")); // false -> "foo" is not the numeric NaN
6
7console.log(Number.isNaN(NaN)); // true
- Usa
Number.isNaNper verificare i numeri e validare i risultati dei calcoli per evitare conversioni di tipo non necessarie.
Errori di virgola mobile e confronti con Number.EPSILON
A causa dello standard IEEE-754 si verificano errori come 0.1 + 0.2 !== 0.3. Per confronti rigorosi è comune usare la differenza e Number.EPSILON.
1// Floating point precision example and EPSILON comparison
2const sum = 0.1 + 0.2;
3console.log(sum === 0.3); // false
4
5function nearlyEqual(a, b, epsilon = Number.EPSILON) {
6 return Math.abs(a - b) <= epsilon * Math.max(1, Math.abs(a), Math.abs(b));
7}
8
9console.log(nearlyEqual(sum, 0.3)); // true
- Quando si tollerano errori nei confronti, è consigliata un'implementazione robusta come
nearlyEqualche esegue anche lo scaling oltre all'uso delle differenze assolute.
Verifica di interi e interi sicuri (isInteger, isSafeInteger)
Ci sono API per verificare se un valore è un intero e se rientra nell'intervallo degli interi sicuri.
1// Integer and safe integer checks
2console.log(Number.isInteger(3)); // true
3console.log(Number.isInteger(3.0)); // true
4console.log(Number.isInteger(3.1)); // false
5
6console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)); // true
7console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)); // false
- Quando è richiesta la precisione di grandi numeri interi, usa
Number.isSafeIntegerper controllare e considera l'uso diBigIntper numeri che superano tale intervallo.
Visualizzazione e formattazione: toFixed, toPrecision, toString
Sono disponibili metodi per controllare la visualizzazione dei numeri. toFixed restituisce una stringa con un numero specificato di cifre decimali, ma bisogna fare attenzione all'arrotondamento.
1// Formatting numbers for display
2const x = 1.23456;
3console.log(x.toFixed(2)); // "1.23" (string)
4console.log(x.toPrecision(3)); // "1.23" (string with total significant digits)
5console.log((255).toString(16)); // "ff" (hexadecimal string)
toFixedrestituisce una stringa, perciò presta attenzione ai valori dopo averli convertiti nuovamente in numeri per i calcoli.
Avvertenze sulla concatenazione di stringhe e sull'operatore +
L'operatore + viene utilizzato sia per la somma numerica che per la concatenazione di stringhe, quindi possono verificarsi risultati indesiderati a seconda dei tipi di dati coinvolti.
1// Pitfall with + operator and type coercion
2console.log(1 + 2 + "px"); // "3px"
3console.log("px" + 1 + 2); // "px12"
4console.log(1 + "2" - 0); // 3 (string coerced to number for subtraction)
- Quando vengono mescolati stringhe e numeri, è più sicuro usare esplicitamente
String(),Number()o i template literal per evitare conversioni di tipo implicite.
Casi d'uso avanzati: Number.parseInt / Number.parseFloat, valueOf
Number.parseInt e Number.parseFloat sono alias delle funzioni globali. valueOf viene utilizzato per ottenere il valore primitivo da un oggetto Number, ma è raramente necessario nella pratica.
1// Number.parseInt/parseFloat aliases and valueOf example
2console.log(Number.parseInt("100", 10)); // 100
3console.log(Number.parseFloat("3.14")); // 3.14
4
5const nObj = new Number(5);
6console.log(nObj.valueOf()); // 5
7console.log(nObj + 1); // 6 (object coerced to primitive)
- Quando utilizzi
Number.parseInteNumber.parseFloat, fai attenzione alla base e alla rimozione degli spazi nell'input. Gli oggetti wrapper generalmente vengono evitati.
Riferimento: Esempio di piccola utilità - Funzioni di validazione dei numeri
Ecco delle piccole funzioni di utilità che raccolgono controlli comunemente usati. Questo rende più semplici attività come la validazione degli input.
1// Small number utility functions
2function toNumberStrict(value) {
3 // Return a Number or throw for invalid numeric strings
4 const n = Number(value);
5 if (typeof value === "string" && value.trim() === "") {
6 throw new Error("Empty string is not a valid number");
7 }
8 if (Number.isNaN(n)) {
9 throw new Error(`Invalid number: ${value}`);
10 }
11 return n;
12}
13
14function almostEqual(a, b, eps = Number.EPSILON) {
15 // Robust relative comparison
16 return Math.abs(a - b) <= eps * Math.max(1, Math.abs(a), Math.abs(b));
17}- Si tratta di funzioni molto versatili che possono essere riutilizzate per l'elaborazione degli input e i confronti. Implementazioni che generano errori sono utili a fini di validazione.
Riepilogo sulle prestazioni e sulle migliori pratiche
Ecco alcuni punti pratici nell'uso di Number.
- Fondamentalmente, usa il tipo primitivo
numbered evitanew Number(). - Scegli tra
Number()(rigoroso) oparseInt/parseFloat(estrazione parziale) per la conversione da stringa a numero a seconda del caso d'uso. - Usa
Number.isNaNeNumber.isFiniteper controlli sicuri. - Per confronti in virgola mobile, usa
Number.EPSILONoppure crea una funzione dedicata. - Quando è richiesta precisione sugli interi, usa
Number.isSafeIntegere se il valore supera l'intervallo, usaBigInt. - Puoi usare
toFixedotoPrecisionper arrotondare a scopo di visualizzazione, ma nota che il valore restituito è una stringa.
Riepilogo
Number è il tipo di base per tutti i numeri in JavaScript, inclusi interi, decimali e valori speciali (NaN e Infinity). È importante essere consapevoli della conversione dei tipi e degli errori di virgola mobile, utilizzando correttamente metodi come Number.isNaN e Number.EPSILON. Se viene superato l'intervallo degli interi sicuri, usa BigInt e utilizza toFixed o toPrecision per arrotondamenti e visualizzazione.
Puoi seguire l'articolo sopra utilizzando Visual Studio Code sul nostro canale YouTube. Controlla anche il nostro canale YouTube.