Prototypes in JavaScript: The only blog you need to understand prototypes


In JavaScript, everything is an object, from Arrays to strings, including functions, which are called specialized objects. JavaScript follows a prototype-based system that allows objects to inherit properties from one another with the help of prototypes.This prototypes plays a key role in how Javascript handles inheritance and object relationship.
What is a prototype?
Prototypes in JavaScript lay the foundation for the object-oriented programming (OOP) concept in the language. A prototype is an object from which other objects inherit properties and methods. It allows all instances of a particular data type or constructor to share common behavior.
When a property or method is added to a constructor’s prototype, all instances created from that constructor can access it. For example, if a method is added to Array.prototype
or String.prototype
, it becomes accessible to all arrays and strings, including those created after the addition.
Example :→
Array.prototype.myprint=function (){
console.log("Hi I am array");
}
const arr=[1,2,3,4];
arr.myprint();
// -> Hi I am array
Question :→ Predict output of the following code:→
Object.prototype.myPrint=function(){
console.log("I am a object print");
}
const obj={
name:'Swayam'
}
obj.myPrint();
const arr=[1,2,2,4];
arr.myPrint(); // will this work??
So if you thought for object obj when you write obj.print() it will give right output and for arr.myprint() it won’t work and throw some beautiful error then you have probably misinterpreted it .
Object.prototype.myPrint=function(){
console.log("I am a object print");
}
const obj={
name:'Swayam'
}
obj.myPrint();
const arr=[1,2,2,4];
arr.myPrint(); // will this work?? yes! (o/p:-> I am a object print)
How prototypes in JavaScript works ?
Every time in JavaScript when you declare a object all the properties and methods and automatically wrapped to that object and when you try to access those properties with help of ‘.’ operator you would witness list of function you are able to access that already defined in it.
So when we wrote this code block myprint function was added to obj.protoype of obj in our program .
Object.prototype.myPrint=function(){
console.log("I am a object print");
}
In Javascript ,every object has an internal [[Prototype]] property,(which can be accessed and modified using proto ) which points to another object .This allows the object to inherit properties and methods from its prototype.
Whenever we try to access a method for any object the Javascript checks for the object itself then try to check in other objects until it reaches null. This is also called as prototype chaining (which we will discuss in detail in this blog in further section. ).
Objects created using a constructor function inherit properties and methods from the constructor's prototype. This allows for reusable code and shared behaviour across multiple objects.
You can add new properties or methods to an object's prototype, and all instances of that object will automatically have access to the new functionality. This is a common way to extend built-in objects like Array or Object.
Below diagram would help you visualize in better and much more intuitive way:→
Before I move on to explain construction function let me explain you how prototype chaining in JavaScript works.
Prototype chaining
Let’s take the same example :→
Object.prototype.myPrint=function(){
console.log("I am a object print");
}
const obj={
name:'Swayam'
}
obj.myPrint();
const arr=[1,2,2,4];
arr.myPrint(); // will this work?? yes! (o/p:-> I am a object print)
The baffling part is how an array is able to access a method added to Object.prototype
.
Remember what we said at the beginning: “Everything in JavaScript is an object.”
When you call arr.myPrint()
, JavaScript looks for myPrint
in the array’s own prototype chain.
Here's how it works:
JavaScript checks if
arr
itself has amyPrint
method.It doesn’t find it on the array instance, so it looks up to
Array.prototype
.Still not found? It goes one step up to
Object.prototype
, where it does findmyPrint
.
This lookup process is known as prototype chaining — it's how JavaScript resolves property and method references.
So in nutshell,whenever a object(which may be function,array or string) is not able to access the function or method in it’s protoype then it will look up in the chain for prototype’s prototype until it finds null.This is called prototype chaining.That’s the reason which is why arrays are able to access methods of Object.prototype
.
Refer the below image :—>
Creating Constructor Functions
Constructor Function in JavaScript is a way of creating special functions using new keyword.When we write new keyword it initializes and create objects. It sets up methods and properties on newly created object allowing for the creation of multiple instances with shared behavior.
function Car(car){
this.car=car;
}
Function.prototype.myCarName=function(){
console.log(`I have a ${this.car} car`);
}
const car=new Car('ABC');
car.myCarName();
A constructor function is a special function used to create and initialize new objects. In this case, Car is a constructor that takes a car as an argument and assigns it to the car property of the new object using this.
The myCarName method is added to the Car prototype, meaning all instances of Car will have access to this method, allowing them to mention about their car name.
The expression new Car('ABC') creates a new object using the Car constructor, passing "ABC" as the car argument. The new object is stored in the car variable.
The myCarName method is then called on the car object, which outputs "I have a ABC car" to the console.
How to inherit methods of one object into another object without deepcloning them?
const obj1={
name:"Swayam",
greet:function(){
console.log(`Hi my name is ${this.name}`);
}
}
const obj2={
name:'Ravi Gupta'
}
However we can use the concept of call and bind to access them then our code would look like
const obj1={
name:"Swayam",
greet:function(){
console.log(`Hi my name is ${this.name}`);
}
}
const obj2={
name:'Ravi Gupta'
}
obj1.greet.call(obj2);
const o2=obj1.greet.bind(obj2);
o2();
This is not inheritance of methods of object to other and inorder to inherit what we will do is :→
const obj1={
name:"Swayam",
greet:function(){
console.log(`Hi my name is ${this.name}`);
}
}
const obj2={
name:'Ravi Gupta',
__proto__:obj1
}
obj2.greet();
Alternative way:→
const obj1={
name:"Swayam",
greet:function(){
console.log(`Hi my name is ${this.name}`);
}
}
const obj2={
name:'Ravi Gupta',
}
obj2.__proto__=obj1;
obj2.greet();
What we did in the above code is an example of prototype inheritance in JavaScript.
By assigning
obj1
as the prototype ofobj2
usingobj2.__proto__ = obj1
, we allowobj2
to access methods and properties defined inobj1
.In this case,
obj2
does not have its owngreet
method, so JavaScript looks up the prototype chain and findsgreet
inobj1
, which it then executes usingobj2
as the context (this
).However, the use of
__proto__
is disregarded in modern JavaScript because it’s a legacy feature and may lead to inconsistencies.The recommended and safer way to set the prototype of an object is by using
Object.setPrototypeOf(obj2, obj1)
, which achieves the same result in a more standard and reliable manner.
Do inheritance without using extends keyword in JavaScript?
Before learning __proto__
and prototype you would use to do something just like this (‘Not a coldplay song)
class A{
functionInsideA(){
console.log('Function inside A');
}
}
class B extends A{
functionInsideB(){
console.log('Function inside B');
}
}
const b1=new B();
b1.functionInsideA();
Output
Can we implement this without using extend keyword ?
Yes, we can let me show you how to do this.
class A{
functionInsideA(){
console.log('Function inside A');
}
}
class B {
functionInsideB(){
console.log('Function inside B');
}
}
B.prototype.__proto__=A.prototype;
const b1=new B();
b1.functionInsideA();
Internally
This allows instances of B
(like b1
) to access methods from A.prototype
, even though B
does not formally extend A
.
b1 is an instance of B
which means b1.__proto__ is equal to B.prototype therefore the prototype chain looks like
b1 → B.prototype → A.prototype → Object.prototype → null
As I must have told you multiple times that use of __proto__ is discarded therefore we can use
Object.setPrototypeOf(B.prototype, A.prototype);
Advantages of Prototypes
Memory Efficiency
Inheritance Support
Code Resusablity
Performance Optimization
Flexiblity
Conclusion
JavaScript prototypes are key to inheritance, code reuse, and memory efficiency. They allow methods to be shared across instances, reducing redundancy and improving performance. Prototypes provide flexibility to extend or modify objects dynamically. Understanding them is essential for mastering JavaScript and creating efficient, maintainable applications.
Subscribe to my newsletter
Read articles from Swayam Allewar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
