Что такое прокси в JavaScript и как его использовать
Что проверяют
Знаете ли вы не синтаксис, а границу применимости. Proxy перехватывает операции с объектом на уровне языка, и за это приходится платить скоростью и предсказуемостью. Вопрос часто идёт от реактивности: понимаете ли вы, на чём устроены современные хранилища состояния, и отличаете ли перехват от обычной обёртки с геттерами.
Как отвечать
Proxy встаёт перед целевым объектом и перехватывает базовые операции: чтение и запись свойства, проверку через in, удаление, перечисление ключей, вызов функции, создание через new. Поведение задаётся ловушками в объекте-обработчике.
const logged = new Proxy(target, {
get(t, key, receiver) {
console.log("read", key);
return Reflect.get(t, key, receiver);
},
set(t, key, value, receiver) {
return Reflect.set(t, key, value, receiver);
},
});Обратите внимание на Reflect: он даёт поведение по умолчанию и, главное, передаёт получателя, поэтому геттеры и наследование работают как без прокси.
Где приём уместен: отслеживание чтений и записей для реактивности, валидация присваиваемых значений, подстановка значений по умолчанию для отсутствующих ключей, заглушки и шпионы в тестах, ленивое создание тяжёлого объекта, временный доступ через Proxy.revocable, который потом отзывается.
Где спотыкаются
Пишут в ловушке target[key] вместо Reflect.get с получателем. На плоском объекте разницы нет, а на геттере из прототипа или на классе с наследованием значение внезапно считается мимо прокси.
Забывают вернуть из ловушки set признак успеха. Молчаливый undefined в строгом режиме и в модулях превращает обычное присваивание в TypeError, и падает оно далеко от места, где создавали прокси.
Ждут, что прокси перехватит вообще всё. Вложенные объекты приходят неперехваченными, и оборачивать их надо на лету. У Map, Set, Date и приватных полей класса методы требуют внутренних слотов самого объекта и на прокси падают. Инварианты неконфигурируемых свойств не дают ловушке соврать. И по ссылке прокси не равен цели, поэтому поиск по идентичности в коллекциях ломается.