0Pricing
JavaScript Academy · Урок

Практические сценарии применения Proxy

Создавайте объекты для проверки данных, logging и реактивности.

«Практические сценарии применения Proxy» — бесплатный урок JavaScript Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения JavaScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс JavaScript Academy содержит 4 уроков всего.

Прокси на практике

Теперь вы объедините прокси и Reflect, чтобы решать реальные задачи: проверку, журналирование, значения по умолчанию и другие. Каждый шаблон оборачивает обычный объект, не изменяя его.

Обёртка для проверки

Обеспечьте соблюдение схемы: отклоняйте любую запись, не соответствующую rule. target остаётся чистым, потому что некорректные данные никогда в него не попадают.

function validated(obj, rules) {
  return new Proxy(obj, {
    set(target, prop, value, receiver) {
      const rule = rules[prop];
      if (rule && !rule(value)) {
        throw new TypeError('invalid value for ' + prop);
      }
      return Reflect.set(target, prop, value, receiver);
    }
  });
}

const user = validated({}, { age: v => v >= 0 });
user.age = 25;
console.log(user.age);
try { user.age = -1; } catch (e) { console.log(e.message); }

Обёртка для журналирования

Отслеживайте каждое чтение и запись для отладки: после журналирования передавайте операцию через Reflect.

function logged(obj) {
  return new Proxy(obj, {
    get(t, p, r) { console.log('GET ' + p); return Reflect.get(t, p, r); },
    set(t, p, v, r) { console.log('SET ' + p + '=' + v); return Reflect.set(t, p, v, r); }
  });
}

const data = logged({ count: 0 });
data.count = 5;
console.log(data.count);

Значения по умолчанию

Возвращайте резервное значение (fallback) для любого отсутствующего свойства, чтобы чтение никогда не давало undefined.

function withDefault(obj, fallback) {
  return new Proxy(obj, {
    get(t, p, r) {
      return p in t ? Reflect.get(t, p, r) : fallback;
    }
  });
}

const scores = withDefault({ ada: 90 }, 0);
console.log(scores.ada);
console.log(scores.unknown);

Отрицательная индексация массивов

Добавьте массивам поддержку отрицательных индексов в стиле Python, преобразуя их в перехватчике get.

function negIndex(arr) {
  return new Proxy(arr, {
    get(t, p, r) {
      const i = Number(p);
      if (Number.isInteger(i) && i < 0) {
        return Reflect.get(t, t.length + i, r);
      }
      return Reflect.get(t, p, r);
    }
  });
}

const list = negIndex(['a', 'b', 'c']);
console.log(list[-1]);
console.log(list[0]);

Представление только для чтения

Предоставляйте объект, который можно читать, но нельзя изменять; это полезно для защиты общей конфигурации config.

function readonly(obj) {
  return new Proxy(obj, {
    set() { console.log('blocked write'); return false; },
    deleteProperty() { console.log('blocked delete'); return false; }
  });
}

const config = readonly({ apiUrl: '/api' });
config.apiUrl = '/hacked';
console.log(config.apiUrl);

Подсчёт обращений

Отслеживайте, сколько раз читается каждое свойство, сохраняя counts вне target.

function counted(obj) {
  const counts = {};
  const proxy = new Proxy(obj, {
    get(t, p, r) {
      counts[p] = (counts[p] || 0) + 1;
      return Reflect.get(t, p, r);
    }
  });
  return { proxy, counts };
}

const { proxy, counts } = counted({ x: 1 });
proxy.x; proxy.x; proxy.x;
console.log(counts.x);

Вычисляемые виртуальные свойства

Предоставляйте производные значения, которые не хранятся в объекте, а заново вычисляются при каждом чтении.

const rect = new Proxy({ width: 4, height: 3 }, {
  get(t, p, r) {
    if (p === 'area') return t.width * t.height;
    return Reflect.get(t, p, r);
  }
});

console.log(rect.area);
rect.width = 10;
console.log(rect.area);

Ошибка при чтении неизвестных свойств

Выявляйте опечатки на раннем этапе, выдавая ошибку, когда код читает несуществующее свойство.

function strict(obj) {
  return new Proxy(obj, {
    get(t, p, r) {
      if (typeof p === 'string' && !(p in t)) {
        throw new ReferenceError('unknown property: ' + p);
      }
      return Reflect.get(t, p, r);
    }
  });
}

const o = strict({ name: 'Ada' });
console.log(o.name);
try { console.log(o.naem); } catch (e) { console.log(e.message); }

Объединение аспектов

Настоящие обёртки часто объединяют проверку и журналирование в одном обработчике, а каждый перехватчик передаёт операцию через Reflect.

const account = new Proxy({ balance: 0 }, {
  set(t, p, v, r) {
    if (p === 'balance' && v < 0) throw new RangeError('no overdraft');
    console.log(p + ' set to ' + v);
    return Reflect.set(t, p, v, r);
  }
});

account.balance = 100;
console.log(account.balance);
try { account.balance = -50; } catch (e) { console.log(e.message); }

Почему важны эти шаблоны

Прокси добавляют сквозное поведение, проверку, журналирование, значения по умолчанию и контроль доступа, не засоряя исходный объект или код, который его вызывает. Именно так реактивные фреймворки отслеживают изменения state. Используйте прокси, когда нужен прозрачный перехват.

const observed = new Proxy({ n: 0 }, {
  set(t, p, v, r) {
    const ok = Reflect.set(t, p, v, r);
    console.log(p + ' is now ' + t[p]);
    return ok;
  }
});
observed.n = 1;
observed.n = 2;

Быстрая проверка

Какой перехватчик прокси следует использовать, чтобы отклонить недопустимые значения до их сохранения?

Итоги: практические случаи применения прокси

Вы применили прокси для решения реальных задач:

  • Проверка в перехватчике set отклоняет некорректные данные.
  • Журналирование отслеживает чтение и запись через Reflect.
  • Значения по умолчанию и виртуальные свойства реализуются в перехватчике get.
  • Представления только для чтения, подсчёт обращений и строгая проверка опечаток прозрачно оборачивают объекты.

Часто задаваемые вопросы

Урок «Практические сценарии применения Proxy» бесплатный?

Да — полный текст урока «Практические сценарии применения Proxy» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс JavaScript Academy, подпишись на CoddyKit PRO. Курс JavaScript Academy содержит 4 уроков всего.

Чему я научусь в уроке «Практические сценарии применения Proxy»?

Создавайте объекты для проверки данных, logging и реактивности. Ты практикуешь JavaScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать JavaScript Academy?

Предыдущий опыт не требуется. JavaScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Практические сценарии применения Proxy»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке JavaScript Academy?

Да. Каждый урок JavaScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Создание Proxy
  2. Ловушки get и set
  3. API Reflect
  4. Практические сценарии применения Proxy
← Назад к JavaScript Academy