JavaScript
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Types
-
Section 3: Strings and Numbers in Depth
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Objects and Arrays
-
Section 7: Maps, Sets, and Symbols
-
Section 8: Asynchronous JavaScript
-
Section 9: Object-Oriented and Prototypes
-
Section 10: The DOM
-
Section 11: Browser APIs
-
Section 12: Modern JavaScript (ES2015-ES2025)
-
Section 13: Functional Programming Patterns
-
Section 14: Error Handling and Debugging
-
Section 15: Testing
-
Section 16: Accessibility for JavaScript Developers
-
Section 17: Internationalization and Localization
-
Section 18: Performance
-
Section 19: Node.js Fundamentals
-
Section 20: Regular Expressions
-
Section 21: Design Patterns in JavaScript
-
Section 22: Security Basics
-
Section 23: Data Structures and Algorithms in JavaScript
-
Section 24: Practical Projects
-
Section 25: More Advanced Async Patterns
-
Section 26: More Object and Class Practice
-
Section 27: Working with Dates and Internationalization
-
Section 28: Web Components
-
Section 29: More DOM and Browser Practice
-
Section 30: Build Tooling for Vanilla JavaScript
-
Section 31: More Practice Projects
-
Section 32: Interview and Algorithm Practice
-
Section 33: Error Objects (MDN Reference)
-
Section 34: TypedArrays and Binary Data
-
Section 35: Reflection and Metaprogramming (MDN Reference)
-
Section 36: More Global Functions (MDN Reference)
69: The Prototype Chain
Wait, so if a property isn't on the object, where does JS actually look?
Think of the prototype chain as a series of "fallback" options. When you try to access a property or a method on an object, JavaScript doesn't just give up if it doesn't find it right there on the surface. Instead, it asks: "Do I have a prototype?" If the answer is yes, it jumps to that prototype object and looks there. If it's still not found, it jumps to that object's prototype, and so on.
I like to visualize this as a family tree of capabilities. Let's say we're building a game with different types of units. We might have a generic Unit and a specific Soldier.
const unit = {
move: function() {
console.log("Moving to new coordinates...");
}
};
const soldier = Object.create(unit);
soldier.attack = function() {
console.log("Firing weapon!");
};
soldier.attack(); // Found directly on 'soldier'
soldier.move(); // Not on 'soldier', so JS climbs the chain to 'unit' and finds it there.
In this case, unit is the prototype of soldier. When you called move(), JavaScript checked the soldier object, saw nothing called move, and then looked at the "parent" (the prototype) to find it. That's the chain in action.
I'm confused about the difference between prototype and __proto__. Aren't they the same thing?
This is probably the single most confusing part of JavaScript for everyone I've ever mentored. The short answer: No, they aren't the same, but they are related. Here is the deal: __proto__ (which is better accessed via Object.getPrototypeOf() these days) is a property every single object has. it's the actual link pointing to its prototype.
prototype, on the other hand, is a special property that only functions have. It isn't the function's own prototype; it's the blueprint that will be assigned as the __proto__ to any new objects created using that function with the new keyword.
If you're using a constructor function, it looks like this:
function Species() {}
Species.prototype.eat = function() {
console.log("Nom nom");
};
const cat = new Species();
console.log(cat.prototype); // undefined (objects don't have a .prototype property!)
console.log(Object.getPrototypeOf(cat) === Species.prototype); // true
I usually tell people to think of prototype as the "Instruction Manual" that the function keeps in its desk, and __proto__ as the actual "Physical Link" the created object uses to go back and read that manual.
Does this chain go on forever, or is there a final stop?
It can't go on forever, or your browser would freeze in an infinite loop every time you tried to access a property that didn't exist. Almost every object you create in JavaScript eventually leads back to Object.prototype. This is why almost every object has access to methods like toString() or hasOwnProperty(), even if you didn't define them.
The absolute end of the line is null. When JavaScript reaches Object.prototype and still doesn't find what it's looking for, it looks at Object.prototype's prototype, which is null. At that point, JavaScript gives up and returns undefined.
You can actually see this if you're feeling adventurous in your console:
const myObj = {};
console.log(Object.getPrototypeOf(myObj)); // This is Object.prototype
console.log(Object.getPrototypeOf(Object.prototype)); // This is null
It's a very elegant system once you stop fighting it. It allows us to share logic across thousands of instances without duplicating the memory for every single function.
📋 Practical Task
Building a Multi-Level Component Hierarchy
You are building a UI library. You need to create a prototype chain that mimics how UI components inherit functionality. Follow these requirements:
- Create a base object called
BaseComponentthat has a methodgetId()which returns a unique ID string. - Create an object called
ClickableComponentthat inherits fromBaseComponent. Add a methodclick()to it that logs "Component clicked!". - Create an object called
SubmitButtonthat inherits fromClickableComponent. Add a methodsubmitForm()that logs "Form submitted!".
Verification: Your SubmitButton object should be able to call submitForm(), click(), and getId(), demonstrating a chain three levels deep. Use Object.create() to establish the links.
There are no comments for now.