C
JavaScript/Advanced/Lesson 20

Prototype — *Object-Oriented JS*

45 min·theory
This chapter
2/2

Prototype — *Object-Oriented JS*

🎯 After reading this lesson

After finishing this lesson, you will be confident in the following three things.

  • ✅ How the prototype chain + __proto__ works
  • ✅ Why class is syntactic sugar over prototypes
  • ✅ Comparing Object.create vs the new keyword

Keep the learning goals as a checklist, and close the lesson once you can answer all of them.

What is a prototype?

Key takeaway

JS object-orientation is prototype-based, not class-based. Every object has a parent object (its prototype) and inherits methods from it.

How it differs from other languages

python
# Python (class-based)
class Animal:
    def speak(self): print("Sound")

class Dog(Animal):
    pass

d = Dog()
d.speak()   # "Sound" (inherited from Animal)
javascript
// JS (prototype-based)
const animal = {
    speak() { console.log("Sound"); }
};

const dog = Object.create(animal); // animal as prototype

dog.speak(); // "Sound" (found on animal)

code

*Objects inherit directly from other objects* — there is no *template step* called a class.

## Prototype chain

javascript

const a = { x: 1 }; // top-level parent — holds x

const b = Object.create(a); // b's parent = a

const c = Object.create(b); // c's parent = b

console.log(c.x); // 1

//

// 🔎 How was c.x found? Walk up the chain:

// ① c itself → no x

// ② c's parent b → no x

// ③ b's parent a → x = 1 found! ✅

//

// 💡 This is the "prototype chain" — how JS looks up properties

code

When a property is requested, JS *walks up* until it finds it. That is the **prototype chain**.

## The `class` syntax — *just sugar*

ES6 (2015) introduced the `class` keyword, but *the internals are still prototypes*.

javascript

class Animal {

speak() { console.log("sound"); }

}

class Dog extends Animal { // inherits from Animal
bark() { console.log("Woof woof"); }
}

const d = new Dog();

d.speak(); // "Sound" ← not on Dog → found on Animal

d.bark(); // "Woof woof" ← on Dog → used directly

code

You can write in a *class-based style*, but under the hood:

javascript

Dog.prototype.__proto__ === Animal.prototype; // true

d.__proto__ === Dog.prototype; // true

code

The prototype chain is still there.

## Commonly seen prototype methods

javascript

const arr = [1, 2, 3];

// 🔎 Who is arr's parent?
console.log(arr.__proto__ === Array.prototype); // true
console.log(arr.map(x => x * 2)); // [2, 4, 6]
// ↑ map is defined on Array.prototype, not on arr itself!

const s = "hello";
console.log(s.__proto__ === String.prototype); // true
console.log(s.toUpperCase()); // "HELLO"
// ↑ toUpperCase is also defined on String.prototype and shared

// 💡 Every array/string "shares" methods → no copy per instance → higher memory efficiency

code

All *built-in methods* (map, filter, toUpperCase, etc.) are defined on *prototypes* and *shared* by every array or string. Memory efficiency ↑.

## Building one yourself

javascript

function Animal(name) {

this.name = name;

}

Animal.prototype.speak = function() {

console.log(${this.name}: sound);

};

const a = new Animal("Puppy");

a.speak(); // "Puppy: sound"

code

This is the old *constructor function* style. Today the *class* syntax is cleaner — use class almost always.

Common pitfalls

1. Arrow functions have no prototype:

javascript
const Foo = () => {};
new Foo();   // ❌ TypeError

2. Directly mutating __proto__ is dangerous:

javascript
obj.__proto__ = anotherObj;   // possible but hurts performance
// Use Object.create() or Object.setPrototypeOf() instead

3. Surprising behavior of for...in:

javascript
for (const key in obj) { ... }
// Iterates over both own + *inherited* properties
// Own properties only: Object.keys(obj) or obj.hasOwnProperty(key)

Summary

  • JS = prototype-based object-orientation
  • Every object has a parent (prototype)
  • class is syntactic sugar — prototypes underneath
  • The mechanism behind inheritance and method sharing

⚡ Try it yourself — class inheritance + prototype chain

Verify for yourself that class inheritance is, internally, a prototype chain.
✏️ JS 코드
📟 Console output
▶ Press the Run button
⚠️ Runs in a browser sandbox — only console.log() is supported; alert/fetch are not.

🤖 Try asking AI this

Knowing the concepts in this lesson lets you give AI specific instructions — not a vague "fix this" but a vocabulary-driven request. That is where token savings begin.

  • "Add appropriate TypeScript type annotations to this variable"
  • "Unify this mix of === and == to use === consistently and make the intent clear"
  • "Add unknown type + a type guard to the JSON.parse result in this code"

Why does this reduce tokens?

Without the concepts, you still have to ask "What does that mean?" after every AI response. Those follow-up questions eat tokens. Learn the concept once and the conversation ends in one turn.

Prototypes - JavaScript