Proxy obyekti

ULASHISH

Proksi nima?

Proksi-server boshqa obyektlarni o‘rashi mumkin bo‘lgan JavaScript obyektidir.

Proksi-server sizga boshqa obyektlardagi operatsiyalarni boshqarish imkonini beradi.

Proksi-server quyidagi hollarda kodni ushlab qolishi va ushlab turishi mumkin:

  • Xususiyatni o‘qish (get)
  • Xususiyatni o‘rnatish (set)
  • Xususiyatni o‘chirish (deleteProperty)
  • Xususiyat mavjudligini tekshirish (has)
  • Funksiyani chaqirish (apply)
  • Obyektni yaratish (construct)

Proksi-server kimdir obyekt bilan o‘zaro aloqada bo‘lganda o‘z kodingizni ishga tushirish imkonini beradi.

Proxy sizning kodingiz va JavaScript obyekti o‘rtasida vositachi bo‘lishi mumkin.


Proxy sintaksisi

const proxy = new Proxy(target, handler);
  • target — asl obyekt yoki funksiya
  • ishlov beruvchi - tuzoq usullariga ega obyekt

Misol

const myObject = {name: "Jan"};

const proxy = new Proxy(myObject, {
  get(target, prop) {
    return target[prop];
  }
});

Proxy yordamida loglash

Proksi-serverning odatiy misoli obyekt o‘zgarishlarini qayd qilishdir.

Quyida demo mavjud:

  • Obyektni Proxy bilan o‘raydi
  • Xususiyat har safar o‘qilganda yoki yozilganda log yozadi
  • Har bir olish va o‘rnatish operatsiyasini real vaqtda qayd qiladi

Misol

Barcha xususiyat qiymatlaridagi barcha o‘zgarishlarni qayd qiling:

// Create an Object
const user = { name: "Jan", age: 40 };

//Create a Proxy
const proxy = new Proxy(user, {
  get(target, property) {
    log("Getting: " + property);
    return target[property];
  },
  set(target, property, value) {
    log("Setting: " + property);
    return target[property];
  }
});

proxy.name = "John";
proxy.age = 42;

let text1 = proxy.name;
let text2 = proxy.age
O‘zingiz sinab ko‘ring »


Reflect bilan Proxy (eng keng tarqalgan)

Quyida demo mavjud:

  • Obyektni Proxy bilan o‘raydi
  • Xususiyat har safar o‘qilganda yoki yozilganda log yozadi
  • Proxy handlerlari ichida Reflect.get() va Reflect.set() dan foydalanadi
  • get trap uses Reflect.get(target, property, receiver)
  • set trap Reflect.set(target, property, value, receiver) dan foydalanadi
  • Reflect Proxy xatti-harakatini oddiy obyekt xatti-harakatiga moslashtiradi

Misol

Barcha xususiyat qiymatlaridagi barcha o‘zgarishlarni qayd qiling:

// Create an Object
const user = { name: "Jan", age: 40 };

// Create a Proxy
const proxy = new Proxy(user, {
  get(target, property) {
    log("Getting: " + property);     // safe forwarding
    return Reflect.get(target, property);
  },
  set(target, property, value) {
    log("Setting: " + property);     // safe forwarding
    return Reflect.set(target, property, value);
  }
});

proxy.name = "John";
proxy.age = 42;

let text1 = proxy.name;
let text2 = proxy.age
O‘zingiz sinab ko‘ring »

Reflect bilan Proxy ishlash oqimi

Quyidagi oqim Proksi + Reflect bilan JavaScript metadasturlashning mohiyatidir.

Proxy

Flow Explanation:

  • Sizning kodingiz obyekt bilan o‘zaro ta’sir qiladi
  • Proxy amalni ushlab qoladi
  • Tuzoq kodingiz nima qilishni hal qiladi
  • Reflect amalni xavfsiz tarzda uzatadi
  • Maqsad (target) obyekt haqiqiy amalni qabul qiladi

Nima uchun Proxy’lar?

Proksi-serverlar sizga quyidagilarga imkon beradi:

  • Add logging
  • Validate changes
  • Auto-generate properties
  • Protect sensitive data
  • Virtual yoki hisoblanadigan obyektlarni yaratish
  • Intercept function calls
  • Create reactive systems (like Vue.js)

Proxy yordamida validatsiya

Misol

// Create an Object
const user = { name: "Jan", age: 40 };

// Create a Proxy
const proxy = new Proxy(user, {
  set(target, prop, value) {
    if (prop === "age" && value < 0) {
      text = "Age cannot be negative!";
      document.getElementById("demo").innerHTML = text;
    }
    return Reflect.set(target, prop, value);
  }
});

proxy.age = 45; // OK
proxy.age = -5; // Error
O‘zingiz sinab ko‘ring »

Virtual xususiyatlar

Misol

// Create an Object
const person = {
first: "John",
last: "Doe"
};

// Create a Proxy
const virtual = new Proxy(person, {
  get(target, prop) {
    if (prop === "fullName") {
      return target.first + " " + target.last;
    }
    return Reflect.get(target, prop);
  }
});

let text = virtual.fullName; // "John Doe"
O‘zingiz sinab ko‘ring »

Dinamik funksiyalar

Misol

const fn = new Function("a", "b", "return a + b");

let result = fn(3, 2);
O‘zingiz sinab ko‘ring »

Metaprogramming

Metaprogramming lets JavaScript:

  • Intercept behavior
  • Modify behavior
  • Define new behavior
  • Generate behavior dynamically

U dasturchilarga tilning ichki mexanizmlari ustidan chuqur nazorat beradi.


Proxy tuzoqlari (traps)

Trap — Proxy handler ichidagi funksiya.

Proksi-serverda ma’lum bir operatsiya bajarilganda ishlaydi.

Quyida har bir JavaScript proksi tuzog‘ining to‘liq va to‘g‘ri tushuntirishi, ularni nima qo‘zg‘atayotgani, parametrlari va nima qaytarishi kutilmoqda.

Trap NameQachon ishga tushadi
getXususiyat o‘qilganda
setXususiyat o‘zgartirilganda
hasin operatoridan foydalanilganda
deletePropertyXususiyat o‘chirilganda
applyFunksiya chaqirilganda
constructObyekt yaratilganda (new bilan)
getOwnPropertyDescriptorXususiyat deskriptori olinganda
definePropertyXususiyat aniqlanganda
getPrototypeOfPrototip olinganda
setPrototypeOfPrototip o‘rnatilganda
isExtensibleKengaytiriluvchanlik tekshirilganda
preventExtensionsKengaytirish taqiqlanganda
ownKeysXususiyatlar ro‘yxatlanganda

Yuqoridagi ro‘yxat 2025 yilga to‘g‘ri keladi va ECMAScript-da belgilangan barcha 13 ta proksi tuzoqlarni o‘z ichiga oladi.

Har bir trap handler quyida tavsiflangan.


handler.get()

Xususiyat o‘qilganda ishga tushadi:

get(obj, prop, receiver) {
  return Reflect.get(obj, prop, receiver);
}

Ishga tushiruvchi amallar:

proxy.property
proxy["property"]
object.property()

Parametrlar

  • obj — maqsadli Object
  • prop — murojaat qilinayotgan xususiyat
  • receiver — getter’lar uchun this qiymati (odatda proxy’ning o‘zi)

Qaytarishi kerak

  • Xususiyat qiymati

handler.set()

Xususiyatga qiymat berilganda ishga tushadi:

set(obj, prop, value, receiver) {
  return Reflect.set(obj, prop, value, receiver);
}

Ishga tushiruvchi amallar:

proxy.property = value;
proxy["property"] = value;

Parametrlar

  • obj — maqsadli Object
  • prop - o‘rnatilayotgan xususiyat
  • value - the new property value
  • receiver — qiymat berishni qabul qilgan obyekt (odatda proxy)

Qaytarishi kerak

  • true — agar qiymat berish muvaffaqiyatli bo‘lsa
  • false — agar qiymat berish muvaffaqiyatsiz bo‘lsa

Xato chiqarishga (throw) ham ruxsat beriladi.


handler.has()

in operatorini ushlab qoladi.

has(obj, prop) {
  return Reflect.has(obj, prop);
}

Ishga tushiruvchi amallar:

"property" in proxy

Parametrlar

  • obj — maqsadli Object
  • prop — murojaat qilinayotgan xususiyat
  • qabul qiluvchi - bu sozlagichlar uchun qiymati (odatda proksi-serverning o‘zi)

Qaytarishi kerak

  • rost
  • yolg‘on

handler.deleteProperty()

Intercepts the o‘chirish operator.

deleteProperty(obj, prop) {
  return Reflect.deleteProperty(obj, prop);
}

Ishga tushiruvchi amallar:

delete proxy.property

Parametrlar

  • obj — maqsadli Object
  • prop - o‘chirish uchun xususiyat

Qaytarishi kerak

  • true — muvaffaqiyat uchun
  • false — muvaffaqiyatsizlik uchun

handler.apply()

Funksiya chaqirilganda ishga tushadi:

apply(func, thisArg, args) {
  return Reflect.apply(func, this, args);
}

Ishga tushiruvchi amallar:

proxy()
proxy.call()
proxy.apply()

Parametrlar

  • func - chaqiriladigan obyekt (funksiya)
  • this - chaqiruv uchun this argumenti
  • args — funksiya argumentlari massivi

Qaytarishi kerak

  • Funksiyaning qaytariladigan qiymati

handler.construct

new operatorini ushlab qoladi.

construct(obj, args, newTarget) {
  return Reflect.construct(obj, args, newTarget);
}

Ishga tushiruvchi amallar:

nex proxy()

Parametrlar

  • obj — konstruktor obyekti
  • args - o‘tgan argumentlar Array
  • newTarget - konstruktor

Qaytarishi kerak

  • Obyekt (yangi misol)

Tuzilma tuzog‘i faqat yangisini ishlatganda ishlaydi.

const obj = {}  // No trap
Object.create() // No trap

class User {};
new User();     // No trap

handler.getOwnPropertyDescriptor()

Intercepts property descriptor retrieval.

getOwnPropertyDescriptor(obj, prop) {
  return Reflect.getOwnPropertyDescriptor(obj, prop);
}

Ishga tushiruvchi amallar:

Object.getOwnPropertyDescriptor(obj, prop)

Parametrlar

  • obj — maqsadli Object
  • prop — tavsiflanadigan xususiyat

Qaytarishi kerak

  • Xususiyat deskriptori
  • Aniqlanmagan

handler.defineProperty()

Intercepts Object.defineProperty().

defineProperty(obj, prop, descriptor) {
  return Reflect.defineProperty(obj, prop, descriptor);
}

Ishga tushiruvchi amallar:

Object.defineProperty()

Parametrlar

  • obj — maqsadli Object
  • prop — tavsiflanadigan xususiyat
  • descriptor — xususiyat deskriptori

Qaytarishi kerak

  • true — muvaffaqiyatli bo‘lsa
  • false — aks holda

handler.getPrototypeOf()

Intercepts prototype lookup.

getPrototypeOf(obj) {
  return Reflect.getPrototypeOf(obj);
}

Ishga tushiruvchi amallar:

Object.getPrototypeOf()

Parametrlar

  • obj — maqsadli Object

Qaytarishi kerak

  • Obyekt
  • null

handler.setPrototypeOf()

Prototipni sozlashni to‘xtatadi.

setPrototypeOf(obj, prototype) {
  return Reflect.setPrototypeOf(obj, prototype);
}

Ishga tushiruvchi amallar:

Object.settPrototypeOf()

Parametrlar

  • obj — maqsadli Object
  • prototype — yangi prototip yoki null

Qaytarishi kerak

  • Obyekt
  • null

handler.isExtensible()

Obyekt kengaytiriladigan ekanligini tekshirishni ushlab qoladi.

isExtensible(obj) {
  return Reflect.isExtensible(obj);
}

Ishga tushiruvchi amallar:

Object.isExtensible()

Parametrlar

  • obj — maqsadli Object

Qaytarishi kerak

  • true — ha
  • false — yo‘q

handler.preventExtentions()

Obyektni kengaytirib bo‘lmaydigan qilishni ushlab qoladi.

preventExtensions(obj) {
  return Reflect.preventExtensions(obj);
}

Ishga tushiruvchi amallar:

Object.preventExtensions()

Parametrlar

  • obj — maqsadli Object

Qaytarishi kerak

  • true — muvaffaqiyat uchun
  • false — muvaffaqiyatsizlik uchun

handler.ownKeys()

Kalitlarni (xususiyat nomlari yoki Symbol’larni) ro‘yxatlovchi amallarni ushlab qoladi.

ownKeys(obj) {
  return Reflect.ownKeys(obj);
}

Ishga tushiruvchi amallar:

Object.keys()
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()

Parametrlar

  • obj — maqsadli Object

Qaytarishi kerak

  • Takrorlanmaydigan kalitlar massivi

Proxy tuzoqlari Reflect metodlariga mos keladi

Proxy trap JavaScript’ning ichki amallaridan birini ifodalaydi:

  • [[Construct]]
  • [[Call]]
  • [[Get]]
  • [[Set]]
  • [[HasProperty]]
  • [[Delete]]
  • [[DefineProperty]]
  • [[GetOwnProperty]]
  • [[OwnPropertyKeys]]
  • [[GetPrototypeOf]]
  • [[SetPrototypeOf]]
  • [[PreventExtensions]]
  • [[IsExtensible]]

Bu ichki amallar siz obyektlarga murojaat qilganingizda yoki ularni o‘zgartirganingizda JavaScript (dvigatel ichida) foydalanadigan amallardir.

Proksi-server ushbu operatsiyalardan birini to‘xtatganda, ular to‘g‘ri yo‘naltirilishi kerak:

get(target, property, receiver) {
  return Reflect.get(target, property, receiver);
}

Reflect ishlatiladi, chunki Reflect usullari ichki operatsiyalarning 1 dan 1 gacha ko‘zgusidir.

  • Ular to‘g‘ri qaytariladigan qiymatlarni hosil qiladi (true/false/descriptor)
  • Ular proksi qoidalarini buzadigan xatolardan qochishadi
  • Ular Proxy’ning oddiy JavaScript obyektlari kabi ishlashini ta’minlaydi (agar o‘zgartirilmagan bo‘lsa)
Shuning uchun har bir Proksi tuzog‘ida bir xil nom va imzo bilan Reflect usuli mavjud.

JavaScript ichki mexanizmlari Reflect’ga aylandi

ES6 (2015)’gacha ko‘plab asosiy amallar funksiya sifatida mavjud emas edi:

OperatsiyaBefore E6Problem
get propertyobj[prop]Funksiya sifatida chaqirib bo‘lmaydi
xususiyatni o‘rnatishobj[prop] = valueFunksiya sifatida chaqirib bo‘lmaydi
delete propertydelete obj[prop]Funksiya emas, operator
check property"prop" in objFunksiya emas, operator
construct (new)new Foo()Umumiy tarzda chaqirib bo‘lmaydi
get prototypesObject.getPrototypeOf(obj)Obyekt bo‘lmagan qiymatlarda xato chiqaradi
define propertyObject.defineProperty()Boolean o‘rniga obyekt qaytaradi
own keysObject.keys()To‘liq emas (Symbol’larni o‘tkazib yuboradi)

Bular to‘liq bo‘lmagan va proksi-server orqali jo‘natish uchun nomuvofiq edi.

So ES6 (2015) added Reflect:

Internal Operation Reflect Method
[[Construct]]Reflect.construct()
[[Call]]Reflect.apply()
[[Get]]Reflect.get()
[[Set]]Reflect.set()
[[HasProperty]]Reflect.has()
[[Delete]]Reflect.deleteProperty()
[[DefineProperty]]Reflect.defineProperty()
[[GetOwnProperty]]Reflect.getOwnProperty()
[[OwnPropertyKeys]]Reflect.ownPropertyKeys()
[[IsExstensible]]Reflect.isExtensible()
[[PreventExstensions]]Reflect.preventExtensions()
[[GetPrototypeOf]]Reflect.getPrototypeOf()
[[SetPrototypeOf]]Reflect.setPrototypeOf()


W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!