Вопрос или проблема
Меня интересует следующий фрагмент кода на JS:
const array = [1,2,3];
const locales="en-US";
const options = null;
console.log(array.toLocaleString(locales,options));
Перед Node.js 20 этот код выводил 1,2,3. Однако в Node.js 20 теперь возникает следующая ошибка:
Uncaught TypeError: Number.prototype.toLocaleString called on null or undefined
at Number.toLocaleString (<anonymous>)
at Array.toLocaleString (<anonymous>)
Я пытаюсь понять, что изменилось в реализации. В частности, меня интересует точная строка кода, которая была изменена в исходном коде. Я изучил спецификацию языка ECMAScript, но не смог найти связанных изменений. Мое внимание сосредоточено на выявлении того, где код изменился в реализации, а не на понимании причин этого. Пожалуйста, укажите мне правильное направление.
Причина этого вопроса заключается в том, что у меня есть библиотека, которая ввела новую структуру данных и предоставляет аналогичные методы, как array
. Я хочу, чтобы мои структуры данных и массив давали одинаковые результаты для любого типа входных данных, включая null
. Как только я заметил, что между версиями toLocaleString
дает другой результат, я понял, что мне нужно обновить свой собственный toLocaleString
, чтобы поддержать последние изменения. Для этого я пытаюсь выяснить точное изменение, чтобы взглянуть на него собственными глазами.
Ошибка также возникает в современных браузерах Chrome. Параметр options
ожидается как object|undefined
. Передача null
в необязательный объектный параметр не является законной.
Я полагаю, что V8 отказывается от null
, рассматриваемого как undefined
, поскольку это плохо работает с языком TypeScript.
Аргумент
В приведенном ниже коде TypeScript вы можете увидеть ошибку TS2345. В TypeScript необязательный аргумент ?
рассматривается как этот тип или undefined
.
const aNumber: number = 42;
aNumber.toLocaleString('en', null);
// ----
// ^
// | Аргумент типа 'null' не может быть присвоен
// | параметру типа
// | 'NumberFormatOptions | undefined'.
// | (2345)
Вот сигнатура типа TypeScript для метода Number.prototype.toLocaleString
для справки:
(method) Number.toLocaleString(
locales?: string | string[],
options?: Intl.NumberFormatOptions
): string
Ответ или решение
В ваше внимание заслуживает изменения, произошедшие в реализации метода Array.prototype.toLocaleString
в Node.js 20 и современных браузерах, таких как Chrome. Давайте разберемся шаг за шагом:
Изменения в реализации
В предыдущих версиях JavaScript и Node.js метод toLocaleString
не выбрасывал исключение при передаче null
в качестве аргумента для параметра options
. Тем не менее, начиная с Node.js 20, была внесена поправка, которая строго проверяет входные параметры.
Теперь вызов array.toLocaleString(locales, options)
с options
равным null
приведет к следующему исключению:
Uncaught TypeError: Number.prototype.toLocaleString called on null or undefined
Это связано с тем, что метод toLocaleString
для объектов типа Number
ожидает, что параметр options
будет либо объектом, либо undefined
. Передача null
теперь считается ошибочной, что согласуется с строгими стандартами TypeScript и правилами типов.
Поиск изменений в исходном коде
Чтобы определить, где именно произошли изменения в исходном коде V8 (мотора JavaScript, который используется в Node.js), вам нужно будет просмотреть репозиторий V8 на GitHub. К сожалению, точную строку кода сложно указать без доступа к репозиторию, но вы можете выполнить поиск по ключевым словам, таким как toLocaleString
и null
, чтобы увидеть, какие изменения могли быть внесены.
Обновление вашей библиотеки
В связи с последними изменениями, рекомендую вам обновить реализацию вашего аналогичного метода toLocaleString
в собственных структурах данных, чтобы отлавливать null
в аргументе options
и предотвращать потенциальные ошибки. Например, вы можете реализовать проверку:
function customToLocaleString(locales, options) {
if (options === null) {
options = undefined; // Преобразование null в undefined
}
// Дальнейшая логика...
}
Таким образом, ваша реализация будет совместима с последними изменениями в стандартной библиотеке JavaScript и не вызовет ошибок.
Заключение
С переходом к строгой типизации и улучшению обработки параметров, таких как в toLocaleString
, в новых версиях JavaScript, неизбежно будут возникать изменения, влияющие на совместимость с существующими библиотеками. Поэтому важно быть в курсе этих изменений и адаптировать собственные методы для обеспечения корректной работы.