Реализация Array.prototype.toLocaleString

Вопрос или проблема

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

Оцените материал
Добавить комментарий

Капча загружается...