Prototypes & Prototypal Inheritance in JS

Unlock the foundation of JavaScript's object-oriented nature by mastering how objects inherit and share functionality.

Lesson ProgressStep 1 of 9
function Animal()
Animal.prototype
const dog = new Animal()
0 EXP

Welcome! Let's explore JavaScript's core: Prototypal Inheritance. It's how objects get their powers.

// The journey begins...

What is a Prototype?

In JavaScript, almost every object has a hidden, internal property called [[Prototype]]. This property is simply a **link** to another object.

When you try to access a property on an object (e.g., `myObj.name`), if the property doesn't exist directly on `myObj`, the JavaScript engine follows the `[[Prototype]]` link and looks for the property on that linked object.

You can access this internal link using the modern Object.getPrototypeOf(myObj) method. (You may also see the legacy myObj.__proto__, but it's discouraged in modern code).

System Check

What is the modern, standard way to get an object's internal [[Prototype]] link?

Advanced Holo-Simulations

0 EXP

Log in to unlock these advanced training modules and test your skills.


Achievements

🏆
Prototype Master

Define a constructor and add a method to its prototype.

🏗️
Chain Navigator

Correctly identify the order of a complex prototype chain.

✍️
Syntax Expert

Fix broken prototype inheritance syntax.

Mission: Build an Inheritance Chain

Follow the instructions in the code to make `Car` inherit from `Vehicle`. This is a classic inheritance pattern. Our AI will guide you.

A.D.A. Feedback:

> System integrity looks stable. Code is valid.

Challenge: Order the Prototype Chain

A `Car` inherits from `Vehicle`. Drag the items into the correct prototype chain order for `carInstance`, starting from the instance (top) to the end of the chain (bottom).

Vehicle.prototype
carInstance
Object.prototype
null
Car.prototype

Challenge: Complete the Syntax

Fill in the missing parts to make `Dog` inherit from `Animal`.

function Animal() {...}Animal.prototype.speak = function() {...}function Dog() {...}
Dog.prototype =(.prototype);
Dog.prototype.constructor =;

Consult A.D.A.

Community Holo-Net

JavaScript's Soul: A Deep Dive into Prototypes

When developers come to JavaScript from languages like Java or C#, they look for "classes" and "inheritance." While JavaScript has a `class` keyword, it's crucial to understand that this is a lie. Well, a "white lie" at best. It's **syntactic sugar** layered over the engine's true, beating heart: **prototypal inheritance**.

Unlike classical inheritance where classes are blueprints and objects are instances, JavaScript's model is simpler: **objects inherit from other objects**. That's it. This article demystifies the system, one link at a time.

The Two "Prototypes" (This is the confusing part)

The number one source of confusion is the word "prototype," which JavaScript uses for two *different* but related concepts:

  • 1. The `[[Prototype]]` Link: Every single object has a hidden, internal property called `[[Prototype]]`. This is a **link** to another object. When you try to access a property on an object, if it's not found, the engine follows this link to its `[[Prototype]]` object and looks there. This process continues, forming the "prototype chain."
    (You can access this with `Object.getPrototypeOf(myObj)` or, via a legacy getter, `myObj.__proto__`.)
  • 2. The `Constructor.prototype` Property: This is a special property that *only functions* have. It's a plain object that, by default, contains only a `constructor` property pointing back to the function itself. Its purpose? To be the **blueprint**. When you create a new object using `new MyConstructor()`, the new object's `[[Prototype]]` link is set to point at `MyConstructor.prototype`.

Let's be clear: `const obj = ` has a `[[Prototype]]` link. `function Foo() ` has a `[[Prototype]]` link *and* a `.prototype` property.

The `new` Keyword: What's Really Happening?

When you write `const dog = new Animal("Rex")`, the `new` keyword is a function that performs four magic steps:

  1. Creates a new, empty object: `let obj = ;`
  2. Links the object's `[[Prototype]]`:`Object.setPrototypeOf(obj, Animal.prototype);`
  3. Calls the constructor with `this`:`Animal.call(obj, "Rex");`
  4. Returns the new object: `return obj;` (unless the constructor explicitly returns another object).

That's it. The "magic" of `new` is just linking a new object to the constructor's `prototype` property.

Why Bother? Memory & Performance

Why not just add methods inside the constructor? Compare these two:

❌ Bad Practice

function Animal(name) {
  this.name = name;
  this.speak = function() {
    console.log(this.name);
  }
}

Every `new Animal()` creates a **new** `speak` function in memory. 1000 animals = 1000 functions.

✔️ Good Practice

function Animal(name) {
  this.name = name;
}
Animal.prototype.speak = function() {
  console.log(this.name);
}

The `speak` function exists **once** on `Animal.prototype`. 1000 animals = 1 function.

By placing shared methods on the prototype, all instances share the *same* function via the prototype chain. This is massively more performant and memory-efficient.

The Modern Ways: `Object.create` and `class`

Manually setting up inheritance is tedious.

function Dog(name, breed) {
  Animal.call(this, name); // 1. Call parent constructor
  this.breed = breed;
}
// 2. Link prototypes
Dog.prototype = Object.create(Animal.prototype);
// 3. Reset constructor
Dog.prototype.constructor = Dog;

Dog.prototype.bark = function() { ... }

This is the "classic" way. The `class` keyword does all of this for you. The following code is (almost) identical to the code above:

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() { ... }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // 1. Calls parent constructor
    this.breed = breed;
  }
  bark() { ... }
}
// 2 & 3 are handled by 'extends' and 'super'
Key Takeaway: The `class` syntax is cleaner and safer, but it's just a friendly mask. Underneath, it's all `prototype` links and `Object.create()`. Understanding the prototype chain is the true key to mastering JavaScript's object-oriented nature, debugging `this` issues, and writing efficient, professional code.

JavaScript Prototype Glossary

`[[Prototype]]`
The internal, hidden property on every object that holds the link to its prototype. This is the first link in the prototype chain.
`Constructor.prototype`
A property that exists on all functions. It's a plain object that will be assigned as the `[[Prototype]]` of any new object created when that function is used as a constructor (with `new`).
`__proto__` (legacy)
A non-standard, legacy getter/setter for an object's `[[Prototype]]`. Modern code should use `Object.getPrototypeOf()` and `Object.setPrototypeOf()`.
Prototypal Inheritance
The core inheritance model of JavaScript. Objects inherit properties and methods directly from other objects via the prototype chain.
Prototype Chain
The series of `[[Prototype]]` links from an object, to its prototype, to its prototype's prototype, and so on, until it reaches `Object.prototype`, which has a `[[Prototype]]` of `null`.
`new` Keyword
An operator that creates a new empty object, links its `[[Prototype]]` to the constructor's `prototype`, binds `this` to the new object, and calls the constructor.
`Object.create()`
A method that creates a new object, using an existing object as the `[[Prototype]]` of the newly created object. This is the modern,
`Object.getPrototypeOf()`
The standard, modern method for reading an object's `[[Prototype]]` link.
`hasOwnProperty()`
A method on `Object.prototype` (and thus available on all objects) that returns `true` if a property exists directly on the object, and `false` if it's inherited from the prototype chain.
`class` (Syntactic Sugar)
The ES6 (2015) syntax for creating constructors and setting up prototypal inheritance in a way that is easier to read and more familiar to developers from classical-inheritance languages.

About the Author

Author's Avatar

TodoTutorial Team

Passionate developers and educators making programming accessible to everyone.

This article was written and reviewed by our team of senior JavaScript developers, who have navigated the evolution of JS from `__proto__` to `class` and understand the core principles deeply.

Verification and Updates

Last reviewed: October 2025.

We strive to keep our content accurate and up-to-date. This tutorial is based on the latest ECMA-262 (JavaScript) specifications and is periodically reviewed.

External Resources

Found an error or have a suggestion? Contact us!