JavaScript Objects: Advanced (অবজেক্ট)
Shallow/deep copy, freeze, seal, getter/setter, prototype, value vs reference, optional chaining, this-এর নিয়ম, pitfalls, interview notes — বাংলায়।
এই ধাপে object-এর ভেতরের গভীর, সূক্ষ্ম বিষয়গুলো — যেগুলো interview-এ ও বড় codebase-এ পার্থক্য গড়ে।
Value বনাম Reference
const a = { name: "আনামুল" };
const b = a; // reference — একই object
const c = { ...a }; // নতুন object
console.log(a === b); // true (একই)
console.log(a === c); // false (আলাদা object)
console.log(a.name === c.name); // true (মান এক)Primitive মান দিয়ে, object reference দিয়ে যায়। তাই object প্যারামিটার হিসেবে পাঠালে function-এর ভেতরে বদলানো হলে বাইরের object-ও বদলে যায়।
Shallow বনাম Deep copy
const user = {
name: "আনামুল",
address: { city: "ঢাকা" },
};
// Shallow — উপরের স্তর আলাদা, ভেতরের object একই
const shallow = { ...user };
shallow.address.city = "চট্টগ্রাম";
console.log(user.address.city); // "চট্টগ্রাম" — বদলে গেল!
// Deep — সব স্তর আলাদা
const deep = structuredClone(user);
deep.address.city = "খুলনা";
console.log(user.address.city); // "চট্টগ্রাম" — অপরিবর্তিতnested data থাকলে deep copy-র জন্য structuredClone() সবচেয়ে নির্ভরযোগ্য। JSON-based JSON.parse(JSON.stringify(obj)) কাজ করে, তবে function/undefined/date হারায়।
Optional chaining (?.) ও nullish (??)
const user = {
name: "আনামুল",
address: { city: "ঢাকা" },
};
// ?. — মাঝখানে undefined হলে crash না করে undefined
console.log(user.phone?.number); // undefined
console.log(user.address?.city); // ঢাকা
// ?? — null/undefined হলে ডিফল্ট
const city = user.address?.city ?? "অজানা";
console.log(city); // ঢাকা
console.log(user.email ?? "no-email"); // no-email?. দেয় safely access — chain-এর কোনো অংশ না থাকলে error ছাড়াই undefined। ?? দেয় ডিফল্ট মান — শুধু null/undefined-এর জন্য (0 বা empty string override করে না, ||-এর মতো নয়)।
Freeze ও Seal
const config = Object.freeze({ api: "v1", debug: false });
config.debug = true; // হবে না (silently fails / strict-mode-এ error)
console.log(config.debug); // false
// freeze: কোনো নতুন key / delete / modify — কিছুই হতে দেওয়া হয় না
const settings = Object.seal({ theme: "dark" });
settings.lang = "bn"; // নতুন key যোগ হবে না
console.log(settings); // { theme: "dark" }
// seal: যোগ/delete নয়, কিন্তু বর্তমান key-এর মান বদলানো যায়
settings.theme = "light";
console.log(settings); // { theme: "light" }Getter ও Setter
const user = {
firstName: "আনামুল",
lastName: "হাসান",
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set fullName(value) {
[this.firstName, this.lastName] = value.split(" ");
},
};
console.log(user.fullName); // "আনামুল হাসান" (function ছাড়াই)
user.fullName = "প্রিয়াঞ্জলী দাস";
console.log(user.firstName); // প্রিয়াঞ্জলী
console.log(user.fullName); // "প্রিয়াঞ্জলী দাস"Prototype
const laptop = {
brand: "Lenovo",
boot() {
return "Boot হচ্ছে...";
},
};
const thinkPad = Object.create(laptop);
thinkPad.model = "X1";
// laptop-এর property নিজের না থেকেও অ্যাক্সেস হয়
console.log(thinkPad.brand); // Lenovo (inherited)
console.log(thinkPad.boot()); // "Boot হচ্ছে..."
console.log(thinkPad.model); // X1 (নিজের)Object.create(parent) দিয়ে prototype-based inheritance — child নিজের property রাখে, আর না পাওয়া property parent-এ খোঁজে। class syntax-ও আসলে prototype-ই।
this-এর নিয়ম
const obj = {
name: "আনামুল",
regular() {
return this.name; // obj-কে বোঝায়
},
arrow: () => {
return this.name; // বাইরের scope-এর this (এখানে undefined)
},
};
console.log(obj.regular()); // আনামুল
console.log(obj.arrow()); // undefinedregular function-এ this = যেভাবে call করা হয়েছে (সাধারণত obj)। arrow function-এর নিজের this থাকে না — বাইরের (lexical) scope থেকে নেয়, তাই object method-এ arrow ব্যবহার এড়িয়ে চলুন।
Common pitfalls
// ১. object-কে === দিয়ে তুলনা
console.log({ a: 1 } === { a: 1 }); // false — reference তুলনা
// ২. অবশ্যই JSON compare দরকার?
const a = { x: 1 }, b = { x: 1 };
const same = JSON.stringify(a) === JSON.stringify(b);
console.log(same); // true (সহজ কৌশল, তবে key-order-এ সংবেদনশীল)
// ৩. undefined property delete-এর পরে
const o = { a: 1 };
delete o.a;
console.log("a" in o); // false
// ৪. numbers/booleans object-এ সাধারণ `{}` না — `[]` ব্যবহার
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // falseInterview notes
// Q: object-কে shallow copy?
const copy = { ...obj };
// Q: deep copy?
const copy2 = structuredClone(obj);
// Q: property আছে কিনা?
console.log("name" in obj || obj.hasOwnProperty("name"));
// Q: object থেকে array?
console.log(Object.entries(obj)); // [[key, value], ...]
// Q: কীভাবে merge?
const merged = { ...a, ...b };object-এ কোনো built-in length নেই — size পেতে Object.keys(obj).length ব্যবহার করুন। loop চলানোর সময় for...in চাইলে hasOwnProperty-এর দিক খেয়াল রাখুন; সাধারণত Object.entries()-ই পরিষ্কার।
ছোট, নির্দিষ্ট collection-এ object; ক্রমান্বয়িত/একই-ধরনের ডেটায় array। dynamic key-এর জায়গায় object-কে map-এর মতো ব্যবহার করবেন না — Map আলাদা সুবিধা মেলে।