LESSON 18 · INTERMEDIATE4 min read

The Prototype Chain: Inheritance via Object Delegation

Demystify JavaScript's object model. Learn how prototype delegation works, inspect [[Prototype]] links, and leverage Object.create() for behavior delegation.

ES2024 / Node.js 20+Free to readModule 5 of 10
YOUR NEXT SMALL WINS

By the end, you’ll be able to…

  • Contrast class-based classical inheritance with JavaScript's prototype delegation.
  • Trace property lookup across the [[Prototype]] chain up to Object.prototype.
  • Implement clean behavior delegation using Object.create() and Object.getPrototypeOf().

01Inheritance vs Delegation

Almost all mainstream object-oriented languages (Java, C++, C#) employ classical inheritance: classes serve as rigid blueprints, and instantiating an object copies properties and behaviors into a brand-new concrete instance. JavaScript does NOT work this way. JavaScript uses Prototype Delegation.

In JavaScript, objects are linked directly to other objects. When you request a property or method on an object (e.g. user.login()), if the object does not possess that property directly on itself, the engine does not fail. Instead, it delegates the lookup to the object's hidden internal [[Prototype]] link. If found on the prototype, that method executes in the context of the calling object.

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

02The Prototype Chain and Object.prototype

Every object created in JavaScript has an internal [[Prototype]] link (accessible via Object.getPrototypeOf(obj) or the legacy __proto__ accessor). The prototype object itself has its own prototype, forming a chain of linked objects known as the Prototype Chain.

At the very top of almost every prototype chain sits Object.prototype. Object.prototype provides universal methods like hasOwnProperty(), isPrototypeOf(), and toString(). The prototype of Object.prototype is null, which terminates the lookup chain. If a property is not found anywhere on the chain up to null, the lookup yields undefined.

The critical distinction in JavaScript's prototype model is between the 'prototype' property and the internal '[[Prototype]]' slot. Only functions (specifically constructor functions and classes) have a public .prototype property. Ordinary object instances do not have a .prototype property.

Instead, every object instance has an internal [[Prototype]] slot, accessible via Object.getPrototypeOf(obj) or the legacy __proto__ accessor. When you instantiate const user = new User(), user's internal [[Prototype]] is linked directly to User.prototype, forming the delegation link.

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

03The 'prototype' Property vs [[Prototype]] Link

One of the greatest sources of confusion in JavaScript is the difference between the prototype property on functions and the hidden [[Prototype]] link on objects. Only constructor functions and classes possess a .prototype property.

The .prototype property on a function is NOT the function's own prototype; it is an object that will become the [[Prototype]] of any instances created when calling new FunctionName(). This subtle distinction explains how the new operator binds prototype delegation behind the scenes.

example.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

04Why This Matters in Production

Understanding prototype delegation allows you to share methods across millions of object instances without duplicating function definitions in memory. If you declare methods inside a constructor (this.method = function() {}), every single instance consumes additional heap memory for its own copy of the function.

By attaching methods to the prototype, all instances share a single memory allocation. Furthermore, mastering delegation allows using Object.create(null) to create clean, prototype-less dictionary maps that are impervious to prototype pollution security vulnerabilities.

LET IT CLICK

The ideas worth keeping.

  • JavaScript uses object delegation, not classical class-based copying.
  • Unresolved properties delegate up the [[Prototype]] chain until reaching null.
  • Use Object.create(null) to create clean dictionaries safe from prototype pollution.
TURN UNDERSTANDING INTO SOMETHING YOU CAN DO

Make it yours.

Type and test your code right here in the interactive workspace. Run your solution, check the output, and compare with the worked guide when ready.

01

Exercise 1: Safe Dictionary without Prototype Pollution

Create a pure dictionary object that has no prototype link (Object.getPrototypeOf is null) to safely store untrusted user keys.

your_turn_1.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.jsJavaScript
const safeDict = Object.create(null);// safeDict has no toString, hasOwnProperty, or constructor vulnerabilities

Object.create(null) produces an object with no prototype chain, making it completely immune to prototype pollution attacks.

02

Exercise 2: Verifying Prototype Chain Distance

Write a function getPrototypeDepth(obj) that returns the number of prototype links between an object and null.

your_turn_2.js⚡JavaScript
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.jsJavaScript
function getPrototypeDepth(obj) {  let depth = 0;  let current = obj;  while ((current = Object.getPrototypeOf(current)) !== null) {    depth++;  }  return depth;}

Iterating with Object.getPrototypeOf until null accurately counts the depth of the prototype delegation chain.

A SMALL QUESTION. A USEFUL NEXT STEP.

What stayed with you?

Check the ideas while they’re fresh. Your answers stay in this page and feedback appears as you go.

A LITTLE ACTIVE RECALL0 / 3 answered
01How does JavaScript resolve a method that does not exist directly on the calling object?
02What sits at the very end of standard prototype chains?
03Why does attaching methods to a prototype conserve memory compared to defining them in the constructor?
⚡CODING CHALLENGE
🔒Required to Mark Lesson Complete

Exercise 1: Safe Dictionary without Prototype Pollution

Create a pure dictionary object that has no prototype link (Object.getPrototypeOf is null) to safely store untrusted user keys.

EXPECTED OUTPUT
[Process exited with code 0 - No output]
main.jsJavaScript
Ctrl + ↵
Execution Console
Click "Run & Verify" (or press Ctrl + Enter) to test your code against the challenge.

Keep exploring.

The official references behind this lesson, when you want a second angle or the full details.

One lesson closer.

Reading is a start. Trying it yourself makes the connection.

Solve the hands-on coding challenge in the knowledge section to verify your code and unlock lesson completion.