WeakMap, WeakSet, Proxy, Reflect
WeakMap/WeakSet-এর memory সুবিধা, WeakRef, Proxy দিয়ে বিহেভিয়ার, Reflect — advanced JS টুলবক্স বাংলায়।
এই পর্ব-এ তিনটি advance টুল: WeakMap/WeakSet — memory-safe জোড়া ডেটা, Proxy — object-এর কার্যকলাপ interception, আর Reflect — proxy-র সাথে মিলে ব্যবহার।
WeakMap — memory-friendly keyed ডেটা
const wm = new WeakMap();
let user = { name: "রহিম" };
wm.set(user, "active");
console.log(wm.get(user)); // "active"
// user-কে মুছে দিলে entry গার্বেজ-কুড়ির সুযোগ
user = null;
// WeakMap: key অবশ্যই object — string নয়WeakMap-এর key অবশ্যই object। key গ্রাহক হয়ে গেলে (গার্বেজ collected হলে) entry নিজে মুছে যায় — তাই memory leak-এ helper ডেটা রাখার নিরাপদ জায়গা।
WeakMap কীভাবে ব্যবহার হয়?
private metadata, cache, class-সংগত সহায়ক ডেটা — এসবই WeakMap-এর আসল ব্যবহার। এখানে object-key দরকারি, আলাদা কিছু মনে রাখা ঠিক নয়।
// object-সংগত private/extra data
const meta = new WeakMap();
class Player {
constructor(name) {
this.name = name;
meta.set(this, { score: 0 });
}
addScore(points) {
meta.get(this).score += points;
}
getScore() {
return meta.get(this).score;
}
}
const p = new Player("রহিম");
p.addScore(10);
console.log(p.getScore()); // 10instance-এ non-enumerable সহায়ক data রাখার স্মার্ট pattern — class-এর private state-এর মতো। instance কমে গেলে WeakMap-এর entry-ও চলে যায়।
WeakSet
const ws = new WeakSet();
let obj = {};
ws.add(obj);
console.log(ws.has(obj)); // true
obj = null;
// WeakSet-থেকে object নিজে-নিজে সরে যায়WeakSet-এ object-এর unique membership ট্র্যাক করা যায় — memory leak না করে। size/forEach নেই (non-iterable)।
WeakRef ও FinalizationRegistry (সংক্ষেপ)
const ref = new WeakRef({ data: "কিছু" });
// deref() — object বেঁচে থাকলে দেয়, নাহলে undefined
const value = ref.deref?.();
console.log(value?.data);WeakRef-এ object-এর দুর্বল সংযোগ — মেমরি-চাপে গেলে GC-এর হয়ে যাওয়ার সুযোগ। FinalizationRegistry-এ object GC হলে callback চালানো যায় — cache/cleanup-জাতীয় কাজে, তবে বেশিরভাগ অ্যাপে জরুরি নয়।
Proxy — interception
const target = { name: "রহিম" };
const proxy = new Proxy(target, {
get(obj, prop) {
if (!(prop in obj)) {
return `অজানা: ${prop}`;
}
return obj[prop];
},
set(obj, prop, value) {
if (prop === "age" && (typeof value !== "number" || value < 0)) {
throw new Error("invalid age");
}
obj[prop] = value;
return true;
},
});
console.log(proxy.name); // রহিম
console.log(proxy.nonexistent); // অজানা: nonexistent
proxy.age = 25;
console.log(proxy.age);
// proxy.age = -5; // Errornew Proxy(target, handler) — handler-এর get/set ইত্যাদি দিয়ে object-অ্যাক্সেস কাস্টমাইজ করা যায় — validation, logging, fallback।
Proxy tracker
const user = { name: "রহিম" };
const proxy2 = new Proxy(user, {
get(obj, prop) {
console.log(`অ্যাক্সেস: ${prop}`);
return obj[prop];
},
});
console.log(proxy2.name);
// অ্যাক্সেস: name
// রহিমProxy দিয়ে কী অ্যাক্সেস হচ্ছে তা লগ করা যায় — performance debugging, security, observer প্যাটার্ন, form state validation।
Reflect — proxy-র সঙ্গী
const target = { a: 1 };
const proxy3 = new Proxy(target, {
get(obj, prop, receiver) {
return Reflect.get(obj, prop, receiver) ?? "নেই";
},
});
console.log(proxy3.a); // 1
console.log(proxy3.zzz); // নেইReflect-এর method (Reflect.get, Reflect.set) object-তে default আচরণ ছাড়া আর কিছুই — Proxy trap-এ default-আচরণ রাখতে ব্যবহার হয়, বিশেষত receiver/this গুছিয়ে রাখতে।
কখন ব্যবহার করবেন?
যতটুকু এড়ানো যায়, Proxy/WeakMap ততই ভালো — কিন্তু দরকার হলে:
- validation/form guard — Proxy দিয়ে set trap
- observability/log — get/set trap
- private সহায়ক ডেটা — WeakMap
- unique membership — WeakSet
| টুল | মূল শক্তি |
|---|---|
| WeakMap | object-key + auto-clean |
| WeakSet | unique object-মার্ক |
| Proxy | get/set interception |
| Reflect | default proxy-র helper |
WeakMap/WeakSet-এ size/keys/forEach নেই — GC-নির্ভর বলে তালিকা দেওয়া যায় না। সবগুলো একসাথে দরকার হলে Map/Set।
"WeakMap কেন?" — memory-safe keyed data, auto GC। "Proxy কী?" — object-তে traps — validation/observability।
WeakMap দিয়ে একটি counter class লেখেন (প্রতি instance-এ আলাদা count) আর একটি Proxy দিয়ে object থেকে insecure প্রপার্টি পড়া ব্লক করেন।