Класс `Number` в JavaScript

Класс `Number` в JavaScript

В этой статье объясняется класс Number в JavaScript.

Мы подробно рассмотрим особенности Number, распространённые ошибки, полезные API и практические примеры шаг за шагом.

YouTube Video

Класс Number в JavaScript

Number — это основной числовой тип в JavaScript, представленный как 64-битное число с плавающей запятой двойной точности по стандарту IEEE-754.

Основы: представление числа и проверка типа

В JavaScript все числа представлены примитивным типом 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)
  • Этот код демонстрирует разницу между примитивным типом number и объектом-обёрткой Number. Обычно используются примитивы, а не объекты-обёртки.

Особые значения: NaN, Infinity и константы

Number предоставляет специальные значения (NaN, Infinity) и константы.

 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
  • Целые числа больше или равные MAX_SAFE_INTEGER могут быть представлены неточно. Используйте BigInt, если требуется точность. EPSILON используется для сравнения чисел с плавающей запятой.

Преобразование в число: Number(), parseInt, parseFloat и оператор +

Существует несколько способов преобразовать строку в число, и каждый ведёт себя по-разному.

 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() возвращает NaN, если вся строка не полностью соответствует числовому формату, тогда как parseInt и parseFloat извлекают распознаваемую числовую часть с начала строки. Безопаснее всегда явно указывать систему счисления при использовании parseInt.

Обработка и проверка NaN: isNaN и Number.isNaN

NaN (Not-A-Number, не число) примечателен тем, что NaN !== NaN. Между ними есть различия: глобальный isNaN приводит типы и может давать ложные срабатывания, поэтому рекомендуется использовать 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
  • Используйте Number.isNaN для проверки чисел и валидации результатов вычислений, чтобы избежать ненужного приведения типов.

Погрешности чисел с плавающей запятой и сравнения с использованием Number.EPSILON

Из-за стандарта IEEE-754 возможны ошибки, такие как 0.1 + 0.2 !== 0.3. Для строгих сравнений обычно используют разницу и 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
  • Если сравнение допускает погрешности, рекомендуется надёжная реализация вроде nearlyEqual, использующая масштабирование и абсолютные разницы.

Проверка целых чисел и безопасных целых (isInteger, isSafeInteger)

Существуют API для проверки, является ли значение целым числом и находится ли оно в диапазоне безопасных целых.

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
  • Когда требуется точность для больших целых чисел, используйте Number.isSafeInteger для проверки, а для чисел, выходящих за пределы диапазона, используйте BigInt.

Отображение и форматирование: toFixed, toPrecision, toString

Существуют методы для управления отображением чисел. toFixed возвращает строку с заданным количеством знаков после запятой, но следует учитывать нюансы округления.

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 возвращает строку, будьте внимательны при преобразовании значения обратно в число для вычислений.

Предостережения при конкатенации строк и использовании оператора +

Оператор + используется как для числового сложения, так и для конкатенации строк, из-за чего возможны неожиданные результаты в зависимости от типов данных.

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)
  • При смешивании строк и чисел безопаснее явно использовать String(), Number() или шаблонные строки, чтобы избежать неявного преобразования типов.

Продвинутые случаи использования: Number.parseInt / Number.parseFloat, valueOf

Number.parseInt и Number.parseFloat — это алиасы глобальных функций. valueOf используется для получения примитивного значения из объекта Number, но на практике требуется редко.

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)
  • При использовании Number.parseInt и Number.parseFloat будьте внимательны с указанием системы счисления и обрезкой строки. Объектов-обёрток обычно избегают.

Справка: небольшой утилитный пример — функции проверки чисел

Вот небольшие утилитные функции, которые объединяют часто используемые проверки. Это упрощает задачи, например, валидацию ввода.

 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}
  • Это очень универсальные функции, которые можно многократно использовать для обработки ввода и сравнений. Реализации, выбрасывающие ошибки, полезны для целей валидации.

Резюме по производительности и лучшим практикам

Вот практические советы по использованию Number.

  • В целом, используйте примитивный тип number и избегайте new Number().
  • Выбирайте между Number() (строгое преобразование) или parseInt/parseFloat (частичное извлечение) для преобразования строки в число в зависимости от задачи.
  • Используйте Number.isNaN и Number.isFinite для безопасной проверки.
  • Для сравнения чисел с плавающей запятой используйте Number.EPSILON или создайте специализированную функцию сравнения.
  • Когда требуется точность целых чисел, используйте Number.isSafeInteger; если диапазон превышен — используйте BigInt.
  • Вы можете использовать toFixed или toPrecision для округления при отображении, но имейте в виду, что возвращаемое значение — это строка.

Резюме

Number — это базовый тип для всех чисел в JavaScript, включая целые, дробные и специальные значения (NaN и Infinity). Важно учитывать преобразование типов и ошибки с плавающей запятой, а также правильно использовать методы вроде Number.isNaN и Number.EPSILON. Если диапазон безопасных целых превышен, используйте BigInt, а для округления и отображения используйте toFixed или toPrecision.

Вы можете следовать этой статье, используя Visual Studio Code на нашем YouTube-канале. Пожалуйста, также посмотрите наш YouTube-канал.

YouTube Video