πŸ”§ Proxy Π² JavaScript ΠΈ TypeScript: 7 способов использования

ΠžΠ±ΡŠΠ΅ΠΊΡ‚ Proxy Π² JavaScript/TypeScript – супСрполСзный инструмСнт, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ мноТСство возмоТностСй для управлСния ΠΈ манипуляции ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ ΠΈ функциями. Рассмотрим нСсколько практичСских ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² использования Proxy для ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ, логирования, динамичСской Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ ΠΈ Π²Ρ‹Π·ΠΎΠ²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΎΠΉ.

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Proxy Π² JavaScript

Proxy Π² JavaScript β€” ΠΌΠΎΡ‰Π½Ρ‹ΠΉ инструмСнт, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ±Π΅Ρ€Ρ‚ΠΊΡƒ Π²ΠΎΠΊΡ€ΡƒΠ³ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈΠ»ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹Ρ… Ρ†Π΅Π»Π΅Π²Ρ‹ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ). Π­Ρ‚Π° ΠΎΠ±Π΅Ρ€Ρ‚ΠΊΠ° Π΄Π°Π΅Ρ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ, ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с этим ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ², Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹Ρ… Π»ΠΎΠ²ΡƒΡˆΠΊΠ°ΠΌΠΈ (traps). Π›ΠΎΠ²ΡƒΡˆΠΊΠΈ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ собой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚, ΠΊΠ°ΠΊ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒΡΡ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ β€” Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ свойств, запись Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅.

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρƒ нас Π΅ΡΡ‚ΡŒ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:

let user = {
  name: "Иван",
  age: 30
};

Когда ΠΌΡ‹ обращаСмся ΠΊ свойствам этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈΠ»ΠΈ измСняСм ΠΈΡ…, это происходит Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ. Но Ρ‡Ρ‚ΠΎ, Ссли ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΡƒΡŽ-Ρ‚ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Π»ΠΎΠ³ΠΈΠΊΡƒ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΈΠ»ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ? Π—Π΄Π΅ΡΡŒ Π½Π° ΠΏΠΎΠΌΠΎΡ‰ΡŒ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ Proxy.

Proxy позволяСт Π½Π°ΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ посрСдника ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠΎΠ΄ΠΎΠΌ ΠΈ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ. Π­Ρ‚ΠΎΡ‚ посрСдник ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ:

  • Π§Ρ‚Π΅Π½ΠΈΠ΅ свойств ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
  • Π—Π°ΠΏΠΈΡΡŒ Π½ΠΎΠ²Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² свойства.
  • Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ свойств.
  • ΠŸΠ΅Ρ€Π΅Π±ΠΎΡ€ свойств ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
  • Π’Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ (Ссли ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ являСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ).

ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования Proxy с JavaScript выглядит Ρ‚Π°ΠΊ:

let user = {
  name: "Иван",
  age: 30
};

let userProxy = new Proxy(user, {
  get(target, property) {
    console.log(`ΠšΡ‚ΠΎ-Ρ‚ΠΎ пытаСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ свойство ${property}`);
    return target[property];
  },
  set(target, property, value) {
    console.log(`ΠšΡ‚ΠΎ-Ρ‚ΠΎ пытаСтся ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ свойство ${property} Π½Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ${value}`);
    target[property] = value;
    return true;
  }
});

console.log(userProxy.name); // Π’Ρ‹Π²Π΅Π΄Π΅Ρ‚: "ΠšΡ‚ΠΎ-Ρ‚ΠΎ пытаСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ свойство name" ΠΈ Π·Π°Ρ‚Π΅ΠΌ "Иван"
userProxy.age = 31; // Π’Ρ‹Π²Π΅Π΄Π΅Ρ‚: "ΠšΡ‚ΠΎ-Ρ‚ΠΎ пытаСтся ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ свойство age Π½Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 31"

А Ρ‚Π°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ этот ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π½Π° TypeScript:

interface User {
  name: string;
  age: number;
}

const user: User = {
  name: "Иван",
  age: 30
};

const userProxy = new Proxy<User>(user, {
  get(target: User, property: keyof User): any {
    console.log(`ΠšΡ‚ΠΎ-Ρ‚ΠΎ пытаСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ свойство ${String(property)}`);
    return target[property];
  },
  set(target: User, property: keyof User, value: any): boolean {
    console.log(`ΠšΡ‚ΠΎ-Ρ‚ΠΎ пытаСтся ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ свойство ${String(property)} Π½Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ${value}`);
    (target as any)[property] = value;
    return true;
  }
});

console.log(userProxy.name); // Π’Ρ‹Π²Π΅Π΄Π΅Ρ‚: "ΠšΡ‚ΠΎ-Ρ‚ΠΎ пытаСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ свойство name" ΠΈ Π·Π°Ρ‚Π΅ΠΌ "Иван"
userProxy.age = 31; // Π’Ρ‹Π²Π΅Π΄Π΅Ρ‚: "ΠšΡ‚ΠΎ-Ρ‚ΠΎ пытаСтся ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ свойство age Π½Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 31"

Для Ρ‡Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Proxy

Proxy прСдоставляСт ΠΌΠΎΡ‰Π½Ρ‹ΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ для управлСния ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π½Π° Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅. Π’ΠΎΡ‚ нСсколько основных случаСв использования:

  • Валидация β€” ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Proxy для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅Π΄ ΠΈΡ… присвоСниСм свойствам ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
  • ЛСнивая Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° β€” Proxy позволяСт ΠΎΡ‚ΡΡ€ΠΎΡ‡ΠΈΡ‚ΡŒ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Π΄Π°Π½Π½Ρ‹Ρ… Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½ΡƒΠΆΠ½Ρ‹.
  • ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок β€” ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ, ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΡ… ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.
  • Π›ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ β€” Proxy ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Π»Π΅Π³ΠΊΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ всСх ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Π±Π΅Π· измСнСния самого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
  • ΠŸΡ€ΠΎΠΊΡΠΈ-сСрвСры ΠΈ API β€” Proxy слуТит для создания ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹Ρ… прокси-сСрвСров ΠΈΠ»ΠΈ API, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ запросов ΠΈ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ².

Рассмотрим нСсколько ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅.

πŸ‘¨β€πŸ’»πŸŽ¨ Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄Π΅Ρ€Π°
Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄Π΅Ρ€Π°Β»

АвтозаполнСниС свойств

Proxy ΠΌΠΎΠΆΠ΅Ρ‚ динамичСски Π·Π°ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ свойства ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΡ€ΠΈ доступС ΠΊ Π½ΠΈΠΌ β€” Ρ‚Π°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΠΏΠΎ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΡŽ ΠΈΠ»ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ слоТных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Ρƒ нас Π΅ΡΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ профиля ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ с ΠΈΠΌΠ΅Π½Π΅ΠΌ, Ρ„Π°ΠΌΠΈΠ»ΠΈΠ΅ΠΉ ΠΈ ΠΏΠΎΠ»Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ гСнСрируСтся автоматичСски ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ Π½Π΅ΠΌΡƒ:

TypeScript
type LazyProfile = {
    firstName: string;
    lastName: string;
    fullName?: string;
};

let lazyProfileHandler: ProxyHandler<LazyProfile> = {
    get: (target: LazyProfile, property: keyof LazyProfile) => {
        if (property === "fullName" && !target[property]) {
            target[property] = `${target.firstName} ${target.lastName}`;
        }
        return target[property];
    }
};

let profile = new Proxy<LazyProfile>({ firstName: "АндрСй", lastName: "Болконский" }, lazyProfileHandler);
console.log(profile.fullName);  // Π’Ρ‹Π²ΠΎΠ΄: АндрСй Болконский
JavaScript
const lazyProfileHandler = {
    get: (target, property) => {
        if (property === "fullName" && !target[property]) {
            target[property] = `${target.firstName} ${target.lastName}`;
        }
        return target[property];
    }
};

const profile = new Proxy({ firstName: "АндрСй", lastName: "Болконский" }, lazyProfileHandler);
console.log(profile.fullName);  // Π’Ρ‹Π²ΠΎΠ΄: АндрСй Болконский

ΠŸΠΎΠ΄ΡΡ‡Π΅Ρ‚ количСства ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Proxy подсчитываСтся число ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ чтСния свойств ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° β€” Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ, ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π° ΠΈΠ»ΠΈ тСстирования ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ прилоТСния:

TypeScript
type Counter = {
    [key: string]: any;
    _getCount: number;
};

let countHandler: ProxyHandler<Counter> = {
    get: (target: Counter, property: string | symbol, receiver: any) => {
        if (property === "_getCount") {
            return target[property];
        }
        target._getCount++;
        return Reflect.get(target, property, receiver);
    }
};

let counter: Counter = new Proxy({ a: 1, b: 2, _getCount: 0 }, countHandler);
counter.a;
counter.b;
console.log(counter._getCount);  // Π’Ρ‹Π²ΠΎΠ΄: 2
JavaScript
const countHandler = {
    get: (target, property, receiver) => {
        if (property === "_getCount") {
            return target[property];
        }
        target._getCount++;
        return Reflect.get(target, property, receiver);
    }
};

const counter = new Proxy({ a: 1, b: 2, _getCount: 0 }, countHandler);
counter.a;
counter.b;
console.log(counter._getCount);  // Π’Ρ‹Π²ΠΎΠ΄: 2

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ нСизмСняСмых ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²

Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Proxy ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ нСизмСняСмыС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹: любая ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ свойства Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° послС создания Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ. Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ создаСтся функция createImmutable, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π΅Π³ΠΎ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ:

TypeScript
function createImmutable<T extends object>(obj: T): T {
    return new Proxy(obj, {
        set: (target, property, value) => {
            console.log(`ΠŸΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ свойство '${String(property)}' Π½Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ${value}`);
            console.log("Ошибка: Π­Ρ‚ΠΎΡ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ нСизмСняСм");
            return false; // Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ false, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ опСрация Π½Π΅ ΡƒΠ΄Π°Π»Π°ΡΡŒ
        }
    });
}

const immutableObject = createImmutable({ name: "Иван", age: 30 });

console.log("Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:", immutableObject);

try {
    immutableObject.age = 31;
} catch (error) {
    console.log("ΠŸΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:", error.message);
}

try {
    // @ts-ignore (ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΎΠ±Ρ…ΠΎΠ΄Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ‚ΠΈΠΏΠΎΠ² TypeScript)
    immutableObject.newProperty = "НовоС свойство";
} catch (error) {
    console.log("ΠŸΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:", error.message);
}

console.log("ΠžΠ±ΡŠΠ΅ΠΊΡ‚ послС ΠΏΠΎΠΏΡ‹Ρ‚ΠΎΠΊ измСнСния:", immutableObject);
JavaScript
function createImmutable(obj) {
    return new Proxy(obj, {
        set: (target, property, value) => {
            console.log(`ΠŸΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ свойство '${String(property)}' Π½Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ${value}`);
            console.log("Ошибка: Π­Ρ‚ΠΎΡ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ нСизмСняСм");
            return false; // Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ false, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ опСрация Π½Π΅ ΡƒΠ΄Π°Π»Π°ΡΡŒ
        }
    });
}

const immutableObject = createImmutable({ name: "Иван", age: 30 });

console.log("Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:", immutableObject);

try {
    immutableObject.age = 31;
} catch (error) {
    console.log("ΠŸΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:", error.message);
}

try {
    immutableObject.newProperty = "НовоС свойство";
} catch (error) {
    console.log("ΠŸΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:", error.message);
}

console.log("ΠžΠ±ΡŠΠ΅ΠΊΡ‚ послС ΠΏΠΎΠΏΡ‹Ρ‚ΠΎΠΊ измСнСния:", immutableObject);

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Ρ‚Π΅ΠΊΡƒΡ‡Π΅Π³ΠΎ интСрфСйса с Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΎΠΉ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²

Π’Π΅ΠΊΡƒΡ‡ΠΈΠΉ интСрфСйс позволяСт Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΎΠΉ:

TypeScript
type FluentPerson = {
    setName(name: string): FluentPerson;
    setAge(age: number): FluentPerson;
    save(): void;
};

function FluentPerson(): FluentPerson {
    let person: any = {};

    const handler = {
        get: (target: any, property: string | symbol) => {
            if (property === "save") {
                return () => { console.log(person); };
            }
            return (value: any) => {
                person[property] = value;
                return proxy;
            };
        }
    };

    const proxy = new Proxy({}, handler) as FluentPerson;
    return proxy;
}

const person = FluentPerson();
person.setName("ОнСгин").setAge(30).save();  // Π’Ρ‹Π²ΠΎΠ΄: { setName: 'ОнСгин', setAge: 30 }
JavaScript
function FluentPerson() {
    let person = {};

    const handler = {
        get: (target, property) => {
            if (property === "save") {
                return () => { console.log(person); };
            }
            return (value) => {
                person[property] = value;
                return proxy;
            };
        }
    };

    const proxy = new Proxy({}, handler);
    return proxy;
}

const person = FluentPerson();
person.setName("ОнСгин").setAge(30).save();  // Π’Ρ‹Π²ΠΎΠ΄: {setName: 'ОнСгин', setAge: 30}

Π£ΠΌΠ½ΠΎΠ΅ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ·Π²Π»Π΅ΠΊΠ°ΡŽΡ‚ΡΡ ΠΈΠ»ΠΈ Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡŽΡ‚ΡΡ ΠΏΠΎ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΡŽ, Π° Π·Π°Ρ‚Π΅ΠΌ хранятся для быстрого ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ доступа:

TypeScript
function smartCache<T extends object>(obj: T, fetcher: (key: keyof T) => any): T {
  const cache: Partial<T> = {};
  return new Proxy(obj, {
    get: (target, property: string | symbol) => {
      if (!cache[property]) {
        cache[property] = fetcher(property as keyof T);
      }
      return cache[property];
    }
  });
}

const userData = smartCache({ userId: 1 }, (prop) => {
  console.log(`ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ${String(prop)}`);
  return { name: "Π•Π²Π³Π΅Π½ΠΈΠΉ" }; // Бимуляция получСния Π΄Π°Π½Π½Ρ‹Ρ…
});

console.log(userData.userId); // Π’Ρ‹Π²ΠΎΠ΄: ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ userId, { name: 'Π•Π²Π³Π΅Π½ΠΈΠΉ' }
JavaScript
function smartCache(obj, fetcher) {
  const cache = {};
  return new Proxy(obj, {
    get: function(target, property) {
      if (!cache[property]) {
        cache[property] = fetcher(property);
      }
      return cache[property];
    }
  });
}

const userData = smartCache({ userId: 1 }, function(prop) {
  console.log(`ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ${String(prop)}`);
  return { name: "Π•Π²Π³Π΅Π½ΠΈΠΉ" }; // Бимуляция получСния Π΄Π°Π½Π½Ρ‹Ρ…
});

console.log(userData.userId); // Π’Ρ‹Π²ΠΎΠ΄: ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ userId, { name: 'Π•Π²Π³Π΅Π½ΠΈΠΉ' }

ДинамичСская валидация свойств

Proxy ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для создания ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² с динамичСской Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠ΅ΠΉ свойств β€” для обСспСчСния цСлостности Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ прСдотвращСния ошибок:

TypeScript
let user = {
  age: 25,
  name: "Π•Π²Π³Π΅Π½ΠΈΠΉ",
  email: "onegin@example.com"
};

let validator = {
  set: (obj, prop, value) => {
    if (prop === 'age') {
      if (typeof value !== 'number' || value < 18 || value > 100) {
        throw new Error("Возраст Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ числом ΠΌΠ΅ΠΆΠ΄Ρƒ 18 ΠΈ 100.");
      }
    } else if (prop === 'name') {
      if (typeof value !== 'string' || value.length < 2) {
        throw new Error("Имя Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡΠΎΡΡ‚ΠΎΡΡ‚ΡŒ хотя Π±Ρ‹ ΠΈΠ· Π΄Π²ΡƒΡ… символов.");
      }
    } else if (prop === 'email') {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (typeof value !== 'string' || !emailRegex.test(value)) {
        throw new Error("НСвСрный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ email.");
      }
    }
    obj[prop] = value;
    return true;
  },
  get: (obj, prop) => {
    console.log(`ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ свойство: ${String(prop)}`);
    return obj[prop];
  }
};

let userProxy = new Proxy(user, validator);

// ΠŸΠΎΠΏΡ‹Ρ‚ΠΊΠΈ измСнСния свойств ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°

console.log("--- ΠšΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ---");
try {
  userProxy.age = 30;
  console.log("Возраст ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ Π½Π°:", userProxy.age);
  
  userProxy.name = "Π’Π°Ρ‚ΡŒΡΠ½Π°";
  console.log("Имя измСнСно:", userProxy.name);
  
  userProxy.email = "larina@example.com";
  console.log("Email ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π΅Π½ Π½Π°:", userProxy.email);
} catch (error) {
  console.error("Π’ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка:", error.message);
}

console.log("\n--- НСкоррСктныС Π΄Π°Π½Π½Ρ‹Π΅ ---");
try {
  userProxy.age = 15;
} catch (error) {
  console.error("Ошибка измСнСния возраста:", error.message);
}

try {
  userProxy.age = "thirty";
} catch (error) {
  console.error("Ошибка измСнСния возраста:", error.message);
}

try {
  userProxy.name = "A";
} catch (error) {
  console.error("Ошибка измСнСния имСни:", error.message);
}

try {
  userProxy.email = "invalid-email";
} catch (error) {
  console.error("Ошибка измСнСния email:", error.message);
}

console.log("\n--- ЀинальноС состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ---");
console.log(userProxy);
JavaScript
let user = {
  age: 25,
  name: "Π•Π²Π³Π΅Π½ΠΈΠΉ",
  email: "onegin@example.com"
};

let validator = {
  set: function(obj, prop, value) {
    if (prop === 'age') {
      if (typeof value !== 'number' || value < 18 || value > 100) {
        throw new Error("Возраст Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ числом ΠΌΠ΅ΠΆΠ΄Ρƒ 18 ΠΈ 100.");
      }
    } else if (prop === 'name') {
      if (typeof value !== 'string' || value.length < 2) {
        throw new Error("Имя Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡΠΎΡΡ‚ΠΎΡΡ‚ΡŒ хотя Π±Ρ‹ ΠΈΠ· Π΄Π²ΡƒΡ… символов.");
      }
    } else if (prop === 'email') {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (typeof value !== 'string' || !emailRegex.test(value)) {
        throw new Error("НСвСрный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ email.");
      }
    }
    obj[prop] = value;
    return true;
  },
  get: function(obj, prop) {
    console.log(`ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ свойство: ${String(prop)}`);
    return obj[prop];
  }
};

let userProxy = new Proxy(user, validator);

// ΠŸΠΎΠΏΡ‹Ρ‚ΠΊΠΈ измСнСния свойств ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
console.log("--- ΠšΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ---");
try {
  userProxy.age = 30;
  console.log("Возраст ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ Π½Π°:", userProxy.age);
  
  userProxy.name = "Π’Π°Ρ‚ΡŒΡΠ½Π°";
  console.log("Имя измСнСно:", userProxy.name);
  
  userProxy.email = "larina@example.com";
  console.log("Email ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π΅Π½ Π½Π°:", userProxy.email);
} catch (error) {
  console.error("Π’ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка:", error.message);
}

console.log("\n--- НСкоррСктныС Π΄Π°Π½Π½Ρ‹Π΅ ---");
try {
  userProxy.age = 15;
} catch (error) {
  console.error("Ошибка измСнСния возраста:", error.message);
}
try {
  userProxy.age = "thirty";
} catch (error) {
  console.error("Ошибка измСнСния возраста:", error.message);
}
try {
  userProxy.name = "A";
} catch (error) {
  console.error("Ошибка измСнСния имСни:", error.message);
}
try {
  userProxy.email = "invalid-email";
} catch (error) {
  console.error("Ошибка измСнСния email:", error.message);
}

console.log("\n--- ЀинальноС состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ---");
console.log(userProxy);

ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ

Proxy позволяСт ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ измСнСния своих свойств ΠΈ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»ΡΡ‚ΡŒ ΠΎΠ± этих событиях. Π­Ρ‚ΠΎΡ‚ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ особСнно ΠΏΠΎΠ»Π΅Π·Π΅Π½ Π² ситуациях, ΠΊΠΎΠ³Π΄Π° Π½ΡƒΠΆΠ½ΠΎ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° измСнСния Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅:

TypeScript
function watchProperties(obj, onAccess, onChange) {
  const handler = {
    get: (target, property, receiver) => {
      onAccess(`Бвойство ${String(property)} Π±Ρ‹Π»ΠΎ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ΠΎ`);
      return Reflect.get(target, property, receiver);
    },
    set: (target, property, value, receiver) => {
      onChange(`Бвойство ${String(property)} ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΎ Π½Π° ${value}`);
      return Reflect.set(target, property, value, receiver);
    }
  };
  return new Proxy(obj, handler);
}

const book = {
  title: "Π›Π°Π±ΠΈΡ€ΠΈΠ½Ρ‚",  
  genre: "Π’Ρ€ΠΈΠ»Π»Π΅Ρ€",
  author: "Π€Ρ€Π°Π½ΠΊ ВильС",
  releaseYear: 2024,
  price: 560
};

const watchedBook = watchProperties(book, console.log, console.log);

console.log(watchedBook.title);   // Π’Ρ‹Π²ΠΎΠ΄: Бвойство title Π±Ρ‹Π»ΠΎ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ΠΎ Π›Π°Π±ΠΈΡ€ΠΈΠ½Ρ‚
console.log(watchedBook.genre);   // Π’Ρ‹Π²ΠΎΠ΄: Бвойство genre Π±Ρ‹Π»ΠΎ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ΠΎ Π’Ρ€ΠΈΠ»Π»Π΅Ρ€
watchedBook.price = 570;          // Π’Ρ‹Π²ΠΎΠ΄: Бвойство price ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΎ Π½Π° 570
console.log(watchedBook.author);  // Π’Ρ‹Π²ΠΎΠ΄: Бвойство author Π±Ρ‹Π»ΠΎ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ΠΎ Π€Ρ€Π°Π½ΠΊ ВильС
watchedBook.releaseYear = 2022;   // Π’Ρ‹Π²ΠΎΠ΄: Бвойство releaseYear ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΎ Π½Π° 2022
JavaScript
function watchProperties(obj, onAccess, onChange) {
  const handler = {
    get: (target, property, receiver) => {
      onAccess(`Бвойство ${String(property)} Π±Ρ‹Π»ΠΎ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ΠΎ`);
      return Reflect.get(target, property, receiver);
    },
    set: (target, property, value, receiver) => {
      onChange(`Бвойство ${String(property)} Π±Ρ‹Π»ΠΎ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΎ Π½Π° ${value}`);
      return Reflect.set(target, property, value, receiver);
    }
  };
  return new Proxy(obj, handler);
}

const book = {
  title: "Π›Π°Π±ΠΈΡ€ΠΈΠ½Ρ‚",  
  genre: "Π’Ρ€ΠΈΠ»Π»Π΅Ρ€",
  author: "Π€Ρ€Π°Π½ΠΊ ВильС",
  releaseYear: 2024,
  price: 560
};

const watchedBook = watchProperties(book, console.log, console.log);

console.log(watchedBook.title);   // Π’Ρ‹Π²ΠΎΠ΄: Бвойство title Π±Ρ‹Π»ΠΎ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ΠΎ Π›Π°Π±ΠΈΡ€ΠΈΠ½Ρ‚
console.log(watchedBook.genre);   // Π’Ρ‹Π²ΠΎΠ΄: Бвойство genre Π±Ρ‹Π»ΠΎ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ΠΎ Π’Ρ€ΠΈΠ»Π»Π΅Ρ€
watchedBook.price = 570;          // Π’Ρ‹Π²ΠΎΠ΄: Бвойство price ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΎ Π½Π° 570
console.log(watchedBook.author);  // Π’Ρ‹Π²ΠΎΠ΄: Бвойство author Π±Ρ‹Π»ΠΎ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ΠΎ Π€Ρ€Π°Π½ΠΊ ВильС
watchedBook.releaseYear = 2022;   // Π’Ρ‹Π²ΠΎΠ΄: Бвойство releaseYear ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΎ Π½Π° 2022

НСдостатки использования Proxy

Π₯отя Proxy позволяСт Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ массу ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΈ ΡƒΠ΄ΠΎΠ±Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, нСсколько нСдостатков Ρƒ этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π΅ΡΡ‚ΡŒ:

  • ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ. ИспользованиС Proxy ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ½ΠΈΠΆΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, особСнно ΠΏΡ€ΠΈ частых опСрациях, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ каТдая опСрация с проксированным ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ.
  • Π‘Π»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ. Π‘ большой ΠΌΠΎΡ‰ΡŒΡŽ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ большая ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ. НСкоррСктноС использованиС Proxy ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ трудноустранимым ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌ ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌ с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ ΠΊΠΎΠ΄Π°.
  • Π‘ΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ. Proxy Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΠΈΡ„ΠΈΠ»ΠΈΡ‚ΡŒ для старых Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ES6, поэтому Π½Π΅ стоит ΠΈΡ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² срСдах, Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‰ΠΈΡ… ΡˆΠΈΡ€ΠΎΠΊΠΎΠΉ совмСстимости.

Π’ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Proxy Π² JavaScript, особСнно ΠΏΡ€ΠΈ использовании с TypeScript, ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ Π³ΠΈΠ±ΠΊΠΈΠΉ способ взаимодСйствия с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ: позволяСт Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΡŽ, наблюдСниС, привязки, ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, Ρ†Π΅ΠΏΠ½ΠΎΠΉ Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΈ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΡƒΠ΄ΠΎΠ±Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. НСзависимо ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, создаСтС Π»ΠΈ Π²Ρ‹ слоТныС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ интСрфСйсы, Ρ€Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚Π΅ ΠΈΠ³Ρ€Ρ‹ ΠΈΠ»ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚Π΅ Π½Π°Π΄ сСрвСрной Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ, ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΠΈ использованиС Proxy прСдоставит Π²Π°ΠΌ Π±ΠΎΠ»Π΅Π΅ Π³Π»ΡƒΠ±ΠΎΠΊΠΈΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ контроля ΠΈ гибкости.

***

Π₯ΠΎΡ‚ΠΈΡ‚Π΅ ΠΎΡΠ²ΠΎΠΈΡ‚ΡŒ ΡΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π²Π΅Π±-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΠΈ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ свой ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚-ΠΌΠ°Π³Π°Π·ΠΈΠ½? ΠšΡƒΡ€Ρ Frontend Basic ΠΎΡ‚ Poglib Academy ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ 26 Π²ΠΈΠ΄Π΅ΠΎΡƒΡ€ΠΎΠΊΠΎΠ² ΠΈ 28 практичСских Π·Π°Π΄Π°Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΌΠΎΠ³ΡƒΡ‚ Π²Π°ΠΌ ΠΈΠ·ΡƒΡ‡ΠΈΡ‚ΡŒ HTML, CSS, JavaScript ΠΈ React.js Π·Π° 2 мСсяца, Π΄Π°ΠΆΠ΅ Ссли Π²Ρ‹ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚Π΅ с нуля.

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•

eFusion
01 ΠΌΠ°Ρ€Ρ‚Π° 2020

ВОП-15 ΠΊΠ½ΠΈΠ³ ΠΏΠΎ JavaScript: ΠΎΡ‚ Π½ΠΎΠ²ΠΈΡ‡ΠΊΠ° Π΄ΠΎ профСссионала

Π’ этом постС ΠΌΡ‹ собрали ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Ρ‘Π½Π½Ρ‹Π΅ Π½Π° русский язык ΠΊΠ½ΠΈΠ³ΠΈ ΠΏΠΎ JavaScript – ...
admin
10 июня 2018

Π›Π°ΠΉΡ„Ρ…Π°ΠΊ: Π² ΠΊΠ°ΠΊΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈΠ·ΡƒΡ‡Π°Ρ‚ΡŒ JavaScript

ΠžΠ³Ρ€ΠΎΠΌΠ½Ρ‹ΠΉ инструмСнтарий JS ΠΈ Ρ‚ΠΎΠ½Π½Ρ‹ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² ΠΏΠΎ Π½Π΅ΠΌΡƒ. Π‘ Ρ‡Π΅Π³ΠΎ Π½Π°Ρ‡Π°Ρ‚ΡŒ? Расск...