The Prototype Chain And The Global Link

Why copy functions when you can share them? The Prototype Chain allows objects to 'borrow' methods from a shared store.

April 25, 20263 min read3 / 7

To solve the memory efficiency problem in Object-Oriented Programming, we need a way for objects to share functionality without duplicating it. In the previous part, we saw that Factory Functions lead to memory bloat. To fix this, we use the Prototype Chain.

The Essentials

  1. Shared Store: An object that holds all the functions we want multiple users to access.
  2. Object.create(): A tool that creates an empty object and creates a hidden link to another object.
  3. [[Prototype]]: The hidden property (bond) that JavaScript uses to find methods.
  4. The Chain: If a property isn't on an object, JavaScript looks at its prototype, then the prototype's prototype, and so on.

Prototype Chain Lookup Journey ExpandPrototype Chain Lookup Journey


Solution 2: Using the Prototype Chain

Instead of defining functions inside the factory, we store them in a single object: userFunctionStore.

JavaScript
const userFunctionStore = { increment: function() { this.score++; }, login: function() { console.log("Logged in"); } }; function userCreator(name, score) { const newUser = Object.create(userFunctionStore); newUser.name = name; newUser.score = score; return newUser; } const user1 = userCreator("Denver", 3); user1.increment();

The "Hidden Bond"

When we use Object.create(userFunctionStore), the newUser object is initially empty, but it has a hidden property called [[Prototype]] (visible in some consoles as __proto__). This property points directly to userFunctionStore.

The Lookup Journey

When we call user1.increment():

  1. Search user1: Does it have an increment property? No.
  2. Follow the Bond: JavaScript follows the [[Prototype]] link to userFunctionStore.
  3. Search userFunctionStore: Does it have an increment property? Yes.
  4. Execute: Run the function.

The Global Chain: hasOwnProperty

Have you ever wondered where user1.hasOwnProperty('score') comes from? You didn't add it to user1, and you didn't add it to userFunctionStore.

JavaScript objects have a multi-layered chain:

  1. Level 1: user1 (Unique data).
  2. Level 2: userFunctionStore (Shared custom methods).
  3. Level 3: Object.prototype (Built-in global methods).

If JavaScript doesn't find a property on Level 1 or Level 2, it looks at the built-in Object.prototype. This is where hasOwnProperty, toString, and other defaults live. If it's not there, the chain points to null and the search ends.

JavaScript Execution Engine
Thread of Execution
1const user1 = Object.create(userFunctionStore);
2user1.name = 'Denver';
3user1.increment();
4user1.hasOwnProperty('name');

Step 1:increment is not on user1. JS looks up the bond to UFS and finds it there.

Memory
user1{ name: 'Denver', [[Prototype]]: ref:UFS }
Call Stack
Global
user1.increment()
Bottom of Stack

The Benefit: Memory Efficiency

We now have 1,000 users, but only one increment function in memory. Every user simply "borrows" it when they need it. This is a sophisticated, complete solution.

But there is a catch. If we are sharing a single function, how does that function know which user's score to change? In the next part, we'll dive into the most famous keyword in JavaScript: this.

Further Reading and Watching