Prototypes in JavaScript

Prototypes in JavaScript

In JavaScript, prototypes are an essential part of the language's inheritance model. They allow you to share properties and methods between objects, enabling a powerful way to build object-oriented functionality. Understanding prototypes is key to writing efficient and maintainable code.

In this blog post, we’ll break down the concept of prototypes, how they work, and how you can use them to manage inheritance and share methods across objects.


1. What Is a Prototype?

In JavaScript, each object has a prototype. A prototype is an object itself, and it serves as a blueprint for other objects. Every JavaScript object has a property called prototype, which allows you to define shared properties and methods that other objects can access.

For example, when you create an object in JavaScript, it can inherit methods and properties from its prototype. This prototype is used when the object doesn't have the property or method you're trying to access.


2. How Does Prototyping Work in JavaScript?

JavaScript uses a prototype chain. If an object does not have a property or method, JavaScript will check its prototype. If it's not there, it will check the prototype of that prototype, and so on, up the chain. This continues until it reaches null, at which point it stops searching.


3. Creating Objects with Prototypes

You can create an object with its prototype using constructor functions or ES6 classes. Let’s look at both approaches.

Constructor Function

In JavaScript, a constructor function allows you to create new objects and add methods to their prototype. Here’s an example of using a constructor function and setting up a prototype:

function Animal(name) {
  this.name = name;
}
 
// Adding a method to the Animal's prototype
Animal.prototype.speak = function() {
  console.log(`${this.name} makes a sound.`);
};
 
const dog = new Animal("Dog");
dog.speak(); // Output: Dog makes a sound.

In this example, speak is a method of the Animal prototype. When we create a new dog object, it inherits the speak method from Animal.prototype.

ES6 Class

With ES6 classes, you can define methods directly inside the class body. Behind the scenes, these methods are added to the prototype of the class.

class Animal {
  constructor(name) {
    this.name = name;
  }
 
  speak() {
    console.log(`${this.name} makes a sound.`);
  }
}
 
const dog = new Animal("Dog");
dog.speak(); // Output: Dog makes a sound.

The functionality is similar to the constructor function example, but the class syntax is cleaner and more intuitive.


4. Prototype Chain

As mentioned earlier, objects can inherit properties and methods from other objects through a prototype chain. This allows for more efficient memory usage, as methods do not need to be duplicated across multiple instances of an object.

Let’s illustrate this with an example:

function Animal(name) {
  this.name = name;
}
 
Animal.prototype.speak = function() {
  console.log(`${this.name} makes a sound.`);
};
 
function Dog(name, breed) {
  Animal.call(this, name); // Inherit properties from Animal
  this.breed = breed;
}
 
// Inheriting methods from Animal prototype
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
 
const dog = new Dog("Buddy", "Golden Retriever");
dog.speak(); // Output: Buddy makes a sound.

In this example:

  • The Dog constructor function inherits the properties from Animal via Animal.call(this, name).
  • The Dog.prototype is set to a new object created from Animal.prototype, which allows instances of Dog to access methods like speak from Animal.

5. Accessing the Prototype

You can access an object’s prototype using Object.getPrototypeOf(). This method returns the prototype (i.e., the object it inherits from).

const dog = new Dog("Buddy", "Golden Retriever");
console.log(Object.getPrototypeOf(dog)); // Output: Animal { speak: [Function] }

You can also check the prototype using the __proto__ property, although it is less commonly used in modern JavaScript.


6. Prototype Inheritance in Action

Prototype inheritance allows you to create a hierarchy of objects. For instance, a Dog object might inherit from Animal, and you can extend this further to create more specific types of animals.

function Animal(name) {
  this.name = name;
}
 
Animal.prototype.speak = function() {
  console.log(`${this.name} makes a sound.`);
};
 
function Dog(name, breed) {
  Animal.call(this, name);
  this.breed = breed;
}
 
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
 
Dog.prototype.bark = function() {
  console.log(`${this.name} barks.`);
};
 
const dog = new Dog("Buddy", "Golden Retriever");
dog.speak(); // Output: Buddy makes a sound.
dog.bark(); // Output: Buddy barks.

Here, Dog extends Animal by inheriting the speak method and adding a new method bark to its prototype. This illustrates how inheritance works in JavaScript via prototypes.


7. Modifying the Prototype

You can add or modify methods to the prototype of an object or class at any time. This is particularly useful when you need to extend built-in objects or add shared functionality to all instances of a certain type.

For example, adding a new method to all Dog instances:

Dog.prototype.sleep = function() {
  console.log(`${this.name} is sleeping.`);
};
 
const dog = new Dog("Buddy", "Golden Retriever");
dog.sleep(); // Output: Buddy is sleeping.

8. Prototype and Performance

The prototype chain improves performance by sharing common methods among objects. If each object had its own copy of methods, memory usage would increase significantly, especially when dealing with many instances of the same object.


Conclusion

Prototypes are one of the core features of JavaScript that allows you to create efficient and flexible inheritance models. They provide a way to share methods and properties across objects, helping reduce memory usage and making your code more maintainable. By understanding prototypes, you can better design your objects and take advantage of inheritance to create more dynamic and reusable code.


Practice Code Snippet

Here’s a code snippet to practice creating and manipulating prototypes:

JavaScript Code Runner on: classes

IndGeek provides solutions in the software field, and is a hub for ultimate Tech Knowledge.