ES6 class learning - class static attributes and static methods

Posted by musson on Mon, 28 Feb 2022 08:34:11 +0100

Static properties and static methods

We can assign a method to the function itself of the class instead of the "prototype" assigned to it. Such a method is called static.

In a class, they start with the static keyword as follows:

class User {
  static staticMethod() {
    alert(this === User);
  }
}

User.staticMethod(); // true

This is actually the same as assigning it directly as an attribute:

class User { }

User.staticMethod = function() {
  alert(this === User);
};

User.staticMethod(); // true

In User The value of this in the staticmethod() call is the class constructor User itself ("object before dot symbol" rule).

Typically, static methods are used to implement functions that belong to the class but do not belong to any specific object of the class.

For example, we have the object Article and need a method to compare them. A natural solution is to add Article Compare method, as follows:

class Article {
  constructor(title, date) {
    this.title = title;
    this.date = date;
  }

  static compare(articleA, articleB) {
    return articleA.date - articleB.date;
  }
}

// usage
let articles = [
  new Article("HTML", new Date(2019, 1, 1)),
  new Article("CSS", new Date(2019, 0, 1)),
  new Article("JavaScript", new Date(2019, 11, 1))
];

articles.sort(Article.compare);

alert( articles[0].title ); // CSS

Here is article Compare stands for "above" articles, which means to compare them. It is not the method of the article, but the method of the whole class.

Another example is the so-called "factory" approach. Imagine that we need to create an article in several ways:

  1. Create (title, date, etc.) by using the given parameters.
  2. Use today's date to create an empty post.
  3. ... other methods.

The first method can be implemented through the constructor. For the second method, we can create a static method of the class to implement.

Like article here createTodays():

class Article {
  constructor(title, date) {
    this.title = title;
    this.date = date;
  }

  static createTodays() {
    // Remember this = Article
    return new this("Today's digest", new Date());
  }
}

let article = Article.createTodays();

alert( article.title ); // Today's digest

Now, whenever we need to create a today's article, we can call article createTodays(). Again, it is not the method of an article, but the method of the whole class.

Static methods are also used in public classes related to the database, which can be used to search / save / delete entries in the database, like this:

// Suppose Article is a special class used to manage articles
// Static methods are used to remove articles:
Article.remove({id: 12345});

Static properties

Static attributes are also possible. They look like regular class attributes, but they are preceded by static:

class Article {
  static publisher = "Levi Ding";
}

alert( Article.publisher ); // Levi Ding

This is equivalent to directly assigning a value to Article:

Article.publisher = "Levi Ding";

Inherit static properties and methods

Static properties and methods are inheritable.

For example, in the following code, animal Compare and animal Planet can be inherited through rabbit Compare and rabbit Planet to access:

class Animal {
  static planet = "Earth";

  constructor(name, speed) {
    this.speed = speed;
    this.name = name;
  }

  run(speed = 0) {
    this.speed += speed;
    alert(`${this.name} runs with speed ${this.speed}.`);
  }

  static compare(animalA, animalB) {
    return animalA.speed - animalB.speed;
  }

}

// Inherited from Animal
class Rabbit extends Animal {
  hide() {
    alert(`${this.name} hides!`);
  }
}

let rabbits = [
  new Rabbit("White Rabbit", 10),
  new Rabbit("Black Rabbit", 5)
];

rabbits.sort(Rabbit.compare);

rabbits[0].run(); // Black Rabbit runs with speed 5.

alert(Rabbit.planet); // Earth

Now we call rabbit Compare, inherited animal Compare will be called.

How does it work? Again, use the Prototype. As you may have guessed, extends makes Rabbit's [[Prototype]] point to Animal.

Therefore, Rabbit extends Animal creates two [[Prototype]] References:

  1. The Rabbit function prototype inherits from the Animal function.
  2. Rabbit.prototype is inherited from animal prototype.

As a result, inheritance works for both regular and static methods.

Here, let's check through the code:

class Animal {}
class Rabbit extends Animal {}

// For static
alert(Rabbit.__proto__ === Animal); // true

// For conventional methods
alert(Rabbit.prototype.__proto__ === Animal.prototype); // true

summary

Static methods are used to implement functions that belong to the entire class. It has nothing to do with concrete class instances.

For example, a method for comparison article Compare (article1, article2) or a factory method article createTodays().

In class life, they are marked with the keyword static.

Static attributes are used when we want to store class level data instead of binding to instances.

The syntax is as follows:

class MyClass {
  static property = ...;

  static method() {
    ...
  }
}

Technically, a static declaration is the same as a direct assignment to the class itself:

MyClass.property = ...
MyClass.method = ...

Static properties and methods are inheritable.

For class B extensions A, the prototype of class B points to A: B.[[Prototype]] = A. Therefore, if A field is not found in B, it will continue to find in A.

Topics: Javascript Front-end