Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk6 min

Understanding Prototypes in JavaScript: A Practical Guide for Developers

Understand JavaScript prototype lookup, inherited and shadowed properties, shared methods, and the difference between an object’s [[Prototype]] and a constructor’s .prototype.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

JavaScript objects find properties by checking themselves first, then following an internal link called [[Prototype]] to other objects. That lookup continues until a matching property is found or the chain ends at null. Once you separate that link from a constructor’s .prototype property, inheritance, shared methods, and shadowing become much easier to reason about.

How JavaScript prototype lookup works

Every ordinary object has an internal [[Prototype]] link. It points to another object, whose own link may point to another. When JavaScript evaluates a property access such as obj.name, it checks obj first. If the property is not there, it checks the object’s prototype, then the next prototype, continuing until it finds the property or reaches null. This is delegation: inherited methods are found through the chain rather than copied onto every instance. See MDN’s guide to inheritance and the prototype chain.

A typical object created with a constructor has this chain:

instance → Constructor.prototype → Object.prototype → null

A class hierarchy created with class Base {}, class Derived extends Base {}, and new Derived() follows the corresponding chain through Derived.prototype, Base.prototype, and Object.prototype, ending at null.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What is the difference between [[Prototype]] and .prototype?

The names are similar, but they refer to different things:

  • [[Prototype]] is an internal link on an object. It determines where property lookup continues when the object does not have a property itself.
  • Constructor.prototype is a property on a constructor function. When that function is called with new, the new instance’s [[Prototype]] is set to the value of the constructor’s .prototype property.
  • Object.getPrototypeOf(obj) is the standard API for reading an object’s prototype link.
  • obj.__proto__ is a legacy accessor available in implementations, not the preferred standard API. The special { __proto__: proto } form in an object literal is separate, standardized syntax for setting the new object’s prototype.

In short: an instance has a prototype link; a constructor’s .prototype is commonly the object that link points to for instances created with new. MDN covers these terms and the prototype chain in its inheritance guide.

Inspect an object’s prototype and its own properties

Use Object.getPrototypeOf() to inspect the link, and Object.hasOwn() to check whether a property belongs directly to an object:

const date = new Date();

Object.getPrototypeOf(date) === Date.prototype; // true
Object.hasOwn(date, "getTime"); // false

date.getTime(); // found on Date.prototype

The getTime method is available on the date because lookup reaches Date.prototype; it is not stored as an own property on that particular date object. MDN’s object prototypes guide demonstrates this kind of chain inspection and recommends Object.hasOwn() for checking own properties.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For an object with no matching property, lookup continues through its prototypes until the chain ends at null. This is why checking ownership and checking whether a property can be read are different questions: an inherited property may be readable without being an own property.

How shadowing changes a property lookup

If an object defines a property with the same name as one on its prototype, the own property is found first. It shadows the inherited property for that object:

const date = new Date();
date.getTime = () => "custom";

date.getTime(); // "custom"

The instance’s own getTime takes precedence over Date.prototype.getTime. The prototype method remains on Date.prototype; the instance’s property does not replace it for other dates. MDN describes this behavior as shadowing in its object prototypes guide.

Also, a property whose value is undefined is not necessarily absent. If the distinction matters, test whether the property exists or is owned explicitly instead of treating its value alone as proof of absence.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Share methods while keeping state on each instance

A common constructor pattern puts per-instance values on each object and reusable methods on the constructor’s prototype:

function Person(name) {
  this.name = name; // own, per-instance state
}

Person.prototype.greet = function () {
  return `Hello, ${this.name}`;
};

const ada = new Person("Ada");
ada.greet(); // "Hello, Ada"

ada.name is an own property. The call to ada.greet() finds greet on Person.prototype, and the method uses the calling object as this. Other instances made by the same constructor can use that inherited method too. MDN’s object prototypes guide explains this pattern of keeping instance values on objects and shared methods on the prototype.

Choose between classes, constructors, and Object.create()

These approaches express different ways to establish a prototype relationship. None is universally best; choose based on how the object should be created and what will be clearest to the maintainers of the code.

Approach How the relationship is established When it is useful
class and extends Class syntax sets up the prototype relationships for instances and derived classes. A recognizable syntax for many modern examples, especially when objects are created through constructors and a derived type is useful.
Constructor function and new The instance receives the constructor’s .prototype as its [[Prototype]]. Understanding existing code and seeing directly how shared prototype methods work.
Object.create(proto) The supplied object is selected directly as the new object’s prototype. When you want an object to delegate to a chosen object without defining a constructor function.

Use class and extends for familiar type syntax

class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    return `Hello, ${this.name}`;
  }
}

class Developer extends Person {}
const ada = new Developer("Ada");

The instance finds greet through the class prototype chain. Class syntax expresses the same prototype-based inheritance model; it does not introduce a separate inheritance mechanism. As MDN puts it, “Although classes are now widely adopted and have become a new paradigm in JavaScript, classes do not bring a new inheritance pattern.” Read the full MDN inheritance guide.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use constructors to understand or maintain function-based patterns

A constructor function is useful when reading code that predates class syntax or when the function-based pattern is already established in a codebase. With new Person("Ada"), JavaScript creates an instance whose prototype is the current value of Person.prototype. Replacing a constructor’s entire .prototype object can remove its conventional constructor property, which can make code that relies on that property confusing or error-prone.

Use Object.create() when the prototype is the point

const personPrototype = {
  greet() {
    return `Hello, ${this.name}`;
  },
};

const ada = Object.create(personPrototype);
ada.name = "Ada";
ada.greet(); // "Hello, Ada"

This makes the delegation relationship explicit: ada is created with personPrototype as its prototype. You can also call Object.create(null) to create an object with no prototype. Such an object does not inherit Object.prototype methods, so code must not assume it has methods such as hasOwnProperty. Use Object.hasOwn(obj, key) when checking an own property.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Prototype practices that avoid common problems

  • Prefer standard inspection: use Object.getPrototypeOf() rather than teaching or relying on the legacy __proto__ accessor.
  • Set relationships at creation time: avoid changing the prototype of an already-created object as a routine pattern. MDN notes that prototype mutation can have performance implications; it does not establish a universal cost or threshold. See the MDN inheritance guide.
  • Keep chains understandable: very long or complicated chains can be harder to follow and may cause performance problems. There is no single numeric chain-length limit established here; keep a chain only as deep as the design needs.
  • Do not casually extend built-in prototypes: adding methods to native prototypes can affect other code. MDN advises against it except where needed for compatibility with newer JavaScript features; see its guidance on inheritance.
  • Check existence, not just value: a property may exist with the value undefined. Use an ownership or existence check when that distinction affects behavior.

There is no universal performance ranking for classes, constructors, or Object.create() established by these sources. Prefer the form that makes object creation and delegation clear in your codebase, and measure a specific performance concern in its actual context rather than relying on a blanket claim.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.