Introduction to Prototypes

Prototypes are a fundamental concept in JavaScript that allow objects to inherit properties and methods from other objects. This guide will introduce you to the basics of prototypes, how to use them, and why they are important.

What is a Prototype?

In JavaScript, every object has a prototype. A prototype is also an object, and it serves as a template from which other objects inherit properties and methods. Understanding prototypes is crucial for mastering object-oriented programming in JavaScript.

Creating Prototypes

Default Prototype

Every function in JavaScript has a prototype property that is used to build the __proto__ property of instances created by that function.

default-prototype.js
function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  return `Hello, my name is ${this.name}`;
};

const john = new Person('John');
console.log(john.greet()); // "Hello, my name is John"

Object.create()

The Object.create method creates a new object, using an existing object as the prototype for the newly created object.

obj-create.js
const person = {
  isHuman: false,
  printIntroduction: function() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};

const me = Object.create(person);
me.name = 'John'; 
me.isHuman = true; 

me.printIntroduction(); // "My name is John. Am I human? true"

Prototype Chain

JavaScript objects have a chain of prototypes, known as the prototype chain. When accessing a property, JavaScript will look up the prototype chain until it finds the property or reaches the end of the chain.

proto-chain.js
const obj1 = {
  a: 1,
  b: 2
};

const obj2 = Object.create(obj1);
obj2.c = 3;

console.log(obj2.a); // 1 (from obj1)
console.log(obj2.c); // 3 (own property)

Inheritance with Prototypes

Prototypes allow for inheritance, where objects can inherit properties and methods from other objects. This is a key aspect of object-oriented programming in JavaScript.

inherit-proto.js
function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  console.log(`${this.name} makes a noise.`);
};

function Dog(name) {
  Animal.call(this, name);
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.speak = function() {
  console.log(`${this.name} barks.`);
};

const dog = new Dog('Rex');
dog.speak(); // "Rex barks."

Best Practices

  • Avoid modifying the prototype of built-in JavaScript objects, as it can lead to unexpected behavior and compatibility issues.
  • Use Object.create for inheritance to create cleaner and more readable code.
  • Understand the prototype chain to debug and troubleshoot issues effectively.

Learn more about object-oriented programming and JavaScript prototypes:

FAQ

Q: What is the difference between `__proto__` and `prototype`?

A: __proto__ is a reference to the prototype object of an instance, while prototype is a property of a constructor function that points to the prototype object used to build __proto__ when creating instances.

Q: Can I change the prototype of an existing object?

A: Yes, you can change the prototype of an existing object using Object.setPrototypeOf(obj, prototype). However, it is generally not recommended due to performance concerns.

Q: Why should I avoid modifying the prototype of built-in objects?

A: Modifying the prototype of built-in objects can cause conflicts with other code and lead to unexpected behavior, making your code harder to maintain and debug.