Klassen `Number` i JavaScript

Klassen `Number` i JavaScript

Denne artikel forklarer klassen Number i JavaScript.

Vi vil omhyggeligt gennemgå egenskaberne ved Number, almindelige faldgruber, nyttige API'er og praktiske eksempler trin for trin.

YouTube Video

Klassen Number i JavaScript

Number er den grundlæggende numeriske type i JavaScript og repræsenteres som et IEEE-754 dobbeltpræcisions-flydende punktal (64-bit).

Grundlæggende: Tals repræsentation og typekontrol

I JavaScript repræsenteres alle tal som den primitive type 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)
  • Denne kode demonstrerer forskellen mellem en primitiv number og Number wrapper-objektet. Normalt bruges primitive typer i stedet for wrappers.

Specielle værdier: NaN, Infinity og konstanter

Number leverer specielle værdier (NaN, Infinity) og konstanter.

 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
  • Heltal større end eller lig med MAX_SAFE_INTEGER kan muligvis ikke repræsenteres nøjagtigt. Overvej at bruge BigInt, hvis nøjagtighed er påkrævet. EPSILON bruges til sammenligning af flydende tal.

Talskonvertering: Number(), parseInt, parseFloat og +-operatoren

Der er flere måder at konvertere en streng til et tal på, hver med forskellig adfærd.

 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() returnerer NaN, medmindre hele strengen udelukkende er i numerisk format, hvorimod parseInt og parseFloat læser den numeriske del fra begyndelsen af strengen. Det er sikrere altid eksplicit at angive det numeriske grundtal (radix), når man bruger parseInt.

Håndtering og kontrol af NaN: isNaN og Number.isNaN

NaN (Not-A-Number) er speciel, da NaN !== NaN. Der er forskelle i, hvordan de kontrollerer; den globale isNaN foretager typekonvertering og kan føre til falske positiver, så Number.isNaN anbefales.

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
  • Brug Number.isNaN til at kontrollere tal og validere beregningsresultater for at undgå unødig typekonvertering.

Fejl i flydende tal og sammenligninger ved hjælp af Number.EPSILON

På grund af IEEE-754 opstår fejl som 0.1 + 0.2 !== 0.3. Ved strenge sammenligninger er det almindeligt at bruge forskellen og 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
  • Når man tillader fejl i sammenligninger, anbefales det at bruge en robust implementering som nearlyEqual, der også tager højde for skalering og bruger absolutte forskelle.

Kontrol af heltal og sikre heltal (isInteger, isSafeInteger)

Der findes API'er til at kontrollere, om en værdi er et heltal, og om den ligger inden for det sikre heltalsområde.

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
  • Når nøjagtighed ved store heltal er nødvendig, brug Number.isSafeInteger til at kontrollere det, og overvej at bruge BigInt for tal, der overstiger dette område.

Visning og formatering: toFixed, toPrecision, toString

Der findes metoder til at kontrollere, hvordan tal vises. toFixed returnerer en streng med et bestemt antal decimaler, men man skal være opmærksom på afrunding.

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)
  • toFixed returnerer en streng, så vær opmærksom på værdierne, når de konverteres til tal for beregninger.

Advarsler vedrørende strengsammenkædning og +-operatoren

+-operatoren bruges både til numerisk addition og sammenkædning af strenge, så utilsigtede resultater kan forekomme afhængigt af de involverede datatyper.

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)
  • Når strenge og tal blandes, er det sikrere eksplicit at bruge String(), Number() eller template literals for at undgå implicit typekonvertering.

Avancerede brugstilfælde: Number.parseInt / Number.parseFloat, valueOf

Number.parseInt og Number.parseFloat er aliaser for de globale funktioner. valueOf bruges til at hente den primitive værdi fra et Number-objekt, men det er sjældent nødvendigt i praksis.

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)
  • Når du bruger Number.parseInt og Number.parseFloat, skal du være forsigtig med grundtallet (radix) og med at trimme inputtet. Wrapper-objekter undgås normalt.

Reference: Lille hjælpeeksempel – Talsvalideringsfunktioner

Her er små hjælpefunktioner, der samler ofte anvendte kontroller. Dette gør opgaver som validering af input lettere.

 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}
  • Dette er meget alsidige funktioner, der kan bruges gentagne gange til inputbehandling og sammenligninger. Implementeringer, der kaster fejl, er nyttige til valideringsformål.

Resumé af ydeevne og bedste praksis

Følgende er praktiske punkter ved brug af Number.

  • Brug grundlæggende den primitive type number og undgå new Number().
  • Vælg mellem Number() (strikt) eller parseInt/parseFloat (delvis udtrækning) til konvertering fra streng til tal afhængigt af din brugssituation.
  • Brug Number.isNaN og Number.isFinite til sikker kontrol.
  • Til sammenligning af flydende tal, brug Number.EPSILON eller opret en dedikeret sammenligningsfunktion.
  • Når heltalsnøjagtighed er påkrævet, brug Number.isSafeInteger, og hvis det overstiger området, brug BigInt.
  • Du kan bruge toFixed eller toPrecision til afrunding til visning, men bemærk, at returværdien er en streng.

Sammendrag

Number er grundtypen for alle tal i JavaScript, inklusiv heltal, decimaltal og specialværdier (NaN og Infinity). Det er vigtigt at være opmærksom på typekonvertering og fejl i flydende tal og at bruge metoder som Number.isNaN og Number.EPSILON korrekt. Hvis det sikre heltalsområde overskrides, brug BigInt, og brug toFixed eller toPrecision til afrunding og visning.

Du kan følge med i ovenstående artikel ved hjælp af Visual Studio Code på vores YouTube-kanal. Husk også at tjekke YouTube-kanalen.

YouTube Video