Objects: Properties, Methods & this

Object — property, method ও this

Read: ~35 min Intermediate 16 practice problems Live in-browser runner

1. What Is an Object?

In JavaScript an object is an unordered collection of key → value pairs. Almost everything in JS that is not a primitive — arrays, functions, dates, regex, even modules — is an object under the hood. Mastering objects is therefore the single biggest step from "I know syntax" to "I can build software."

JavaScript-এ object হলো key → value জোড়ার একটি collection। JS-এ primitive ছাড়া প্রায় সব কিছু — array, function, Date, regex — আসলে object। তাই object ভালোভাবে বুঝতে পারাই হলো "syntax জানা" থেকে "software বানাতে পারা"-এর মূল ধাপ।
first-object.js
// An object literal — the most common way to make an object
const student = {
    name: "Rahim",
    age: 21,
    department: "CSE",
    isEnrolled: true
};

console.log(student);
console.log(`Hello ${student.name}, age ${student.age}`);

2. Property Access — Dot vs Bracket

There are two ways to read or write a property: dot notation (obj.key) and bracket notation (obj["key"]). They do the same thing — but bracket notation is required when the key is dynamic, contains spaces, or starts with a digit.

UseDotBracket
Static key, valid identifier✅ user.name✅ user["name"]
Key in a variable❌✅ user[key]
Key with space / dash❌✅ obj["full name"]
Key that starts with a digit❌✅ obj["404"]
Static সাধারণ key হলে dot notation সহজ। কিন্তু key যদি variable-এ থাকে, space থাকে বা digit দিয়ে শুরু হয় — তখন bracket notation বাধ্যতামূলক।
access.js
const user = { name: "Sadia", "home town": "Dhaka" };

console.log(user.name);              // Sadia
console.log(user["home town"]);     // Dhaka — dot would fail

const field = "name";
console.log(user[field]);             // Sadia — dynamic key

// Reading a missing property returns undefined (not an error)
console.log(user.email);             // undefined

3. Computed Property Names & Shorthand

ES6 added two ergonomics that you will use every day: computed property names {[expr]: value} and property shorthand {x, y} when the key and the variable share the same name.

shorthand.js
const name = "Karim";
const age = 19;

// Old way
const v1 = { name: name, age: age };

// Shorthand — same effect, less noise
const v2 = { name, age };

// Computed key — the key is the value of an expression
const field = "score";
const v3 = { [field]: 95, [`${field}_max`]: 100 };

console.log(v2);
console.log(v3);
{name, age} মানে {name: name, age: age}। আর {[field]: 95}-এ field-এর মান (এখানে "score") key হিসেবে বসে। React, Redux ইত্যাদি library-তে এই দুটি pattern প্রতিদিন ব্যবহৃত হয়।

4. Methods — Functions That Live on Objects

A property whose value is a function is called a method. ES6 lets you write methods without the function keyword — just name() { ... } inside the object literal.

methods.js
const account = {
    owner: "Nadia",
    balance: 5000,

    // ES6 shorthand method — no `function` keyword
    deposit(amount) {
        this.balance += amount;
        return this.balance;
    },

    withdraw(amount) {
        if (amount > this.balance) return "Not enough funds";
        this.balance -= amount;
        return this.balance;
    }
};

console.log(account.deposit(2000));   // 7000
console.log(account.withdraw(3000));  // 4000
console.log(account.balance);          // 4000

5. The this Keyword — Four Binding Rules

this is the most misunderstood word in JavaScript. The trick: where a function is called decides what this means — not where the function was written. There are exactly four rules, applied in this priority order:

  1. new binding — called with new f(), this is the new instance.
  2. Explicit binding — f.call(obj), f.apply(obj), or f.bind(obj): this is obj.
  3. Implicit binding — called as obj.f(): this is obj.
  4. Default binding — plain f(): this is undefined in strict mode (or the global object in sloppy mode).
this-এর মান নির্ভর করে ফাংশনটি কীভাবে call হলো তার উপর — কোথায় লেখা হয়েছিল তাতে নয়। চারটি rule আছে — new, explicit (call/apply/bind), implicit (obj.f()), এবং default। এই priority অনুযায়ীই JS এই মান ঠিক করে।
this-rules.js
function whoAmI() {
    return this && this.label ? this.label : "<no label>";
}

const a = { label: "A", fn: whoAmI };
const b = { label: "B" };

console.log(a.fn());                // "A"  — implicit
console.log(whoAmI.call(b));          // "B"  — explicit
const bound = whoAmI.bind({ label: "C" });
console.log(bound());                 // "C"  — bind

// Losing `this`: pass the method as a callback
const looseRef = a.fn;
console.log(looseRef());              // "<no label>" — default
The classic "lost this" bug Passing obj.method as a callback (e.g. setTimeout(obj.method, 100)) detaches it from obj. By the time it runs, this is no longer your object. Fix with .bind(obj) or wrap in an arrow function: setTimeout(() => obj.method(), 100).

6. Arrow Functions and Lexical this

Arrow functions are different. They do not get their own this — they inherit this from the surrounding (lexical) scope where they were defined. This is exactly what you usually want inside callbacks.

arrow-this.js
const timer = {
    seconds: 0,
    start() {
        // Arrow inherits `this` from start() — so this.seconds works
        const tick = () => {
            this.seconds++;
            console.log(`tick ${this.seconds}`);
        };
        tick(); tick(); tick();
    }
};

timer.start();
// Output: tick 1, tick 2, tick 3
Rule of thumb Use a normal method when you want this to be the object the method is called on. Use an arrow function inside callbacks where you want to keep the outer this.

7. Iterating Objects — keys / values / entries

for...in exists but iterates inherited keys too — usually not what you want. Prefer the three Object static methods:

iterate.js
const prices = { rice: 75, oil: 180, sugar: 110 };

console.log(Object.keys(prices));    // ["rice","oil","sugar"]
console.log(Object.values(prices));  // [75,180,110]
console.log(Object.entries(prices)); // [["rice",75], ...]

let total = 0;
for (const [item, price] of Object.entries(prices)) {
    console.log(`${item} = ${price}৳`);
    total += price;
}
console.log(`Total = ${total}৳`);
Object.keys/values/entries — এই তিনটি method সবচেয়ে নিরাপদ ও আধুনিক উপায়। for...of-এর সাথে destructuring মিলিয়ে আপনি যেকোনো object-এর ওপর সহজে loop চালাতে পারেন।

8. Freezing, Sealing & Spread/Merge

Objects are mutable by default. JS gives you two locks: Object.freeze() (no add, no change, no delete — fully immutable shallow lock) and Object.seal() (no add or delete, but existing properties can still be changed).

freeze-seal.js
"use strict";

const config = Object.freeze({ host: "localhost", port: 3000 });
try {
    config.port = 8080;          // silently ignored OR throws in strict mode
} catch (e) {
    console.log("Frozen — cannot change: " + e.message);
}
console.log(config);                 // { host:'localhost', port:3000 }

const sealed = Object.seal({ a: 1 });
sealed.a = 99;                       // allowed
sealed.b = 2;                        // blocked — cannot add new keys
console.log(sealed);                 // { a: 99 }

Spread {...obj} creates a shallow copy and is the modern way to merge objects:

spread-merge.js
const defaults = { theme: "light", fontSize: 14, lang: "en" };
const userPrefs = { theme: "dark", fontSize: 16 };

// Later keys win — userPrefs override defaults
const settings = { ...defaults, ...userPrefs };
console.log(settings);
// { theme: 'dark', fontSize: 16, lang: 'en' }

9. Shallow vs Deep Copy — and structuredClone

Spread and Object.assign only copy one level deep. Nested objects are shared by reference. Three options for a true deep copy, in increasing power:

JSON.parse(JSON.stringify(obj))

  • Old trick — works for plain JSON-safe data
  • Drops functions, dates become strings
  • Throws on circular references

structuredClone(obj) ⭐ modern

  • Built-in since 2022 (all modern browsers + Node 17+)
  • Handles Map, Set, Date, ArrayBuffer, circular refs
  • The new default deep clone
deep-clone.js
const original = {
    name: "Tania",
    address: { city: "Sylhet", zip: "3100" }
};

// Shallow copy — nested address is SHARED
const shallow = { ...original };
shallow.address.city = "Chattogram";
console.log(original.address.city); // "Chattogram" — leaked!

// Deep copy — completely independent
const deep = structuredClone(original);
deep.address.city = "Khulna";
console.log(original.address.city); // still "Chattogram"
console.log(deep.address.city);     // "Khulna"
Spread shallow copy করে — nested object reference-এ থাকে। Deep copy দরকার হলে আজকের সঠিক উত্তর হলো structuredClone()। পুরোনো কোডে JSON.parse(JSON.stringify()) দেখা গেলেও সেটির অনেক সীমাবদ্ধতা আছে।

10. Glossary (শব্দকোষ)

TermMeaningবাংলায়
Object literalInline { key: value } syntax for creating an object.সরাসরি { key: value } syntax-এ object তৈরি।
PropertyA key-value pair on an object.Object-এর key-value জোড়া।
MethodA function stored as a property of an object.Object-এর property হিসেবে রাখা function।
Computed keyDynamic property name written as [expr].Dynamic key — [expr] দিয়ে লেখা হয়।
thisThe receiver of a method call; one of 4 binding rules decides it.Method-এর receiver — চারটি rule থেকে একটি প্রয়োগ হয়।
bindReturns a new function with this permanently fixed.this নির্দিষ্ট করে নতুন function ফেরত দেয়।
Spread ...Expands properties; shallow copy/merge.Property গুলোকে expand করে; shallow copy/merge।
structuredCloneBuilt-in deep-clone for plain objects, arrays, dates, maps, sets.Built-in deep-clone — nested object সব copy হয়।
Object.freezeMarks an object's own properties non-writable (shallow).Top-level property গুলো immutable করে — shallow।
সংক্ষেপে: Object তৈরি, পড়া, পরিবর্তন, copy, freeze — প্রতিটির জন্য আধুনিক API আছে। Object.keys/values/entries দিয়ে iterate; merge-এ {...a, ...b}; deep-clone-এ structuredClone। this-এর চারটি rule (default, implicit, explicit/bind, new) মুখস্থ থাকলে অর্ধেক JS bug দূর হয়। Arrow function-এর নিজস্ব this নেই — তাই object method হিসেবে arrow ব্যবহার করবেন না।

11. Practice Problems

Try each problem yourself first, then click Show Answer to compare. Most answers are runnable right here in the browser.

প্রতিটি প্রশ্নে আগে নিজে চেষ্টা করুন, তারপর Show Answer বাটনে ক্লিক করুন। বেশিরভাগ উত্তর এই পেজেই সরাসরি চালানো যাবে।
  1. Create an object book with title, author and pages, and print each on its own line.
    title, author এবং pages-সহ একটি book object বানিয়ে প্রতিটি আলাদা লাইনে প্রিন্ট করুন।
    ✨ Show Answer (উত্তর দেখুন)
    ans1.js
    const book = { title: "Pother Panchali", author: "Bibhutibhushan", pages: 320 };
    console.log(`Title : ${book.title}`);
    console.log(`Author: ${book.author}`);
    console.log(`Pages : ${book.pages}`);
  2. Given const key = "score", create an object whose key is score and value is 90 — using a computed property name.
    computed property name ব্যবহার করে এমন object বানান যার key হবে score এবং মান 90।
    ✨ Show Answer (উত্তর দেখুন)
    ans2.js
    const key = "score";
    const obj = { [key]: 90 };
    console.log(obj);
    console.log(obj.score);
  3. Build a rectangle object with width, height, and an area() method that uses this.
    width, height এবং একটি area() method-সহ একটি rectangle object বানান, যেখানে this ব্যবহার করতে হবে।
    ✨ Show Answer (উত্তর দেখুন)
    ans3.js
    const rectangle = {
        width: 8,
        height: 5,
        area() { return this.width * this.height; }
    };
    console.log(`Area = ${rectangle.area()}`);
  4. Use Object.keys to count how many properties a given object has.
    Object.keys ব্যবহার করে একটি object-এর কয়টি property আছে গণনা করুন।
    ✨ Show Answer (উত্তর দেখুন)
    ans4.js
    const obj = { a: 1, b: 2, c: 3, d: 4 };
    console.log(`Property count = ${Object.keys(obj).length}`);
  5. Use Object.entries + for...of to print all key = value pairs of { rice: 75, oil: 180, sugar: 110 }.
    Object.entries ও for...of দিয়ে object-এর প্রতিটি key-value প্রিন্ট করুন।
    ✨ Show Answer (উত্তর দেখুন)
    ans5.js
    const prices = { rice: 75, oil: 180, sugar: 110 };
    for (const [k, v] of Object.entries(prices)) {
        console.log(`${k} = ${v}৳`);
    }
  6. Predict the output: const f = obj.method; f(); when method uses this.x. Why is the result undefined?
    যখন method-এ this.x ব্যবহার হয়, const f = obj.method; f(); চালালে কেন undefined আসে?
    ✨ Show Answer (উত্তর দেখুন)

    Answer: Detaching obj.method into f drops the implicit binding. Calling f() uses default binding — in strict mode this is undefined, so this.x throws or yields undefined. Fix with const f = obj.method.bind(obj).

    obj.method-কে আলাদা variable-এ রাখলে implicit binding চলে যায়। তখন this default-এ চলে আসে — strict mode-এ undefined। সমাধান: obj.method.bind(obj)।

  7. Show that call and apply do the same thing — only argument passing differs.
    প্রমাণ করুন call এবং apply একই কাজ করে — শুধু argument পাঠানোর ভঙ্গি ভিন্ন।
    ✨ Show Answer (উত্তর দেখুন)
    ans7.js
    function greet(g, p) { return `${g}, ${this.name}${p}`; }
    const me = { name: "Imran" };
    console.log(greet.call(me, "Hello", "!"));
    console.log(greet.apply(me, ["Hello", "!"]));
  8. Demonstrate that an arrow function inside a method keeps the outer this.
    প্রমাণ করুন method-এর ভিতরে arrow function বাইরের this ধরে রাখে।
    ✨ Show Answer (উত্তর দেখুন)
    ans8.js
    const obj = {
        name: "Riya",
        delayedHi() {
            setTimeout(() => console.log(`Hi ${this.name}`), 10);
        }
    };
    obj.delayedHi();
  9. Make an object frozen and show that mutation in strict mode throws.
    একটি object freeze করে দেখান strict mode-এ mutation চেষ্টা করলে error হয়।
    ✨ Show Answer (উত্তর দেখুন)
    ans9.js
    "use strict";
    const p = Object.freeze({ pi: 3.14 });
    try { p.pi = 3; }
    catch (e) { console.log("Error: " + e.message); }
    console.log(p.pi);
  10. Merge default settings with user settings using spread, and show user values win.
    spread দিয়ে default settings-এর ওপর user settings মিশিয়ে দেখান user-এর মান জেতে।
    ✨ Show Answer (উত্তর দেখুন)
    ans10.js
    const defaults = { theme: "light", lang: "en", font: 14 };
    const user = { theme: "dark", font: 18 };
    const merged = { ...defaults, ...user };
    console.log(merged);
  11. Show that a shallow spread copy of an object with a nested object still shares the nested reference.
    shallow copy করলে যে nested object reference share হয় — সেটি প্রমাণ করুন।
    ✨ Show Answer (উত্তর দেখুন)
    ans11.js
    const a = { x: 1, nested: { y: 2 } };
    const b = { ...a };
    b.nested.y = 99;
    console.log(a.nested.y); // 99 — shared
    console.log(b.nested.y); // 99
  12. Use structuredClone to deep-copy a nested object and prove the inner object is now independent.
    structuredClone দিয়ে deep copy করে দেখান ভিতরের object আর share হয় না।
    ✨ Show Answer (উত্তর দেখুন)
    ans12.js
    const a = { nested: { y: 2 } };
    const b = structuredClone(a);
    b.nested.y = 99;
    console.log(a.nested.y); // 2 — untouched
    console.log(b.nested.y); // 99
  13. Build a counter object with value, inc(), dec(), and reset() methods.
    value এবং inc/dec/reset method-সহ একটি counter object বানান।
    ✨ Show Answer (উত্তর দেখুন)
    ans13.js
    const counter = {
        value: 0,
        inc() { this.value++; return this; },
        dec() { this.value--; return this; },
        reset() { this.value = 0; return this; }
    };
    counter.inc().inc().inc().dec();
    console.log(counter.value); // 2
    counter.reset();
    console.log(counter.value); // 0
  14. Demonstrate Object.values with reduce to sum all numeric values of an object.
    Object.values এবং reduce-এ object-এর সব মান যোগ করে দেখান।
    ✨ Show Answer (উত্তর দেখুন)
    ans14.js
    const bills = { electric: 1200, gas: 450, internet: 800 };
    const total = Object.values(bills).reduce((s, n) => s + n, 0);
    console.log(`Total bill = ${total}৳`);
  15. In one paragraph, explain why arrow functions are the wrong choice for object methods that need this.
    কেন arrow function কোনো method-এ this দরকার হলে ব্যবহার করা উচিত নয় — এক অনুচ্ছেদে ব্যাখ্যা করুন।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: Arrow functions inherit this from the enclosing lexical scope at the moment they are defined, not from how they are called. When you write a method as an arrow, that lexical scope is usually the module or the global scope — not the object — so this ends up undefined instead of the object you expected. Use a regular method (or shorthand name() {}) for object methods, and reserve arrows for inner callbacks.

    Arrow function-এ this ঠিক হয় যেখানে এটি লেখা হয়েছে সেখান থেকে — যেখান থেকে call হচ্ছে সেখান থেকে নয়। তাই কোনো object-এর method হিসেবে arrow ব্যবহার করলে this object না হয়ে module বা global scope হয়ে যায়। তাই method লিখতে regular function বা shorthand name() {} ব্যবহার করুন; callback-এ arrow।

  16. Write a function renameKey(obj, oldKey, newKey) that returns a new object with the key renamed (without mutating the input).
    renameKey(obj, oldKey, newKey) ফাংশন লিখুন যা mutate না করে একটি নতুন object দেবে যেখানে নাম বদল হয়েছে।
    ✨ Show Answer (উত্তর দেখুন)
    ans16.js
    function renameKey(obj, oldKey, newKey) {
        const { [oldKey]: value, ...rest } = obj;
        return { ...rest, [newKey]: value };
    }
    
    const u = { id: 1, name: "Mim", city: "Dhaka" };
    console.log(renameKey(u, "name", "fullName"));
    console.log(u); // untouched

Summary — Module 13

An object is a bag of key→value pairs. Use dot notation for static keys, brackets for dynamic ones. ES6 gives you shorthand and computed keys. Methods carry behavior. this follows four binding rules — new > explicit > implicit > default — and arrow functions break the chain by inheriting this lexically. Iterate with Object.keys/values/entries, lock with freeze/seal, merge with spread, and deep-copy with the modern structuredClone.

Object হলো key→value-এর সংগ্রহ। সাধারণ key-এ dot, dynamic-এ bracket। ES6-এর shorthand ও computed key খুব প্রয়োজনীয়। this-এর চারটি binding rule আছে — new, explicit, implicit, default — এবং arrow function lexical-ভাবে this ধার করে। Iterate-এ Object.keys/values/entries, লক করতে freeze/seal, merge-এ spread, আর deep clone-এ modern structuredClone।

Next Module → Arrays & Iteration: map, filter, reduce — যেখানে আপনি 90% for-loop বাদ দিয়ে আধুনিক functional JS শিখবেন।