JavaScript Proxy — перехоплення операцій з об'єктом


Proxy (у перекладі — посередник) обгортає об'єкт і перехоплює операції з ним: читання властивості, запис, видалення, перевірку існування.

автор: NagarD

Загальний опис

Це найпотужніший інструмент метапрограмування в JavaScript. Посередник виглядає ззовні як звичайний об'єкт, але кожне звертання до нього спершу проходить через пастку (trap) — твою функцію.

Пастка get спрацьовує на читанні, set — на записі. Усередині можна робити що завгодно: підставити значення за замовчуванням замість undefined, заборонити запис, залогувати звертання, повідомити інтерфейс, що дані змінились.

Саме на цьому побудована реактивність сучасних фреймворків: ти пишеш state.count++, а фреймворк дізнається про це й перемальовує сторінку — бо між тобою й даними стоїть посередник.

автор: NagarD

Порада

Пастка get — готове рішення для значень за замовчуванням: замість undefined віддавай нуль, порожній рядок чи зрозумілу помилку.

автор: NagarD
Нотатка

Оригінальний об'єкт лишається доступним. Посередник контролює лише свій шлях: хто має посилання на оригінал, обійде всі пастки.

автор: NagarD

Синтаксис

const proxy = new Proxy(target, handler);

методи

Метод Опис
revocable Створює проксі, який можна відкликати — після цього будь-яка операція кидає TypeError.

Переглядачі

Підтримка: стаціонарні переглядачі
Переглядач Google Chrome Mozilla Firefox Apple Safari Opera Microsoft EDGE Microsoft Internet Explorer
Proxy 49+ 18+ 10+ 36+ 12+ -
Підтримка: мобільні переглядачі
Переглядач Mobile Google Android Mobile Google Chrome Mobile Mozilla Firefox Mobile Apple Safari
Proxy 49+ yes yes 10+

Приклади

+ запропонувати свій приклад у пісочниці

Значення за замовчуванням, валідація й найпростіша реактивність.

const withDefault = new Proxy({}, {
    get: (target, key) => key in target ? target[key] : 0,
});

console.log(withDefault.missing); // 0, а не undefined

// валідація на записі
const user = new Proxy({}, {
    set(target, key, value) {
        if (key === 'age' && typeof value !== 'number') {
            throw new TypeError('Вік має бути числом');
        }

        target[key] = value;
        return true;
    },
});

user.age = 30;      // добре
// user.age = 'so';  // TypeError

// реактивність у три рядки
const state = new Proxy({ count: 0 }, {
    set(target, key, value) {
        target[key] = value;
        render();
        return true;
    },
});
автор: NagarD

Коментарі

Коментарів ще немає — будьте першим!

Відповідь для

Увійдіть — коментар з'явиться одразу, без капчі й очікування перевірки.

Пропозиція правки

Ваша версія — : після перевірки замінить чинну. Нова порада чи нотатка — з'явиться на сторінці після перевірки.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія секції «»: після перевірки замінить чинну.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія опису «»: після перевірки замінить чинну.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Зворотний зв'язок
Вхід