Научная нотация используется для представления очень больших и очень
маленьких чисел в компактной форме, основанной на степени десяти. В
JavaScript современная поддержка такого формата реализована через
Intl.NumberFormat, а в экосистеме FormatJS — через обёртки
в react-intl и ICU MessageFormat, которые позволяют
стандартизировать отображение чисел в интерфейсах приложений.
В основе лежит параметр форматирования notation,
появившийся в спецификации ECMA-402. Он определяет способ отображения
числовых значений: стандартный (standard), компактный
(compact) и научный (scientific). Научная
нотация представляет число в виде коэффициента и степени десяти,
например:
В программной модели JavaScript это выражается строкой с символом
E, который обозначает экспоненту.
Базовый механизм основан на Intl.NumberFormat. Он
поддерживает параметр notation, который управляет способом
отображения числа.
const formatter = new Intl.NumberFormat('en-US', {
notation: 'scientific'
});
formatter.format(1200000);
// "1.2E6"
formatter.format(0.000031);
// "3.1E-5"
Формат возвращает строку, где число нормализуется до коэффициента от
1 до 10 (или от -10 до -1 для отрицательных значений), а степень
отображается через E.
Локаль влияет на форматирование десятичного разделителя и отображение знаков:
new Intl.NumberFormat('de-DE', {
notation: 'scientific'
}).format(1200000);
// "1,2E6"
В немецкой локали используется запятая вместо точки, что сохраняет культурную согласованность интерфейса.
FormatJS строится вокруг стандарта ICU MessageFormat и библиотеки
react-intl, которая оборачивает Intl API,
добавляя декларативный слой для React-приложений.
Основной инструмент — компонент
<FormattedNumber>.
import { FormattedNumber } from 'react-intl';
<FormattedNumber
value={1200000}
notation="scientific"
/>
Результат будет аналогичен Intl.NumberFormat, но
управляется через React-компонент и контекст локализации.
FormatJS использует ICU Message syntax, позволяющий задавать формат числа прямо в строках сообщений.
Пример:
const messages = {
value: 'Значение: {val, number, scientific}'
};
Использование:
<FormattedMessage
id="value"
values={{ val: 1200000 }}
/>
В этом случае FormatJS применяет научную нотацию автоматически через
ICU-пресет scientific.
В Intl.NumberFormat существует несколько режимов,
которые часто путаются.
Представление числа в виде:
a × 10^n, где 1 ≤ a < 10
Пример:
1200000 → 1.2E6
Используется для UI, где важна краткость:
new Intl.NumberFormat('en-US', {
notation: 'compact'
}).format(1200000);
// "1.2M"
В инженерной нотации степень всегда кратна трём:
new Intl.NumberFormat('en-US', {
notation: 'engineering'
}).format(1200000);
// "1.2E6"
Научная нотация используется в системах, где требуется точное представление масштабов:
FormatJS обеспечивает единый слой локализации, позволяющий использовать одинаковую логику в разных интерфейсах без ручного форматирования.
При использовании научной нотации важную роль играет параметр
maximumSignificantDigits:
new Intl.NumberFormat('en-US', {
notation: 'scientific',
maximumSignificantDigits: 4
}).format(1234567);
// "1.235E6"
Форматирование округляет коэффициент, сохраняя значащие цифры.
Дополнительные параметры:
minimumSignificantDigitsminimumFractionDigitsmaximumFractionDigitsИх поведение в научной нотации влияет на коэффициент, а не на экспоненту.
Отрицательные значения сохраняют знак:
new Intl.NumberFormat('en-US', {
notation: 'scientific'
}).format(-1200000);
// "-1.2E6"
Ноль остаётся нулём:
"0E0"
При этом некоторые реализации локализуют вывод как 0,
если экспонента не имеет смысла в текущем контексте форматирования.
Поведение scientific зависит от движка Jav * aScript:
FormatJS абстрагирует эти различия, но результаты форматирования могут незначительно отличаться между платформами.
react-intl позволяет комбинировать форматирование с
кастомными стилями через render-props:
<FormattedNumber value={1200000} notation="scientific">
{(formatted) => (
<span className="number">{formatted}</span>
)}
</FormattedNumber>
Это полезно для сложных UI, где требуется отдельное управление стилем числа.
В разных культурах различаются:
Пример:
new Intl.NumberFormat('fr-FR', {
notation: 'scientific'
}).format(1200000);
// "1,2E6"
В некоторых локалях возможны альтернативные обозначения экспоненты,
но ICU стремится к унификации через E.
Несмотря на универсальность, существуют ограничения:
Для нестандартных представлений требуется ручное форматирование через пользовательские функции.
FormatJS поддерживает переключение между режимами:
standard — обычное числоcompact — краткие суффиксыscientific — экспоненциальная формаengineering — инженерная шкалаКомбинирование этих режимов позволяет адаптировать интерфейс под контекст отображения данных без изменения бизнес-логики.
ICU MessageFormat позволяет динамически переключать формат:
const messages = {
metric: '{value, number, scientific}'
};
Или с параметрическим управлением:
<FormattedMessage
id="metric"
values={{ value: 0.00000042 }}
/>
Результат автоматически приводится к экспоненциальному виду в зависимости от локали.
Intl.NumberFormat и FormatJS используют кэширование
форматтеров. Это снижает накладные расходы при массовом рендеринге
списков чисел.
Рекомендованный подход:
useIntl() и мемоизации в ReactIntl.NumberFormat на каждом
рендереНаучная нотация особенно полезна при отображении:
FormatJS позволяет унифицировать представление таких данных между интерфейсами, сохраняя локализацию и читаемость.
При переходе к научной нотации происходит нормализация числа:
Это важно учитывать при отображении финансовых или научных данных, где требуется контроль погрешности.
FormatJS поддерживает SSR через react-intl, что
позволяет:
Научная нотация сохраняет консистентность между серверной и клиентской генерацией, если используется одинаковая ICU-версия.