Timothy stood in the center of the archive room, holding a slim, leather-bound ledger labeled childObject. He flipped through its pages frantically, his brow furrowed in frustration.
"It’s not here, Margaret!" he cried out. "I called for the speak() method on this object, but the pages are blank. The function is missing. The code should crash!"
Margaret, calm as ever, walked over from the main desk. She didn't look at the ledger in Timothy's hand. Instead, she pointed to a small, faded stamp on the inside of the back cover.
"The function is not missing, Timothy," she said softly. "It is simply not local. In this library, we do not copy every single instruction into every single book. That would be wasteful. Instead, we rely on Lineage."
The "Link" (The Prototype)
Margaret took the childObject ledger from his hands and tapped the stamp on the back. It read: Inherits from: parentObject.
"This is the secret," Margaret explained. "Every object in our library has a hidden link—a secret reference to another object. We call this the Prototype."
"So the book isn't empty?" Timothy asked.
"The book is merely the first stop," Margaret corrected. "When you ask for a property—like speak—the Engine looks in this book first. If it finds it, wonderful. But if the page is blank, the Engine does not stop. It follows the link."
The Chain (The Walk Up)
Margaret walked to the shelf and pulled down the larger, dustier volume referenced by the stamp: the parentObject.
She opened it. There, clearly written on the first page, was the speak() function.
"You see?" she smiled. "The childObject did not need to own the method itself. It simply needed a connection to an ancestor who did."
"And if this parent didn't have it?" Timothy asked, looking up at the towering shelves.
"Then we would check the parent's parent," Margaret said, gesturing upward. "We walk up the chain, volume by volume, ancestor by ancestor. We only stop when we reach the Null book—the shelf with no volume, the end of all lineage. Only if we reach that void and still find nothing do we return undefined."
The Code (Proving the Lineage)
Timothy hurried to his drafting table. "I must see this in the script. I need to prove that an empty object can still possess wisdom."
Margaret handed him a specific quill labeled Object.create. "Use this," she instructed. "It inscribes the parent's name on the back cover the moment the new ledger is born."
He wrote a simple script to test the theory:
// The Ancestor (Parent)
const parentObject = {
speak: function() {
console.log("I am the Ancestor!");
}
};
// The Descendant (Child)
// We use the quill to link the child to the parent
const childObject = Object.create(parentObject);
// The child is technically empty
console.log("Does child own 'speak'?", childObject.hasOwnProperty("speak"));
// Output: False
// But...
childObject.speak();
// Output: "I am the Ancestor!"
"Look at the logic," Timothy analyzed.
-
The Check: "I ask the child if it owns
speak(hasOwnProperty). It says False. The page is blank." - The Call: "But then I call the function."
-
The Lookup: "The Engine sees the blank page, finds the hidden prototype link, travels to the
parentObject, and executes the code found there."
The Shadowing (Overriding)
"But wait," Timothy paused, his pen hovering. "What if I write a speak() function directly into the childObject? Will it confuse the Engine?"
"Not at all," Margaret assured him. "Remember the rule: Local First. The Engine always checks the book in hand before checking the ancestors."
Timothy added a line to his code:
// Writing directly into the child's ledger
childObject.speak = function() {
console.log("I am the Child!");
};
childObject.speak();
// Output: "I am the Child!"
// The Proof
console.log("Now does child own 'speak'?", childObject.hasOwnProperty("speak"));
// Output: True
"The Engine found the function on page one of the child," Margaret nodded. "So it stopped looking. It never even bothered to check the parent. You have Shadowed the ancestor."
The Conclusion
Timothy looked at the shelves of books, realizing they weren't just isolated volumes, but a massive, interconnected web of relationships.
"It saves so much space," he whispered. "We don't need to rewrite the universe for every new object. We just need a link."
"Precisely," Margaret said, closing the ledger with a satisfying thump. "In other libraries, they build blueprints and copy them endlessly. But here in JavaScript, we do not copy. We delegate. We share. We are a family."
Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.
Top comments (1)
Clear, visual, and memorable. I’ll definitely share this with junior developers struggling with prototypes and object delegation.