π§ 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 ΠΌΠ΅ΡΡΡΠ°, Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ Π²Ρ Π½Π°ΡΠΈΠ½Π°Π΅ΡΠ΅ Ρ Π½ΡΠ»Ρ.