Understanding Prototype in JavaScript Constructors
In JavaScript, the prototype property on standard
constructor functions acts as the central blueprint for implementing
prototypal inheritance and sharing methods across object instances.
Instead of duplicating functions and properties in memory every time a
new instance is created with the new keyword, the engine
links each instance to the constructor’s prototype object.
This article explores how this property works, why it is critical for
memory efficiency, and its mechanics within the JavaScript prototype
chain.
What is the
prototype Property?
Every standard function in JavaScript is automatically created with
an object property named prototype. When a function is used
as a constructor (invoked with the new keyword), this
prototype object becomes the prototype of the newly
instantiated object.
function User(name) {
this.name = name;
}
User.prototype.greet = function() {
return `Hello, my name is ${this.name}`;
};
const user1 = new User('Alice');
const user2 = new User('Bob');In this example, both user1 and user2 have
access to the greet method, but greet exists
only once in memory on User.prototype.
Core Roles of the
prototype Property
1. Memory Optimization and Method Sharing
If methods are defined inside the constructor function body via
this.methodName = function() {...}, a new copy of that
function is allocated in memory for every single instance created.
Defining methods on the constructor’s prototype ensures
that all instances share a single reference to that method. Whether you
instantiate ten or ten thousand objects, the method resides in memory
only once.
2. Establishing the Prototype Chain
When a constructor is called with new, the JavaScript
runtime creates a new object and sets its internal
[[Prototype]] link (accessible in modern environments via
Object.getPrototypeOf() or __proto__) to point
directly to the constructor function’s prototype
property.
Object.getPrototypeOf(user1) === User.prototype; // true3. Property Lookup Delegation
The prototype property facilitates property delegation.
When attempting to access a property or method on an object: 1. The
JavaScript engine checks if the property exists directly on the object
(an “own property”). 2. If not found, it traverses up the prototype
chain to Constructor.prototype. 3. If still not found, it
continues up to Object.prototype, and finally stops at
null.
If a property with the same name exists on the instance itself, it shadows (overrides) the property on the prototype without modifying the shared prototype value.
The prototype
Property vs. [[Prototype]]
A common source of confusion is distinguishing between
prototype and [[Prototype]]: *
Constructor.prototype: A standard,
publicly accessible property that exists only on functions (excluding
arrow functions), specifying what will be assigned as the prototype of
instances created by that function. *
[[Prototype]]: An internal hidden property
present on every JavaScript object (instances, functions, arrays)
pointing to the object from which it inherits properties.
Standard Built-in Constructors
JavaScript’s native types use this exact pattern. Built-in
constructors such as Array, String, and
Object rely on their prototype property to
provide core functionality: * Methods like map,
filter, and push reside on
Array.prototype. * Methods like slice,
toUpperCase, and trim reside on
String.prototype.
Because of this design, all array literals ([])
automatically inherit the methods defined on
Array.prototype without needing to define those functions
on individual arrays.