JavaScript Prototypes and Prototypal Inheritance

JavaScript Prototypes and Prototypal Inheritance

JS Essentials

Prototypes: Foundation of Javascript

In Javascript, everything is an object and the prototype serves as a blueprint for every object containing its properties and methods.

To understand it more easily let's first understand what are constructor functions

Constructor Functions -

Constructor functions are used to create objects. They act as templates for objects, defining their initial state and behavior.

Here's an example -

function myObj(name,age){ //constructor functions
    this.name = name;
    this.age = age;
}

const obj1 = new myObj("xyz","20");
const obj2 = new myObj("yzx","21");

The above constructor function takes properties "name" and "age" and sets them as properties on the newly created objects with the new keyword**.**

However, with this approach, each object created using new myObj() has its own copy of the properties and methods, leading to potential memory inefficiencies if there are many instances.

Prototypes -

JavaScript's prototype system comes into play to address above issue. Every function in JavaScript has a property called prototype, which is an object that can hold properties and methods shared among all instances created by that constructor function.

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHello = function () {
  console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

const person1 = new Person("Alice", 30);
const person2 = new Person("Bob", 25);

person1.sayHello(); // "Hello, my name is Alice and I am 30 years old."
person2.sayHello(); // "Hello, my name is Bob and I am 25 years old."

Since everything in javascript is an object we can use their prototype attribute to create our own set of properties for such objects common to all the instances of that object as the sayHello() function created above will be available to both person1 and person2 objects as both are instance of the same constructor function.

Prototypal Inheritance -

You can achieve prototypal inheritance using the __proto__ property in JavaScript. Here's an example:

// Parent object
const animal = {
  speak: function () {
    console.log(`I am an animal.`);
  },
};

// Child object inheriting from the parent
const dog = {
  __proto__: animal, // Set the prototype to 'animal'
  bark: function () {
    console.log("Woof!");
  },
};

// Create instances of 'dog'
const dog1 = Object.create(dog);
dog1.speak(); // "I am an animal."
dog1.bark();  // "Woof!"

const dog2 = Object.create(dog);
dog2.speak(); // "I am an animal."
dog2.bark();  // "Woof!"

Here, the dog object inherits the properties of the animal object with the help of __proto__ property. so all instances of the dog object will have the speak function in their prototype methods and variables.

However, __proto__ property was used in older javascript syntax in new Javascript modern syntax Object.setPrototypeOf() and Object.getPrototypeOf()

Here's an example -

// Parent object
const animal = {
  speak: function () {
    console.log(`I am an animal.`);
  },
};

// Child object
const dog = {
  bark: function () {
    console.log("Woof!");
  },
};

// Establishing prototype-based inheritance
Object.setPrototypeOf(dog, animal);

// Create instances of 'dog'
const dog1 = Object.create(dog);
dog1.speak(); // "I am an animal."
dog1.bark();  // "Woof!"

const dog2 = Object.create(dog);
dog2.speak(); // "I am an animal."
dog2.bark();  // "Woof!"

We use Object.setPrototypeOf(dog, animal) to establish prototype-based inheritance. This sets the prototype of dog to animal, creating a prototype chain where dog inherits from animal.

Conclusion -

In conclusion, JavaScript offers several mechanisms for establishing prototype-based inheritance, each with its own advantages and use cases. Whether you choose to use constructor functions, Object.create(), or Object.setPrototypeOf(), the fundamental concept remains the same: objects can inherit properties and methods from their prototypes, creating a flexible and efficient way to structure and organize your code.

Understanding prototype chains and how objects relate to each other through prototypes is crucial for writing maintainable and efficient JavaScript code.

Subscribe to our blog post to learn more about the fundamentals of web development.

Did you find this article valuable?

Support Ratish Jain by becoming a sponsor. Any amount is appreciated!