What is prototype in Javascript?

In JavaScript, almost every object is an instance of an object type that comes with predefined properties and methods. This functionality is not hard-coded into each object but resides in a special property called the prototype. The prototype is a master object that provides common properties and methods to instances of the same object type.

JavaScript Prototypes in Action

Let's look at a simple, real-world example. Here we've defined a function myCustomForEach that loops through an array and calls a provided callback function for each element:

// without using prototype
function myCustomForEach(array, callback) {
  for (let i = 0; i < array.length; i++) {
    callback(array[i], i);
  }
}

const a = [1, 2, 3, 4];
myCustomForEach(a, (item, idx) => console.log(item, idx)); // Using custom function

This works, but we have to pass our array to the function every time we want to use it, which isn't as clean or efficient as using a built-in method like Array.prototype.forEach

Load our function with prototypes

Let's redefine myCustomForEach to be an array method by attaching it to Array.prototype has changed.

// with prototype: define your custom method
Array.prototype.myCustomForEach = function(callback) {
  for (let i = 0; i < this.length; i++) {
    callback(this[i], i);
  }
};

Now everything has changed. Every array in our program can use myCustomForEach as if it were a built-in method.

const a = [1, 2, 3, 4];
a.myCustomForEach((item, idx) => console.log(item, idx));

Summary

JavaScript prototypes allow developers to extend built-in types or define new types with custom behaviour. By harnessing the power of prototypes, we can write more flexible, maintainable, and DRY code. But remember - when you add a property or method to a prototype, that addition becomes available to all instances of that prototype. If an instance already has a property with the same name, this can lead to confusing behavior. Also, if a prototype is modified, all instances of that prototype must be updated. This can lead to a non-trivial performance overhead, especially in systems with a large number of object instances.

Happy coding!