> Что такое прокси в JavaScript и как его использовать (JavaScript)
Уровень: junior · Роль: frontend · Категория: Технические вопросы
Компании: Сбер
Стек: JavaScript
> Пример ответа
Короткий ответ
Прокси в JavaScript - это объект-обёртка, который перехватывает операции над другим объектом (target) и позволяет изменить их поведение. Создаётся через new Proxy(target, handler), где handler содержит ловушки (traps) - методы вроде get, set, has. Прокси используется для валидации, логирования, реактивности (как во Vue 3), мемоизации и контроля доступа к свойствам.
Подробное объяснение
Прокси - это механизм метапрограммирования. Он не изменяет сам target, а перехватывает обращения к нему через специальные методы в объекте handler. Каждая ловушка соответствует стандартной операции языка: чтение свойства (get), запись (set), проверка существования (has), удаление (deleteProperty), вызов функции (apply) и другие.
Ключевые особенности:
- Прокси не копирует target - он работает как прослойка, поэтому изменения через прокси отражаются на оригинале и наоборот.
- Ловушки могут возвращать произвольные значения, что позволяет полностью контролировать поведение.
- Существуют "инварианты" - ограничения, которые нельзя нарушить (например, нельзя вернуть несуществующее значение для неперечисляемого свойства).
- Прокси можно использовать для создания "виртуальных" свойств, которых нет в target.
Отличие от Object.defineProperty: прокси перехватывает любые операции, включая обращение к несуществующим свойствам, а defineProperty работает только с конкретными свойствами.
На практике
Основные сценарии использования:
- Валидация данных при записи - проверка типов и значений в
set. - Логирование доступа - отслеживание, какие свойства читаются и изменяются.
- Реактивность - автоматическое обновление UI при изменении данных (используется в Vue 3).
- Мемоизация - кэширование результатов вычислений для одинаковых аргументов.
- Защита от изменений - запрет на удаление или переопределение свойств.
- Создание "умных" объектов - например, автоматическое создание вложенных объектов при обращении к несуществующему свойству.
Важно помнить, что прокси работает только при обращении через сам прокси. Если где-то в коде используется оригинальный объект, ловушки не сработают.
Пример кода
JAVASCRIPTconst target = { name: 'Alice', age: 30 };const handler = {get(obj, prop) {if (prop === 'age') {return obj[prop] + ' лет';}return obj[prop];},set(obj, prop, value) {if (prop === 'age' && typeof value !== 'number') {throw new TypeError('Возраст должен быть числом');}obj[prop] = value;return true; // обязательно вернуть true для успешной записи}};const proxy = new Proxy(target, handler);console.log(proxy.age); // "30 лет"proxy.age = 35; // работает// proxy.age = 'old'; // TypeError// Реактивность на практикеconst reactive = new Proxy({ count: 0 }, {set(obj, prop, value) {obj[prop] = value;console.log(`Свойство ${prop} изменено на ${value}`);return true;}});reactive.count = 5; // "Свойство count изменено на 5"
Как отвечать на собеседовании
Начни с определения и синтаксиса. Затем приведи 2-3 примера использования - валидация, логирование, реактивность. Обязательно упомяни, что прокси не изменяет оригинальный объект, а перехватывает операции. Если спросят про производительность - честно скажи, что прокси медленнее прямого доступа, поэтому не стоит оборачивать горячие участки кода. Хорошо показать понимание Reflect - он используется внутри ловушек для вызова стандартного поведения.
Что проверяет интервьюер
- Понимание синтаксиса
new Proxy(target, handler). - Знание основных ловушек:
get,set,has,deleteProperty,apply. - Понимание, что прокси - это прослойка, а не копия.
- Умение объяснить практический кейс (например, реактивность).
- Осознание ограничений и инвариантов прокси.
Типичные ошибки
- Забыть вернуть
trueизset- без этого запись не сработает. - Пытаться использовать прокси для примитивов - они не являются объектами.
- Оборачивать прокси в прокси без необходимости - это усложняет отладку.
- Путать прокси с
Object.defineProperty- это разные механизмы. - Думать, что прокси работает для всех обращений к объекту - только через сам прокси.
- Игнорировать
Reflect- без него сложно сохранить стандартное поведение.
> Похожие задачи по frontend
Как устроены стек вызовов и куча в JavaScript
В чем разница между двойным (==) и тройным (===) равенством в JavaScript?
Какие данные можно мутировать в JavaScript, а какие нет
Какие проблемы решаются с помощью статических методов Promise в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью