Difference between adding function to prototype and object literal in javascript

Learn difference between adding function to prototype and object literal in javascript with practical examples, diagrams, and best practices. Covers javascript, prototype development techniques wit...

Prototype vs. Object Literal: Adding Functions in JavaScript

Hero image for Difference between adding function to prototype and object literal in javascript

Explore the fundamental differences and use cases for adding functions to JavaScript objects via prototypes versus directly within object literals.

In JavaScript, there are several ways to define objects and their associated behaviors (functions). Two common approaches involve adding functions directly to an object literal or attaching them to the object's prototype. While both methods achieve similar results in terms of function availability, they have distinct implications for memory usage, inheritance, and object instantiation. Understanding these differences is crucial for writing efficient and maintainable JavaScript code, especially when dealing with multiple instances of similar objects.

Adding Functions to Object Literals

When you define a function directly within an object literal, that function becomes a property of that specific object instance. This means that every time you create a new object using an object literal, a new copy of the function is created and stored within that object. This approach is straightforward and easy to understand, making it suitable for single-instance objects or when each object needs its own unique function implementation or state.

const car1 = {
  brand: 'Toyota',
  model: 'Camry',
  start: function() {
    console.log(`${this.brand} ${this.model} started.`);
  }
};

const car2 = {
  brand: 'Honda',
  model: 'Civic',
  start: function() {
    console.log(`${this.brand} ${this.model} started.`);
  }
};

car1.start(); // Output: Toyota Camry started.
car2.start(); // Output: Honda Civic started.

Functions defined directly within object literals

Adding Functions to the Prototype

The prototype is an object that other objects inherit properties and methods from. When you add a function to an object's prototype, that function is shared among all instances created from that constructor function. Instead of each object having its own copy of the function, they all reference the single function defined on the prototype chain. This is a more memory-efficient approach, especially when you have many objects that share the same behavior. It's the cornerstone of classical inheritance patterns in JavaScript.

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

Car.prototype.start = function() {
  console.log(`${this.brand} ${this.model} started.`);
};

const car3 = new Car('Ford', 'Focus');
const car4 = new Car('Nissan', 'Altima');

car3.start(); // Output: Ford Focus started.
car4.start(); // Output: Nissan Altima started.

console.log(car3.start === car4.start); // Output: true (They reference the same function)

Functions added to the prototype of a constructor function

flowchart TD
    A[Constructor Function (Car)] --> B{Car.prototype}
    B --> C[start() method]
    D[car3 instance] --> B
    E[car4 instance] --> B
    subgraph Object Instances
        D
        E
    end
    style B fill:#f9f,stroke:#333,stroke-width:2px
    style C fill:#bbf,stroke:#333,stroke-width:2px

How instances inherit methods from the prototype

Key Differences and When to Use Each

The choice between these two methods largely depends on your specific requirements regarding memory, inheritance, and the uniqueness of behavior. Understanding the implications of each approach will help you make informed decisions in your JavaScript projects.

Hero image for Difference between adding function to prototype and object literal in javascript

Comparison of object literal functions vs. prototype functions

Modern JavaScript (ES6+ Classes)

With the introduction of ES6 classes, the concept of prototypes is often abstracted away, but the underlying mechanism remains the same. When you define methods within a class, they are automatically added to the class's prototype, providing the same memory efficiency as manually adding to prototype.

class Vehicle {
  constructor(type, id) {
    this.type = type;
    this.id = id;
  }

  // This method is automatically added to Vehicle.prototype
  getInfo() {
    console.log(`Vehicle Type: ${this.type}, ID: ${this.id}`);
  }
}

const myCar = new Vehicle('Car', 'XYZ123');
const myBike = new Vehicle('Motorcycle', 'ABC456');

myCar.getInfo();  // Output: Vehicle Type: Car, ID: XYZ123
myBike.getInfo(); // Output: Vehicle Type: Motorcycle, ID: ABC456

console.log(myCar.getInfo === myBike.getInfo); // Output: true

Class methods in ES6 are prototype methods under the hood