JavaScript

coding learning websites codepractice

JS Basics

JS Variables & Operators

JS Data Types & Conversion

JS Numbers & Math

JS Strings

JS Dates

JS Arrays

JS Control Flow

JS Loops & Iteration

JS Functions

JS Objects

JS Classes & Modules

JS Async Programming

JS Advanced

JS HTML DOM

JS BOM (Browser Object Model)

JS Web APIs

JS AJAX

JS JSON

JS Graphics & Charts

JavaScript Object Prototypes


In JavaScript, prototypes are a core concept that underpins inheritance and object-oriented programming. Every JavaScript object has an internal link to another object called its prototype. This prototype object can contain properties and methods that are shared among all objects created from the same prototype.

Prototypes allow JavaScript to support inheritance without classical classes, enabling objects to reuse methods and properties, reduce memory usage, and implement efficient code patterns. Understanding prototypes is crucial for mastering object-oriented JavaScript and working with modern frameworks like React, Node.js, and Vue.js.

1. What is a Prototype?

Every object in JavaScript has a hidden property called [[Prototype]] (accessible via __proto__ in older environments or Object.getPrototypeOf() in modern code).

  • The prototype is itself an object.

  • Properties or methods defined on the prototype can be accessed by all instances linked to that prototype.

  • If a property is not found on an object, JavaScript looks up the prototype chain until it finds the property or reaches null.

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

Person.prototype.fullName = function() {
  return `${this.firstName} ${this.lastName}`;
};

const person1 = new Person("Alice", "Smith");
console.log(person1.fullName()); // Alice Smith
  • fullName is defined on the prototype, so all Person instances share the same method.

2. The Prototype Chain

The prototype chain is the mechanism JavaScript uses to inherit properties and methods.

console.log(person1.toString()); // [object Object]
  • Here, toString() is not defined on person1 or Person.prototype.

  • JavaScript looks up the chain to Object.prototype, where toString exists.

  • The chain ends at Object.prototype, whose prototype is null.

3. Adding Methods to Prototypes

Adding methods to a constructor’s prototype is more memory-efficient than adding them inside the constructor.

function Car(brand, model) {
  this.brand = brand;
  this.model = model;
}

Car.prototype.info = function() {
  return `${this.brand} ${this.model}`;
};

const car1 = new Car("Toyota", "Camry");
const car2 = new Car("Honda", "Civic");

console.log(car1.info()); // Toyota Camry
console.log(car2.info()); // Honda Civic
  • info exists once in memory on the prototype, not separately for each instance.

4. Overriding Prototype Methods

An object can override a method inherited from its prototype:

car1.info = function() {
  return `Car: ${this.brand} - ${this.model}`;
};

console.log(car1.info()); // Car: Toyota - Camry
console.log(car2.info()); // Honda Civic
  • Overridden methods exist only on the specific instance.

  • The prototype remains unchanged for other objects.

5. Prototype vs Object Properties

  • Instance properties: Defined inside the constructor; unique per object.

  • Prototype properties/methods: Shared among all instances.

console.log(car1.brand);           // Toyota (instance property)
console.log(car1.__proto__.info);  // function info() {…} (prototype method)
  • Prototype is ideal for methods or common shared data, not for instance-specific values.

6. Accessing the Prototype

You can access an object’s prototype using:

  • Object.getPrototypeOf(obj) (standard)

  • obj.__proto__ (older, not recommended)

console.log(Object.getPrototypeOf(car1) === Car.prototype); // true
  • Use prototype inspection for debugging inheritance or extending objects.

7. Extending Built-in Prototypes

You can extend built-in objects like Array or String, but it should be done carefully to avoid conflicts.

Array.prototype.first = function() {
  return this[0];
};

const arr = [10, 20, 30];
console.log(arr.first()); // 10
  • Extending prototypes can add custom behavior to all instances, but avoid overriding existing methods.

8. Prototype Inheritance

Prototypes allow inheritance by creating a chain of objects:

function Animal(name) {
  this.name = name;
}

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

function Dog(name, breed) {
  Animal.call(this, name); // call parent constructor
  this.breed = breed;
}

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

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

const dog1 = new Dog("Rex", "Labrador");
dog1.speak(); // Rex barks
  • Dog inherits from Animal, demonstrating prototype-based inheritance.

9. Notes and Best Practices

  • Use prototypes for shared methods, not instance-specific data.

  • Avoid extending built-in prototypes unless necessary.

  • Use Object.create() for safe inheritance.

  • Remember that modifying the prototype affects all instances.

  • Prototypes are foundational for class syntax introduced in ES6.

10. Summary of the Tutorial

  • Every JavaScript object has a prototype, which is an object it inherits from.

  • Prototype methods and properties are shared among instances, saving memory.

  • The prototype chain enables inheritance, method lookup, and object extensions.

  • Overriding prototype methods allows customization at the instance level.

  • Prototypes are crucial for object-oriented programming and form the backbone of JavaScript classes.

Mastering prototypes allows developers to write efficient, memory-conscious, and modular code, making them a critical part of advanced JavaScript programming.


Practice Questions

  1. Basic Prototype Method
    Create a constructor Person with firstName and lastName. Add a method fullName() to its prototype and log the full name of an instance.

  2. Shared Prototype Method
    Create a Car constructor. Add a method info() to its prototype. Create multiple car objects and show that all share the same method.

  3. Overriding Prototype Method
    Override the info() method in one instance of Car and log outputs of multiple instances to show only one instance is affected.

  4. Prototype Chain Access
    Create an object and log a method inherited from Object.prototype, such as toString(). Explain where the method is found.

  5. Extending Built-in Prototypes
    Add a first() method to Array.prototype that returns the first element. Test it on an array.

  6. Prototype Inheritance
    Create a constructor Animal with a method speak(). Create a Dog constructor that inherits from Animal and overrides speak(). Test it with a Dog instance.

  7. Constructor vs Prototype Property
    Add an instance property and a prototype property to Car. Log both and explain the difference.

  8. Accessing Prototype
    Use Object.getPrototypeOf() to verify the prototype of an object created with a constructor.

  9. Adding Multiple Methods
    Add multiple methods to a prototype using Object.assign() and test them on an object instance.

  10. Safe Inheritance with Object.create()
    Create a proto object with a method greet(). Use Object.create() to make a new object inheriting it, and log the greeting.


JavaScript

online coding class codepractice

JS Basics

JS Variables & Operators

JS Data Types & Conversion

JS Numbers & Math

JS Strings

JS Dates

JS Arrays

JS Control Flow

JS Loops & Iteration

JS Functions

JS Objects

JS Classes & Modules

JS Async Programming

JS Advanced

JS HTML DOM

JS BOM (Browser Object Model)

JS Web APIs

JS AJAX

JS JSON

JS Graphics & Charts

Go Back Top