# JavaScript Proxy va Reflect

> Proxy bilan obyekt xatti-harakatini boshqarish: get va set tuzoqlari, validatsiya, himoyalangan xossalar va Reflect metodlari. Amaliy misollar bilan.

Manba: https://learncode.uz/javascript/proxy-reflect/
Sana: 2026-06-08

Obyektdan xossa o'qilganda yoki unga qiymat berilganda **oralikka tushib**,
o'z qoidangizni qo'yish mumkin. Buni `Proxy` bajaradi — zamonaviy
kutubxonalarning ko'p "sehri" shu ustiga qurilgan.

## Birinchi Proxy

```js
const original = { name: "Aziz", age: 20 };

const observer = new Proxy(original, {
  get(target, key) {
    console.log("  o'qildi:", key);
    return target[key];
  },
});

console.log(observer.name);
console.log(observer.age);
```

> **Atama**
>
> **Proxy** — boshqa obyekt (**nishon**) oldiga qo'yiladigan qobiq. Unga
> qilingan murojaatlar avval **tuzoq** (trap) funksiyalaridan o'tadi. Asosiy
> tuzoqlar: `get` (o'qish), `set` (yozish), `has` (`in`), `deleteProperty`
> (`delete`).

## set — yozishni nazorat qilish

```js
const student = new Proxy({}, {
  set(target, key, value) {
    if (key === "age") {
      if (typeof value !== "number") {
        throw new TypeError("age num bo'lishi kerak");
      }
      if (value < 0 || value > 150) {
        throw new RangeError("age 0 dan 150 gacha bo'lsin");
      }
    }
    target[key] = value;
    return true;
  },
});

student.name = "Aziz";
student.age = 20;
console.log(student.name, student.age);

try {
  student.age = "yigirma";
} catch (e) {
  console.log(e.name + ":", e.message);
}

try {
  student.age = 200;
} catch (e) {
  console.log(e.name + ":", e.message);
}
```

Validatsiya obyektning **o'zida** joylashdi — uni ishlatadigan har bir joyda
qayta yozish shart emas.

> **set true qaytarishi kerak**
>
> `set` tuzog'i muvaffaqiyat belgisini qaytarishi shart. `return true`
> yozilmasa, qat'iy rejimda (modullar har doim qat'iy) `TypeError` chiqadi.

## Yo'q xossa uchun standart qiymat

```js
const settings = new Proxy({ theme: "qorong'i" }, {
  get(target, key) {
    return key in target ? target[key] : "belgilanmagan";
  },
});

console.log(settings.theme);
console.log(settings.lang);
console.log(settings.size);
```

`undefined` o'rniga ma'noli qiymat — sozlamalar bilan ishlashda qulay.

## Maxfiy xossalarni yashirish

```js
const original = { name: "Aziz", _parol: "maxfiy", age: 20 };

const guarded = new Proxy(original, {
  get(target, key) {
    if (typeof key === "string" && key.startsWith("_")) {
      throw new Error("Maxfiy xossaga ruxsat yo'q: " + key);
    }
    return target[key];
  },

  has(target, key) {
    if (typeof key === "string" && key.startsWith("_")) return false;
    return key in target;
  },

  ownKeys(target) {
    return Reflect.ownKeys(target).filter(
      (k) => !(typeof k === "string" && k.startsWith("_"))
    );
  },
});

console.log(guarded.name);
console.log("_parol" in guarded);
console.log(Object.keys(guarded));

try {
  console.log(guarded._parol);
} catch (e) {
  console.log(e.message);
}
```

Uch tuzoq birga ishladi: o'qish taqiqlandi, `in` yolg'on qaytardi va
`Object.keys` ro'yxatdan chiqardi.

## Reflect — standart xatti-harakat

> **Atama**
>
> **Reflect** — obyektlar bilan ishlashning **standart** amallarini funksiya
> ko'rinishida beradigan obyekt: `Reflect.get`, `Reflect.set`,
> `Reflect.has`, `Reflect.ownKeys`. Har `Proxy` tuzog'iga mos `Reflect` metodi
> bor — shuning uchun ular birga ishlatiladi.

```js
const obj = { a: 1, b: 2 };

console.log(Reflect.get(obj, "a"));
console.log(Reflect.has(obj, "b"));
console.log(Reflect.ownKeys(obj));

Reflect.set(obj, "c", 3);
console.log(obj);

Reflect.deleteProperty(obj, "a");
console.log(obj);
```

## Nega Reflect Proxy bilan birga

```js
const original = { name: "Aziz" };

const good = new Proxy(original, {
  get(target, key, qabul) {
    console.log("  o'qildi:", String(key));
    return Reflect.get(target, key, qabul);
  },

  set(target, key, value, qabul) {
    console.log("  yozildi:", String(key), "=", value);
    return Reflect.set(target, key, value, qabul);
  },
});

good.age = 20;
console.log(good.name, good.age);
```

`nishon[kalit]` o'rniga `Reflect.get` ishlatish to'g'riroq: u `this`
bog'lanishini (`qabul` argumenti) saqlaydi va `set` uchun kerakli
`true`/`false` ni o'zi qaytaradi.

## Amaliy misol — o'zgarishlarni kuzatish

```js
function watch(obj, message) {
  return new Proxy(obj, {
    set(target, key, value, qabul) {
      const old = target[key];
      const result = Reflect.set(target, key, value, qabul);
      if (old !== value) message(key, old, value);
      return result;
    },
  });
}

const state = watch({ count: 0, title: "test" }, (key, old, fresh) => {
  console.log(`${key}: ${old} → ${fresh}`);
});

state.count = 1;
state.count = 2;
state.count = 2;
state.title = "fresh";

console.log("Yakuniy:", state.count, state.title);
```

Bu — Vue kabi freymvorklardagi reaktivlikning soddalashtirilgan mohiyati:
ma'lumot o'zgarganda interfeys avtomatik yangilanadi.

## Manfiy indeks

```js
function negativeIndex(arr) {
  return new Proxy(arr, {
    get(target, key) {
      if (typeof key === "string" && /^-\d+$/.test(key)) {
        return target[target.length + Number(key)];
      }
      return Reflect.get(target, key);
    },
  });
}

const m = negativeIndex(["a", "b", "c", "d"]);

console.log(m[0]);
console.log(m[-1]);
console.log(m[-2]);
console.log(m.length);
```

Python'dagi kabi manfiy indeks JavaScript'da yo'q — Proxy uni qo'shdi.

## Cheklovlar

> **Tezlik va nosozlik**
>
> Proxy har murojaatga qo'shimcha funksiya chaqiruvi qo'shadi — u issiq
> sikllarda sezilarli sekinlashtiradi. Shuningdek `#` bilan boshlangan
> [maxfiy xossalar](https://learncode.uz/javascript/klasslar) Proxy orqali ishlamaydi.
>
> Shuning uchun Proxy — kundalik vosita emas: kutubxona yozish, kuzatuv va
> validatsiya qatlamlari uchun.

## Amaliy mashq

1. `get` tuzog'i bilan har o'qishni log qiling;
2. `set` bilan yosh maydonini tekshiring;
3. yo'q xossa uchun standart qiymat qaytaring;
4. `_` bilan boshlangan xossalarni yashiring;
5. `Reflect.get` va `Reflect.set` ni tuzoqlarda ishlating;
6. o'zgarishlarni kuzatuvchi obyekt yasang.

## Qisqacha xulosa

- **Proxy** obyekt oldiga qobiq qo'yib, murojaatlarni ushlaydi.
- Asosiy tuzoqlar: `get`, `set`, `has`, `deleteProperty`, `ownKeys`.
- `set` tuzog'i `true` qaytarishi shart.
- **Reflect** standart amallarni funksiya ko'rinishida beradi.
- Tuzoq ichida `Reflect` ishlatish to'g'ri xatti-harakatni saqlaydi.
- Proxy sekinroq va maxfiy `#` xossalar bilan ishlamaydi.

Keyingi darsda [modul tizimi va bundler](https://learncode.uz/javascript/bundler) — kodni
yig'ish va tarqatish.
