Массивы JavaScript - это коллекции элементов, каждый из которых доступен через индекс. Эти индексы являются неотрицательными целыми числами, и доступ к отрицательному индексу просто вернет undefined
.
// JavaScript: const letters = ['a', 'b', 'c', 'd', 'e']; letters[0]; // => 'a' letters[2]; // => 'c' letters[-1]; // => undefined
В других языках программирования, например Python, мы можем использовать отрицательные индексы для доступа к элементам с конца массива:
# Python: letters = ['a', 'b', 'c', 'd', 'e']; letters[0]; // => 'a' letters[-1]; // => 'e'
По умолчанию такое поведение недоступно для JavaScript. Вместо этого мы должны написать подробный код, чтобы получить последний элемент массива, например:
// JavaScript: const letters = ['a', 'b', 'c', 'd', 'e']; letters[letters.length - 1]; // => 'e'
К счастью, с помощью прокси мы можем поддерживать доступ к элементам нашего массива, начиная с конца, с использованием отрицательных индексов.
Что такое прокси?
Прокси - это объект, который по сути является оболочкой для любого другого объекта (называемого целью). Любые взаимодействия, выполняемые на прокси-сервере, по умолчанию перенаправляются на цель, как если бы мы все еще взаимодействовали напрямую с целью.
Однако сила прокси-серверов заключается в способности определять ловушки. Ловушки - это методы, которые фиксируют операции с прокси-объектом (такие как установка / получение значений свойств, удаление свойства и т. Д.) И позволяют нам определять настраиваемое поведение для этих операций.
Создание прокси
Мы можем создать прокси-объект с помощью конструктора Proxy:
const proxy = new Proxy(letters, {});
Он принимает целевой объект для переноса и объект, определяющий ловушки, поведение которых мы хотим настроить. В приведенном выше примере мы еще не определяем никаких ловушек, поэтому любые операции на прокси будут просто перенаправлены на целевой объект.
Определение нашей первой ловушки
При доступе к элементу массива с использованием отрицательного индекса, такого как proxy[-1]
, мы пытаемся «получить» свойство с именем «-1
» в нашем целевом массиве. По умолчанию это просто возвращает undefined
. Но поскольку мы уже обернули этот массив в прокси-объект, теперь мы можем определить ловушку get
для настройки поведения «получить свойство».
const proxy = new Proxy(letters, { get(target, prop) { return target[prop]; } });
В метод get
trap передается целевой объект и свойство, к которому мы пытаемся получить доступ. Какое бы значение мы ни возвращали из этого метода, оно становится значением, возвращаемым тому, кто пытался получить к нему доступ.
Обработка отрицательных индексов массива
Имея наш прокси-объект и ловушку get
, теперь мы можем продолжить возврат элементов из конца целевого массива при доступе к отрицательным индексам.
const proxy = new Proxy(letters, { get(target, prop) { if (!isNaN(prop)) { prop = parseInt(prop, 10); if (prop < 0) { prop += target.length; } } return target[prop]; } });
Здесь мы проверяем, является ли свойство, к которому мы пытаемся получить доступ, числом (кстати, числовые имена свойств, такие как индексы массивов, преобразуются в строки при передаче в ловушку get
) и является ли оно отрицательным. Если да, мы преобразуем его в допустимое значение индекса массива и возвращаем элемент массива по этому вычисленному индексу. После этого мы теперь можем использовать отрицательные индексы для проксируемых массивов:
const letters = ['a', 'b', 'c', 'd', 'e']; const proxy = new Proxy(letters, { get(target, prop) { if (!isNaN(prop)) { prop = parseInt(prop, 10); if (prop < 0) { prop += target.length; } } return target[prop]; } }); proxy[0]; // => 'a' proxy[-1]; // => 'e' proxy[-2]; // => 'd'
Что дальше?
В этой статье мы едва коснулись того, на что способны прокси JavaScript. Мы рассмотрели ловушку get
, которая позволяет нам настраивать поведение при получении свойства из проксируемого объекта.
Прокси-серверы поддерживают множество других ловушек, таких как установка или удаление свойства, проверка существования свойства, вызов цели в качестве конструктора и т. Д. Ознакомьтесь с его документацией на MDN, чтобы узнать о них больше.
Прокси-серверы - это действительно мощная функция, которая позволяет нам писать код, который раньше было бы невозможно или очень сложно выполнить. Я с нетерпением жду других вариантов использования этой функции.
Недавно мы начали небольшой побочный проект под названием rbjs, который пытается реализовать методы массива Ruby в JavaScript. Под капотом мы используем прокси для дополнения массивов JS дополнительными методами без изменения его прототипа. Мы действительно просто ищем повод использовать прокси для чего-то 😆. Пожалуйста, проверьте это и не стесняйтесь вносить свой вклад, спасибо!
Спасибо, что прочитали эту статью! Не стесняйтесь оставлять свои комментарии и дайте нам знать, что вы думаете. Мы - группа разработчиков, которые любят создавать случайные вещи и иногда писать о технологиях. Ознакомьтесь с нашими другими статьями и некоторыми нашими проектами. Хорошего дня! ❤️