Engrain by ByteRush

JS.04.01 Junior· 9 minCore — asked often

Prototypes and the prototype chain: where an object finds what it does not have

Every object links to a prototype. Property lookup walks that chain until it finds the name or reaches null. Learn own vs inherited and __proto__ vs prototype.

Comes up in: JavaScript, Recruiter screen

Learn#

Sneha logs an empty array in the console and sees push, map and filter under it. She never added them. Where do they live?

Every object has a hidden link to another object, its prototype. The spec calls the link [[Prototype]].

When you read a property, JavaScript checks the object itself. If the name is not there, it follows the link and checks the prototype, then the prototype’s prototype, and so on. That path is the prototype chain, and sharing behavior this way is JavaScript’s inheritance.

Most chains end at Object.prototype, whose link is null. If the name is not found by then, the result is undefined.

A property stored on the object itself is an own property. Object.hasOwn(obj, key) tells the two apart.

Object.getPrototypeOf(obj) reads the link.

const animal = { eats: true, describe() { return "eats: " + this.eats; } };
const dog = Object.create(animal);
dog.barks = true;
console.log(dog.barks, dog.eats, dog.describe());
console.log(Object.getPrototypeOf(dog) === animal);
console.log(Object.hasOwn(dog, "barks"), Object.hasOwn(dog, "eats"));
console.log(Object.getPrototypeOf(Object.prototype));
console.log(dog.flies);

Output (verified)

true true eats: true
true
true false
null
undefined

So push lives once on Array.prototype, shared by every array.

Walking the chainStep 1 of 4

dog

  • barks = true ← found

animal

  • eats = true
  • describe()

Object.prototype

  • toString()
  • hasOwnProperty()
  • …

dog.barks: JavaScript checks dog's own properties first, and finds it.

Read the steps as text
  1. dog.barks: JavaScript checks dog's own properties first, and finds it.
  2. dog.eats: not on dog. Follow dog's prototype link to animal — found there.
  3. dog.toString: not on dog, not on animal. One more link: Object.prototype has it.
  4. dog.flies: not anywhere. Object.prototype's link is null, so the answer is undefined.

Predict#

Predict first

const base = { greet: 'hi' }; const child = Object.create(base); child.greet = 'yo'; What is base.greet now?

Interview angle#

Say it like this — about 30 seconds

“Every object has an internal link, [[Prototype]], to another object or null. Reading a property checks the object’s own properties, then walks up the chain until it finds the name or reaches null. Writing normally creates an own property. __proto__ is a legacy accessor for that link; Object.getPrototypeOf is the modern way. prototype is different: it is a property of functions, used as the prototype for objects created with new.”

Stays on your device. Nothing is uploaded.
Follow-up What is the difference between __proto__ and prototype?
__proto__ is an accessor on objects that reads or sets the object’s own prototype link. prototype is an ordinary property of functions; new F() uses F.prototype as the new object’s prototype.
Follow-up How do you check whether a property is own or inherited?
Object.hasOwn(obj, key) — or the older Object.prototype.hasOwnProperty.call(obj, key). The in operator checks the whole chain.
Follow-up Where does the chain end?
At an object whose prototype is null — usually Object.prototype, or an object made with Object.create(null).

Practice#

On your own

Write two small inspectors: chainOf(obj) lists the chain by constructor name, and whereIs(obj, key) finds which link holds a property.

Done when

  • chainOf(new Dog()) for class Dog extends Animal is ["Dog", "Animal", "Object"].
  • whereIs([], "toString") is "Array" and whereIs([], "hasOwnProperty") is "Object".
  • Missing keys give null; own keys give "own".
Your solution
Ctrl/⌘ + Enter

Remember#

Try to answer each card before you open it. Then add them to your reviews.

What does property lookup do when a name is not on the object?

It follows the prototype link and checks there, up the chain until null.

How do you read an object's prototype?

Object.getPrototypeOf(obj).

__proto__ vs prototype?

__proto__ reads an object's prototype link; prototype is a function's property used by new.

How do you test for an own property?

Object.hasOwn(obj, key).

Go deeper

Four layers. Stop at the one your interview needs; each ends with a quick check.

The core ideaEvery round

Objects link to prototypes. Reading walks the links; writing usually stays on the object. Shared methods live once, on a prototype.

Check yourself: Does assigning child.x = 1 change child's prototype?

No. It creates an own property on child.

How it works underneathSenior rounds

Reading obj.key calls [[Get]]. For ordinary objects, if there is no own property, it calls the prototype’s [[Get]] with the original object as receiver — so inherited methods still see the right this Source: ECMA-262: OrdinaryGet.

Check yourself: Which internal method does property reading call?

[[Get]], which falls back to the prototype's [[Get]].

Edge cases and trapsWhere people slip

new Car() links the new object to Car.prototype, not to Car:

function Car() {}
const c = new Car();
console.log(Object.getPrototypeOf(c) === Car.prototype, Object.getPrototypeOf(c) === Car);

Output (verified)

true false

__proto__ is a legacy accessor kept for old code; use Object.getPrototypeOf and Object.create Source: MDN: Inheritance and the prototype chain.

Check yourself: Is new Car() linked to Car.prototype or to Car?

Car.prototype.

In productionStaff-level answers

Avoid Object.setPrototypeOf on existing objects — engines optimize stable shapes. Never add methods to built-in prototypes in app code. Prototype pollution — attackers setting __proto__ keys through merged JSON — is a real security bug (QLT.04): reject those keys or use Object.create(null) maps.

Check yourself: Why is changing an object's prototype after creation discouraged?

Engines optimize for stable object shapes; changing the prototype is slow and deoptimizes code.

Finished the five steps? Mark it, and its cards join your reviews.

Last checked 2026-10-31. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.

Interview questions this answers

  • What is the difference between __proto__ and prototype?