JS::OOP_Mastery
Overview / Session 01
Session 01 of 10  ·  2 hrs + 15 min review

Why OOP? Objects & Object Literals

⏱ 2-hour session 📋 15-min review 🟢 No prerequisites 🗂 4 topics

1 — Why Group Data and Behaviour Together?

JavaScript lets you write code in almost any style — functions scattered across files, plain arrays and objects passed everywhere, callbacks nested inside callbacks. That flexibility is also the problem. As soon as a project grows past a few hundred lines, "what shape is this data supposed to be?" and "what's allowed to change it?" become real questions nobody can answer just by reading.

Object-Oriented Programming is one answer to those questions. The core idea: bundle data (what something is) and behaviour (what it does) into a single unit — an object. Instead of a loose record passed between unrelated functions, you get a self-contained thing that knows how to manage itself.

Side-by-side comparison

Imagine tracking a user's name and email and sending them a welcome message.

JavaScript — Scattered functions
// Data is a loose object, functions are global and unrelated to it
let user = { name: 'Alice', email: 'alice@example.com' };

function sendWelcome(u) {
    console.log(`Welcome, ${u.name}! Check ${u.email}`);
}

sendWelcome(user);
// Nothing stops anyone from doing user.email = null anywhere in the file
JavaScript — Object-Oriented
// Data and behaviour live together on the object itself
const user = {
    name: 'Alice',
    email: 'alice@example.com',
    sendWelcome() {
        console.log(`Welcome, ${this.name}! Check ${this.email}`);
    }
};

user.sendWelcome();
// The method travels with the data — no separate function to hunt for

This is a small example, but the principle scales. When you need to add a profile picture, a role, or a verification flag, you add it to the object that already owns the related logic — not hunt through the codebase for every function that happens to touch a user-shaped value.

The four pillars — a quick map

You'll hear these constantly. Know what they mean before you go further:

  • Encapsulation — bundle data + behaviour; control what's exposed. (Sessions 1, 2, 4)
  • Inheritance — build new classes on top of existing ones. (Session 5)
  • Abstraction — expose only what's necessary; hide the rest. (Sessions 4, 7)
  • Polymorphism — different objects, same interface, different behaviour. (Session 6)

2 — Object Literals: The Simplest Object

The fastest way to make an object in JavaScript is the object literal — curly braces with key-value pairs. No class, no constructor, no new. This is where most JS objects in the wild actually come from: config objects, API responses, component props, state shapes.

JavaScript — Anatomy of an object literal
const cart = {
    // properties — the data
    items: [],
    discountRate: 0.1,

    // methods — the behaviour
    addItem(name, price) {
        this.items.push({ name, price });
    },

    total() {
        const sum = this.items.reduce(
            (acc, item) => acc + item.price, 0
        );
        return sum * (1 - this.discountRate);
    }
};

cart.addItem('Keyboard', 80);
cart.addItem('Mouse', 25);
console.log(cart.total()); // 94.5

Notice this inside the methods. When you call cart.total(), JavaScript sets this to whatever is left of the dot — here, cart itself. That's the mechanism that lets a method reach back into its own object's data.

Shorthand syntax (ES6+)

Modern JS lets you skip repeating a variable name as both key and value, and write methods without the function keyword:

JavaScript — Property & method shorthand
const name = 'Alice';
const email = 'alice@example.com';

// Old way
const userOld = { name: name, email: email };

// Shorthand — same result, identical key/value names collapse
const user = { name, email };

// Method shorthand — no "function" keyword needed
const greeter = {
    name,
    greet() { return `Hi, I'm ${this.name}`; }
};

3 — this Inside Object Methods

this is the single most misunderstood word in JavaScript, and it starts mattering the moment you write your first method. The short version for now — Session 8 covers the full picture, including the bugs it causes: inside a regular method, this refers to the object the method was called on, not the object where the method was defined.

JavaScript — this depends on the call site
const dog = {
    name: 'Rex',
    bark() {
        console.log(`${this.name} says woof!`);
    }
};

dog.bark();              // "Rex says woof!" — this = dog

const justTheFunction = dog.bark;
justTheFunction();           // "undefined says woof!" (or a TypeError in strict mode)
                            // — this is now lost; called with no object before the dot

The lesson for this session: this is decided by how a function is called, not where it was written. That single fact explains roughly 90% of "why doesn't this work" bugs you'll hit later — especially once methods get passed around as callbacks. Keep it in the back of your mind.

4 — Reference vs Value: Objects Aren't Copied Like Numbers

Primitives (number, string, boolean, etc.) are copied by value — each variable gets its own independent copy. Objects are copied by reference — the variable holds a pointer to the same object in memory. This single difference causes more confusion for JS beginners than almost anything else in this session.

JavaScript — primitives vs objects
// Primitives: independent copies
let a = 5;
let b = a;
b = 10;
console.log(a); // 5 — untouched

// Objects: same object, two labels pointing at it
let objA = { value: 5 };
let objB = objA;
objB.value = 10;
console.log(objA.value); // 10 — objA changed too, same object

This is also why comparing two object literals with === is rarely what beginners expect:

JavaScript — identity vs structural equality
const p1 = { x: 1, y: 2 };
const p2 = { x: 1, y: 2 };
const p3 = p1;

console.log(p1 === p2); // false — different objects, same shape
console.log(p1 === p3); // true  — same object, two references

// To copy an object instead of referencing it:
const p4 = { ...p1 };       // spread — shallow copy
const p5 = Object.assign({}, p1); // equivalent shallow copy

"Shallow" matters here: a spread copy duplicates top-level keys, but if a value is itself an object (a nested object or array), both copies still point at that same nested object. Deep copying is a topic for later — for now, know that the default copy you reach for is shallow.

15-Minute Review — Session 01

Stop the session timer and switch to the review timer in the sidebar. Answer these questions from memory — then check.

Q1 — What is the main advantage of grouping data and behaviour together on an object?

Q2 — Inside an object's method, what does this refer to?

Q3 — You write let b = a; where a is an object. You then set b.value = 10. What happens to a.value?

Q4 — Which expression creates a shallow copy of an object obj?

✓ Key concepts checklist

Next: The class Keyword & Instantiation →