Question
How JavaScript Prototype Works: Constructors, Inheritance, and new
Question
How does JavaScript prototype-based programming work? In particular, what is the purpose of the .prototype property, and how does it relate to creating objects with new?
Why does this code not work as intended?
var obj = new Object();
obj.prototype.test = function () {
alert("Hello?");
};
var obj2 = new obj();
obj2.test();
Is JavaScript classless, with instances acting as clones of an original object? What is the correct way to define a shared method for objects created with a constructor function?
function MyObject() {}
MyObject.prototype.test = function () {
alert("OK");
};
var obj = new MyObject();
obj.test();
Short Answer
JavaScript objects can inherit properties from other objects through the prototype chain. You will learn the difference between a function’s .prototype property and an object’s actual prototype, what new does, and why methods placed on a constructor’s prototype are shared by every instance.
Concept
JavaScript uses prototype-based inheritance. Instead of copying all methods into each newly created object, an object can delegate property lookups to another object called its prototype.
A key distinction is important:
- A constructor function has a public
.prototypeproperty. - Every object has an internal prototype link, commonly inspected with
Object.getPrototypeOf(object).
When you use a constructable function with new, JavaScript creates a fresh object and sets that new object's internal prototype to the function's .prototype object.
function MyObject() {}
MyObject.prototype.test = function () {
console.log("OK");
};
const obj = new MyObject();
obj.test();
obj does not have its own test property. When JavaScript evaluates obj.test, it first checks obj. It does not find there, so it follows 's prototype link to , where it finds the method.
Mental Model
Think of an object as a worker and its prototype as a shared instruction manual.
When you ask a worker for an instruction such as test:
- The worker looks in its own pocket first (its own properties).
- If it is not there, the worker checks the shared manual (its prototype).
- If it is still not there, JavaScript checks that manual's prototype, continuing up the prototype chain.
- If no object has the property, the result is
undefined.
A constructor function's .prototype is the instruction manual that will be assigned to future objects created with new Constructor().
Adding a prototype label to an ordinary object is like putting an unused folder named “manual” in the worker's pocket. JavaScript does not treat that folder specially.
Syntax and Examples
A constructor function is a function intended to create objects with new. By convention, its name starts with an uppercase letter.
function User(name) {
this.name = name;
}
User.prototype.greet = function () {
console.log(`Hello, ${this.name}!`);
};
const ada = new User("Ada");
const lin = new User("Lin");
ada.greet(); // Hello, Ada!
lin.greet(); // Hello, Lin!
ada and lin each have their own name value. However, they share the same greet function:
console.(ada. === lin.);
.(.(ada) === .);
.(ada.());
Step by Step Execution
Consider this code:
function Counter(start) {
this.value = start;
}
Counter.prototype.increment = function () {
this.value += 1;
};
const counter = new Counter(5);
counter.increment();
console.log(counter.value);
Step by step:
- JavaScript evaluates
new Counter(5). - It creates a new empty object.
- It links that object's internal prototype to
Counter.prototype. - It runs
Counter(5)withthisset to the new object. this.value = startstores an own property on the new object, so it becomes{ value: 5 }conceptually.- The new object is assigned to
counter.
Real World Use Cases
Prototype lookup is used constantly in JavaScript, including when you do not explicitly write .prototype.
-
Array methods: Arrays inherit methods such as
map,filter, andpushfromArray.prototype.const prices = [10, 20, 30]; const withTax = prices.map(price => price * 1.2); -
String methods: Strings can use methods such as
includesbecause JavaScript provides methods throughString.prototype."admin@example.com".includes("@"); // true -
Domain models: A server-side app might create
User,Order, orInvoiceobjects with shared behavior.
Real Codebase Usage
In modern codebases, developers often write class syntax, factory functions, or plain objects. Understanding prototypes is still essential because JavaScript's property lookup and many built-in APIs rely on them.
Class syntax uses prototypes
class User {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, ${this.name}`;
}
}
const user = new User("Ada");
console.log(user.greet());
console.log(Object.getPrototypeOf(user) === User.prototype); // true
The greet method is on User.prototype, not copied onto every User instance.
Prefer own data and prototype methods
A common constructor pattern keeps instance-specific data on and shared behavior on the prototype:
Common Mistakes
Treating an ordinary object as a constructor
This is broken because obj is not callable or constructable:
const obj = new Object();
const obj2 = new obj(); // TypeError: obj is not a constructor
Use a function or class with new, or use Object.create when you already have a prototype object.
Assuming .prototype is every object's prototype
const person = { name: "Ada" };
person.prototype = { greet() {} };
This creates an ordinary own property called prototype. It does not set the prototype used for property lookup.
Inspect the actual prototype with:
Object.getPrototypeOf(person);
Replacing a constructor's prototype without restoring
Comparisons
| Concept | Meaning | Typical use |
|---|---|---|
Constructor.prototype | The object used as the prototype for instances created later with new Constructor() | Defining shared methods for constructor-created objects |
Object.getPrototypeOf(obj) | Returns the actual prototype object that obj delegates to | Inspecting an object's prototype chain |
obj.property | Looks for a property on obj, then through its prototypes | Normal property and method access |
Object.create(proto) | Creates an object whose internal prototype is proto | Direct prototype-based object creation |
Cheat Sheet
- A prototype is an object another object can delegate property lookups to.
Object.getPrototypeOf(obj)reads an object's actual prototype.Constructor.prototypeis used bynew Constructor()to set the new object's prototype.- Put per-instance state in the constructor with
this. - Put shared methods on
Constructor.prototype.
function User(name) {
this.name = name; // unique per instance
}
User.prototype.greet = function () { // shared method
return `Hello, ${this.name}`;
};
const user = new User("Ada");
user.greet();
Useful checks:
Object.getPrototypeOf(user) === User.;
user.();
user.();
FAQ
What is the difference between .prototype and __proto__ in JavaScript?
A function's .prototype is the object that new uses for future instances. __proto__ is a legacy accessor for an individual object's internal prototype. Prefer Object.getPrototypeOf(obj) instead of __proto__.
Does every JavaScript object have a .prototype property?
No. Functions commonly have a .prototype property. Ordinary objects may have a property with that name, but it has no automatic prototype behavior. Every ordinary object can have an internal prototype link, though objects made with Object.create(null) have no prototype.
Does new copy methods from the prototype?
No. new links the new object to the constructor's prototype. Methods are found later through property lookup, so they are normally shared rather than copied.
Why are prototype methods memory-efficient?
One method function can be stored on the prototype and used by all instances. If the method were created inside the constructor, each instance would usually receive a separate function object.
Can I use prototypes without new?
Mini Project
Description
Build a small TaskList type that stores tasks separately for each list while sharing task-management methods through a prototype. This mirrors a common application pattern: each user, project, or board has independent data but uses the same operations.
Goal
Create task lists that can add, complete, and summarize tasks without sharing task data between instances.
Requirements
Requirement 1
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.