Prototypes
MedPrototypes are JavaScript's mechanism for inheritance. Every object has a hidden [[Prototype]] link to another object. When you access a property, JS looks up the prototype chain until it finds it or reaches null.
Interactive Visualization
Understanding Prototypes
Prototypes are JavaScript's built-in mechanism for inheritance and shared behavior between objects. Unlike classical languages like Java or C++ that use class-based inheritance, JavaScript uses a prototype chain — a linked list of objects where property lookups travel upward until the property is found or the chain ends at null.
Every object in JavaScript has an internal link called [[Prototype]], which you can access using Object.getPrototypeOf() or the older __proto__ property. When you try to read a property on an object and it does not exist on the object itself, JavaScript automatically looks at the object's prototype, then the prototype's prototype, and so on up the chain. This is called prototype chain delegation and is how methods like toString() and hasOwnProperty() are available on every object even though you never defined them — they are inherited from Object.prototype at the top of the chain.
A common source of confusion is the difference between __proto__ and the .prototype property. Every function in JavaScript has a .prototype property, but this is not the function's own prototype. Instead, it is the object that will become the [[Prototype]] of any new instances created with the new keyword. When you write new Person("Alice"), the newly created object's __proto__ is set to Person.prototype. This is how constructor functions share methods across all instances without duplicating them in memory.
ES6 classes are syntactic sugar over this prototype-based system. When you write class Dog extends Animal, JavaScript sets up the prototype chain so that Dog.prototype.__proto__ points to Animal.prototype. The extends keyword, constructor, and super are all just cleaner syntax for prototype operations that have always existed in the language. Understanding this is important because class-based mental models can lead to confusion when JavaScript's prototype behavior does not match expectations — for example, properties defined in a constructor are own properties on each instance, while methods defined in the class body are shared via the prototype.
One practical use of prototype knowledge is creating objects with no prototype using Object.create(null). These bare objects have no inherited properties, making them ideal for use as dictionaries or lookup maps where you do not want collisions with built-in methods like toString or constructor. This pattern is common in library internals and interview discussions about object safety.
Key Points
- Every object has a [[Prototype]] (accessible via __proto__ or Object.getPrototypeOf)
- Property lookup walks up the prototype chain
- Functions have a .prototype property used for constructor instances
- Object.create() creates objects with a specific prototype
- ES6 classes are syntactic sugar over prototypes
Code Examples
Basic Prototype Chain
const animal = { eats: true, walk() { console.log("Walking"); } }; const dog = { barks: true }; dog.__proto__ = animal; dog.barks; // true (own property) dog.eats; // true (from prototype) dog.walk(); // "Walking" (from prototype)
JS walks up __proto__ links to find properties
Simple Object Literal
const obj = { x: 1 }; // All objects inherit from Object.prototype obj.__proto__ === Object.prototype // true // That's why we can use: obj.toString(); // "[object Object]" obj.hasOwnProperty("x"); // true // These methods come from Object.prototype
Object literals inherit from Object.prototype
Object.create()
const parent = { greet() { console.log("Hello from " + this.name); } }; const child = Object.create(parent); child.name = "Child"; child.greet(); // "Hello from Child" // Object.create() sets the prototype Object.getPrototypeOf(child) === parent // true
Create object with specific prototype
Property Shadowing
const parent = { name: "Parent", greet() { return "Hi from " + this.name; } }; const child = Object.create(parent); child.name = "Child"; // shadows parent.name child.greet(); // "Hi from Child" // child.name shadows parent.name // but greet() is still from parent
Child property hides parent property
Constructor Function
function Person(name) { this.name = name; } Person.prototype.greet = function() { console.log("Hi, I'm " + this.name); }; const alice = new Person("Alice"); const bob = new Person("Bob"); alice.greet(); // "Hi, I'm Alice" bob.greet(); // "Hi, I'm Bob" // Both share the same greet method! alice.greet === bob.greet // true
Instances inherit from Constructor.prototype
hasOwnProperty Check
const parent = { inherited: true }; const child = Object.create(parent); child.own = true; // hasOwnProperty: only own properties child.hasOwnProperty("own"); // true child.hasOwnProperty("inherited"); // false // 'in' operator: checks entire chain "own" in child; // true "inherited" in child; // true // Useful for safe iteration for (let key in child) { if (child.hasOwnProperty(key)) { console.log(key); // only "own" } }
hasOwnProperty checks only object, "in" checks chain
Object.create(null)
// Normal object has prototype const normal = {}; normal.toString; // [Function] // Null prototype = truly empty const dict = Object.create(null); dict.toString; // undefined // Safe dictionary (no collisions) dict["hasOwnProperty"] = "safe!"; dict.hasOwnProperty; // "safe!" // With normal object this would // shadow the built-in method
No prototype = no inherited methods, safe dictionaries
Class Syntax (ES6)
class Animal { constructor(name) { this.name = name; } speak() { console.log(this.name + " makes a sound"); } } class Dog extends Animal { speak() { console.log(this.name + " barks"); } } const dog = new Dog("Rex"); dog.speak(); // "Rex barks" // Classes are syntactic sugar! // Under the hood: prototypes
Classes are syntactic sugar over prototypes
Common Mistakes
- Confusing __proto__ with .prototype
- Modifying Object.prototype (affects all objects!)
- Not understanding that arrays/functions are also objects with prototypes
Interview Tips
- Draw the prototype chain for a given object
- Explain the difference between __proto__ and .prototype
- Know how ES6 classes relate to prototypes