π§ 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 ΠΌΠΎΠΆΠ΅Ρ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ Π·Π°ΠΏΠΎΠ»Π½ΡΡΡ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΠΏΡΠΈ Π΄ΠΎΡΡΡΠΏΠ΅ ΠΊ Π½ΠΈΠΌ β ΡΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΠΏΠΎ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ ΠΈΠ»ΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΠ»ΠΎΠΆΠ½ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ².
Π ΡΡΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Ρ Π½Π°Ρ Π΅ΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΏΡΠΎΡΠΈΠ»Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ, ΡΠ°ΠΌΠΈΠ»ΠΈΠ΅ΠΉ ΠΈ ΠΏΠΎΠ»Π½ΡΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΡΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΡΠΈ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠΈ ΠΊ Π½Π΅ΠΌΡ:
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); // ΠΡΠ²ΠΎΠ΄: ΠΠ½Π΄ΡΠ΅ΠΉ ΠΠΎΠ»ΠΊΠΎΠ½ΡΠΊΠΈΠΉ
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 ΠΏΠΎΠ΄ΡΡΠΈΡΡΠ²Π°Π΅ΡΡΡ ΡΠΈΡΠ»ΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ ΡΡΠ΅Π½ΠΈΡ ΡΠ²ΠΎΠΉΡΡΠ² ΠΎΠ±ΡΠ΅ΠΊΡΠ° β ΡΠ°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ, ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° ΠΈΠ»ΠΈ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ:
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
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
, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π΅Π³ΠΎ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΡΡ Π²Π΅ΡΡΠΈΡ:
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);
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);
Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Ρ ΡΠ΅ΠΏΠΎΡΠΊΠΎΠΉ Π²ΡΠ·ΠΎΠ²ΠΎΠ² ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ²
Π’Π΅ΠΊΡΡΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΡΠ΅ΠΏΠΎΡΠΊΠΎΠΉ:
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 }
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}
Π£ΠΌΠ½ΠΎΠ΅ ΠΊΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅
Π ΡΡΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΈΠ·Π²Π»Π΅ΠΊΠ°ΡΡΡΡ ΠΈΠ»ΠΈ Π²ΡΡΠΈΡΠ»ΡΡΡΡΡ ΠΏΠΎ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ, Π° Π·Π°ΡΠ΅ΠΌ Ρ ΡΠ°Π½ΡΡΡΡ Π΄Π»Ρ Π±ΡΡΡΡΠΎΠ³ΠΎ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ Π΄ΠΎΡΡΡΠΏΠ°:
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: 'ΠΠ²Π³Π΅Π½ΠΈΠΉ' }
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 ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Ρ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠΉ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠ΅ΠΉ ΡΠ²ΠΎΠΉΡΡΠ² β Π΄Π»Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΡ ΡΠ΅Π»ΠΎΡΡΠ½ΠΎΡΡΠΈ Π΄Π°Π½Π½ΡΡ ΠΈ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ΅Π½ΠΈΡ ΠΎΡΠΈΠ±ΠΎΠΊ:
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);
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 ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠΎΠ·Π΄Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠ³ΡΡ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°ΡΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΡΠ²ΠΎΠΈΡ ΡΠ²ΠΎΠΉΡΡΠ² ΠΈ ΡΠ²Π΅Π΄ΠΎΠΌΠ»ΡΡΡ ΠΎΠ± ΡΡΠΈΡ ΡΠΎΠ±ΡΡΠΈΡΡ . ΠΡΠΎΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ ΠΏΠΎΠ»Π΅Π·Π΅Π½ Π² ΡΠΈΡΡΠ°ΡΠΈΡΡ , ΠΊΠΎΠ³Π΄Π° Π½ΡΠΆΠ½ΠΎ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°ΡΡ ΠΈΠ»ΠΈ ΡΠ΅Π°Π³ΠΈΡΠΎΠ²Π°ΡΡ Π½Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² ΠΎΠ±ΡΠ΅ΠΊΡΠ΅:
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
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 ΠΌΠ΅ΡΡΡΠ°, Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ Π²Ρ Π½Π°ΡΠΈΠ½Π°Π΅ΡΠ΅ Ρ Π½ΡΠ»Ρ.