Photo by Eric Er on Unsplash

On this page

This chapter follows QuickTip: Filter object properties by key.

Every ordinary object has an internal [[Prototype]] link (exposed as Object.getPrototypeOf). When you read obj.method, the engine checks own properties first, then walks the chain until it finds a match or reaches null.

Prototype chain lookup

const animal = {
speak() {
return '...';
},
};
const dog = Object.create(animal);
dog.speak(); // '...' — found on animal

Object.create(proto) builds an object whose [[Prototype]] is proto. Literal {} gets Object.prototype unless you use Object.create(null) for a null-prototype dictionary.

Constructor functions and .prototype

Before class, shared methods lived on Constructor.prototype. new creates an object whose [[Prototype]] is that prototype object.

function Person(name) {
this.name = name;
}
Person.prototype.greet = function greet() {
return `Hi, ${this.name}`;
};
const ada = new Person('Ada');
ada.greet(); // Hi, Ada

instanceof checks whether Constructor.prototype appears anywhere on the instance’s prototype chain.

Own properties versus inherited

obj.hasOwnProperty('x') and Object.hasOwn(obj, 'x') ignore inherited keys. for...in enumerates inherited enumerable string keys unless you filter with hasOwn.

Assigning obj.method = fn creates an own property that shadows a prototype method without removing it from the prototype.

Subclassing with Object.setPrototypeOf

Prefer class extends (next chapter) for subclassing. Low-level APIs include Object.setPrototypeOf (slow path, mutates existing object) and manual prototype wiring in legacy code.

Performance note

Modern engines optimize common object shapes with hidden classes (see Hidden classes and inline caches). Stable property order and consistent initialization help; reshaping objects after creation can deoptimize hot paths.

Next: Classes in JavaScript.

Search articles

Type a word to search published articles.

Open the search page