JavaScript: Class.method vs. Class.prototype.method

Viewed 203138

What is the difference between the following two declarations?

Class.method = function () { /* code */ }
Class.prototype.method = function () { /* code using this.values */ }

Is it okay to think of the first statement as a declaration of a static method, and the second statement as a declaration of an instance method?

5 Answers

Yes, the first one is a static method also called class method, while the second one is an instance method.

Consider the following examples, to understand it in more detail.

In ES5

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

Person.isPerson = function(obj) {
   return obj.constructor === Person;
}

Person.prototype.sayHi = function() {
   return "Hi " + this.firstName;
}

In the above code, isPerson is a static method, while sayHi is an instance method of Person.

Below, is how to create an object from Person constructor.

var aminu = new Person("Aminu", "Abubakar");

Using the static method isPerson.

Person.isPerson(aminu); // will return true

Using the instance method sayHi.

aminu.sayHi(); // will return "Hi Aminu"

In ES6

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

   static isPerson(obj) {
      return obj.constructor === Person;
   }

   sayHi() {
      return `Hi ${this.firstName}`;
   }
}

Look at how static keyword was used to declare the static method isPerson.

To create an object of Person class.

const aminu = new Person("Aminu", "Abubakar");

Using the static method isPerson.

Person.isPerson(aminu); // will return true

Using the instance method sayHi.

aminu.sayHi(); // will return "Hi Aminu"

NOTE: Both examples are essentially the same, JavaScript remains a classless language. The class introduced in ES6 is primarily a syntactical sugar over the existing prototype-based inheritance model.

A. Static Method:

      Class.method = function () { /* code */ }
  1. method() here is a function property added to an another function (here Class).
  2. You can directly access the method() by the class / function name. Class.method();
  3. No need for creating any object/instance (new Class()) for accessing the method(). So you could call it as a static method.

B. Prototype Method (Shared across all the instances):

     Class.prototype.method = function () { /* code using this.values */ }
  1. method() here is a function property added to an another function protype (here Class.prototype).
  2. You can either directly access by class name or by an object/instance (new Class()).
  3. Added advantage - this way of method() definition will create only one copy of method() in the memory and will be shared across all the object's/instance's created from the Class

C. Class Method (Each instance has its own copy):

   function Class () {
      this.method = function () { /* do something with the private members */};
   }
  1. method() here is a method defined inside an another function (here Class).
  2. You can't directly access the method() by the class / function name. Class.method();
  3. You need to create an object/instance (new Class()) for the method() access.
  4. This way of method() definition will create a unique copy of the method() for each and every objects created using the constructor function (new Class()).
  5. Added advantage - Bcos of the method() scope it has the full right to access the local members(also called private members) declared inside the constructor function (here Class)

Example:

    function Class() {
        var str = "Constructor method"; // private variable
        this.method = function () { console.log(str); };
    }
    Class.prototype.method = function() { console.log("Prototype method"); };
    Class.method = function() { console.log("Static method"); };

    new Class().method();     // Constructor method
    // Bcos Constructor method() has more priority over the Prototype method()

    // Bcos of the existence of the Constructor method(), the Prototype method 
    // will not be looked up. But you call it by explicity, if you want.
    // Using instance
    new Class().constructor.prototype.method(); // Prototype method

    // Using class name
    Class.prototype.method(); // Prototype method

    // Access the static method by class name
    Class.method();           // Static method
Related