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
- Constructor + prototype method; confirm two instances share it.
- Prove greet is NOT an own property via hasOwn.
- Build animal→dog chain with Object.create; override sound.
- Add a method after instantiation; verify old objects see it.
- Class + extends + super; check the chain with getPrototypeOf.
- 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.