Рассмотрение практических примеров использования метапрограммирования


JavaScript - довольно гибкий язык. Это слабо типизированный и динамичный по своей природе. Вы, наверное, уже знаете, что его первая версия - тогда известная как Mocha - была создана всего за 10 дней. Такая гибкость означала, что разработчики могли легко расширить ее для удовлетворения своих индивидуальных сценариев использования.
Благодаря Proxy API эта гибкость выводится на новый уровень. Вы можете подключиться к мета-уровню, чтобы изменить поведение самого JavaScript.
Что такое метапрограммирование?
Метапрограммирование может означать несколько вещей. Но в контексте Proxy API это означает, что программа может изменять себя во время выполнения.
С помощью Proxy API у вас есть возможность переопределить семантику и поведение основных операций, таких как поиск или присвоение свойств. Это все, что представляет собой Proxy API. Итак, как это работает?
Это ловушка
Прокси-серверы используют так называемые «ловушки» для придания операциям индивидуального поведения. Это методы, которые перехватывают операцию, точно так же, как прокси-сервер перехватывает сетевой запрос. Давайте рассмотрим несколько примеров, чтобы увидеть, как они работают.

Получение значений
Во-первых, давайте посмотрим, как мы можем перехватить поиск свойства и обеспечить настраиваемое поведение, когда мы пытаемся прочитать свойство.
По умолчанию пользовательские значения
Представьте, что вы хотите построить свою логику на возврате пустого объекта, если одно из ваших свойств не определено. Вы не хотите использовать undefined, вам нужно иметь запасное значение. В данном случае это пустой {}. Сделать это можно следующим образом:
Мы присваиваем man new Proxy. Прокси-сервер принимает два аргумента:
- Цель: первый аргумент - это целевой объект, который мы хотим превратить в прокси. Это может быть даже массив, функция или другой прокси. Здесь мы используем пустой объект.
- Обработчик: второй аргумент - это объект, у которого есть предопределенные методы. Мы можем использовать эти методы для определения индивидуального поведения операций. Их называют ловушками. Ловушка
getиспользуется для получения значений свойств.
В этом примере мы просто проверяем, существует ли свойство у объекта. Если нет, мы возвращаемся с пустым объектом.

Если вы запросите это в консоли, вы увидите, что man является прокси. Всякий раз, когда я пытаюсь получить доступ к несуществующему свойству, он возвращает пустой объект.
Чтобы сделать вещи более удобочитаемыми, мы можем передать этот вызов функции. Таким образом, мы можем повторно использовать его позже, когда он нам понадобится.
Если мы заключим объект в эту функцию, он вернет прокси с новой функциональностью. Это также скрывает основную логику и делает вещи более удобочитаемыми. Намерение ясно передано.

Оповещение
Давайте посмотрим на более практический пример. Теперь вы хотите знать, когда ваши свойства не определены. С его помощью вы можете установить оповещения.
Вызывая это с тем же объектом, что и раньше, вы получите сообщение об ошибке, выходящее из консоли при каждой ссылке на свойство, которое не определено. Это упрощает выявление потенциальных проблем в вашем приложении.

Умные массивы
Мы также можем улучшить поиск в массиве, реализовав настраиваемую логику для ловушки получения.
Эта ловушка получит исходное значение - с помощью Reflect API - если индекс является положительным числом. Однако, если мы передадим отрицательное число, мы сможем получить значения из конца массива.

Мы можем дополнительно улучшить это, чтобы также поддерживать интервалы.
Смарт-объекты
То же самое можно сделать и с объектами. Допустим, вы хотите получить доступ к глубоко вложенному свойству без необходимости записывать полный путь. Вы знаете только название объекта и свойство, которое ищете. Мы можем сделать это с помощью рекурсивной функции.
Теперь вы можете обращаться к свойствам, как если бы они существовали на верхнем уровне. Вопрос в том, а должны ли вы?
Значения настроек
Подобно тому, как ловушка get может использоваться для перехвата поиска свойств, ловушка set может использоваться для присвоений. Все осталось по-прежнему, за исключением того, что нам нужно использовать set вместо get. Давайте посмотрим.
Проверка свойств
Самый распространенный случай - проверка свойств. Давайте создадим валидатор, который проверяет объект пользователя.
В отличие от ловушки get, set имеет три параметра. Один для объекта, один для свойства и один для его значения. Как видите, нам всегда нужно что-то возвращать.
Если некоторая проверка не удалась, мы возвращаем false. Это предотвратит установку свойства. В конце мы можем использовать Reflect API, чтобы установить значение, если проверка прошла успешно.

Как видите, значение не будет установлено, если адрес электронной почты недействителен. То же самое и с возрастом.
Сделать свойства доступными только для чтения
Мы также можем использовать ловушку для создания свойств только для чтения. Таким образом, вы можете быть уверены, что никто не сможет их изменить.
Здесь мы использовали функцию, единственная цель которой - записать ошибку в консоль. Прокси-сервер не только предотвращает назначения, но и удаление или любое расширение.

Вы также можете ввести некоторую настраиваемую логику, чтобы сделать только выбранное количество свойств доступным только для чтения.
Преобразование строк в числа
Другой вариант использования - автоматическое преобразование строк в числа. Это можно сделать с помощью магии регулярных выражений.
Все, что нам нужно, это оператор if, чтобы переназначить значение, если оно содержит только числа. Теперь всякий раз, когда вы присваиваете значение, которое является строкой, но содержит только числа, прокси преобразует его для нас.

Заключение
Теперь у вас должна быть довольно прочная основа для Proxy API в JavaScript. Как только вы освоитесь, это может стать довольно мощным инструментом для улучшения ваших повседневных операций.
Знаете ли вы другие варианты использования, для которых можно использовать Proxy API и которые не упоминаются в этом руководстве? Дайте нам знать об этом в комментариях! Спасибо, что нашли время прочитать эту статью, удачного кодирования!

