</>
Skip to content
JavaScript lessons (53/64)

JavaScript — Object Prototypes

Every object has a prototype

JavaScript is prototype-based: objects can inherit from other objects.

const user = { name: "Alice" };
user.toString();   // works — inherited from Object.prototype!

The prototype chain

user
  ↓
Object.prototype
  ↓
null

Property lookup walks upward until found or null is reached.

Constructor prototypes

Constructors carry a .prototype that all their instances inherit from:

function User(name) { this.name = name; }

User.prototype.greet = function () {
    console.log(`Hello ${this.name}`);
};

const alice = new User("Alice");
const bob   = new User("Bob");
alice.greet();   // both share ONE function
bob.greet();

Why share? Per-instance methods create a new function per object; prototype methods exist once.

Own vs inherited properties

Object.hasOwn(user, "name");      // true  — stored directly
Object.hasOwn(user, "toString");  // false — inherited
"toString" in user;               // true  — in checks the WHOLE chain

That distinction (in vs hasOwn) matters when inspecting data.

Object.create — explicit inheritance

const animal = { speak() { console.log("Animal sound"); } };

const dog = Object.create(animal);
dog.name = "Max";
dog.speak();        // inherited ✓

Chain:

dog → animal → Object.prototype → null

Shadowing — own beats inherited

dog.sound = "woof";       // own property hides prototype's value
console.log(dog.sound);   // "woof"

Prototypes are live

Adding to the prototype later reaches existing instances:

User.prototype.sayBye = function () { console.log("Bye"); };
alice.sayBye();   // works — lookup happens at call time

Classes use prototypes underneath

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

class Dog extends Animal {
    speak() {
        super.speak();          // call parent version
        console.log("Woof");
    }
}

const d = new Dog();
d.speak();
Object.hasOwn(d, "speak");   // false — it's on Dog.prototype!

extends wires the same chains you'd build manually.

Changing prototypes (carefully)

Object.getPrototypeOf(obj);            // read
Object.setPrototypeOf(obj, proto);     // write — avoid casually:

Frequent prototype mutation hurts performance and readability. The legacy obj.__proto__ accessor exists but standard APIs are preferred.

Null-prototype dictionaries

const dict = Object.create(null);   // no inherited keys
dict.apple = "fruit";

Safe as a pure key→value store without toString collisions.

Prototype pollution awareness

Blindly copying untrusted keys onto objects:

for (const key in input) target[key] = input[key];   // dangerous with "__proto__"

Validate input or copy explicitly when handling untrusted data.

Lookup order summary

1. own property
2. object's prototype
3. prototype's prototype
…
n. null → undefined

Mini Practice

  1. Constructor + prototype method; confirm two instances share it.
  2. Prove greet is NOT an own property via hasOwn.
  3. Build animal→dog chain with Object.create; override sound.
  4. Add a method after instantiation; verify old objects see it.
  5. Class + extends + super; check the chain with getPrototypeOf.
  6. Create a null-prototype dictionary; test missing methods.

Next: DOM →

Related Topics

Frequently Asked Questions about Object Prototypes

What is Object Prototypes in JavaScript?

Object Prototypes is a fundamental concept in JavaScript. This lesson explains it step by step with clear examples, making it easy for beginners to understand.

How do I learn Object Prototypes?

Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Object Prototypes.

Why is Object Prototypes important in JavaScript?

Object Prototypes is essential for JavaScript development. Understanding this concept will help you write better code and solve real-world problems more effectively.