# JavaScript Prototypes and Prototypal Inheritance

## 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 -

```javascript
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.

```javascript
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 -

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1695049273468/66a0bab0-b247-47b8-90ac-8bd346aeca8d.png align="center")

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

```javascript
// 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 -

```javascript
// 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.
