Learnitweb

static in JavaScript

1. Introduction

The static keyword is used to define static method, property or static initialization block for a class. A static method or property is accessed using the class name. A static method or static property can not be accessed using instance of the class.

If a method or a property is not associated to the instance of the class but to the class itself then it can be made static. Utility methods such as round(x), floor(x) which are used for calculation are usually created as static methods as these are not related to the state of the object but work on the argument data. Properties which are used for configuration and are not supposed to change for instances of the class are usually made static.

A static method or property is accessed using the class name:

  • CLASS_NAME.property
  • CLASS_NAME.method()

2. Example of static property and method

class Area {
  static pi = 22 / 7;

  static areaOfCircle(radius) {
    return this.pi * radius * radius;
  }
}

let result = Area.areaOfCircle(7);
console.log(result); // 7

In this example, pi is created as static property and areaOfCircle is created as static method. You can access a static property from a static method within the same class using this.

3. Accessing static member from another static method

To access a static property or method within another static method within the same class, you can use this:

class Decorator {
  static suffix = "!!";
  static msg = "Hello ";

  static addPrefixAndSuffixStr(str) {
    return this.msg + str + this.suffix;
  }

  static decoratedString(str) {
    return this.addPrefixAndSuffixStr(str);
  }
}

let res = Decorator.decoratedString("John");
console.log(res); // Hello John!!

In this code, decoratedString method is calling another static method addPrefixAndSuffixStr using this. The method addPrefixAndSuffixStr is accessing static properties msg and suffix using this.

4. Calling static members from a class constructor

Static members can be called from non-static methods using the class name or by calling the property or method as a property of the constructor.

class MyClass {
  constructor() {
    console.log(MyClass.staticProperty); // static property
    console.log(this.constructor.staticProperty); // static property
    console.log(MyClass.staticMethod()); // static method called.
    console.log(this.constructor.staticMethod()); // static method called.
  }

  static staticProperty = "static property";
  static staticMethod() {
    return "static method called.";
  }
}

let obj = new MyClass(); 

5. Class static initialization blocks

  • A class static initialization block is used to initialize static properties.
  • In a static block executable statements are allowed like any other block.
  • You can declare var, let, const, and function in a static block.
  • A class can have any number of static blocks.
  • Static blocks are executed in the order of their declaration.
  • In case of inheritance, static initialization block of parent class is executed before child class.
  • The scope of variables declared inside the static block is local to the block and therefore var declarations in static block are not hoisted.
class MyParent {
  static staticProperty;

  static {
    console.log("first static block execution");
    this.staticProperty = "new value";
  }

  static {
    console.log("second static block execution");
  }
}

console.log(MyParent.staticProperty);

Output

first static block execution
VM587:10 second static block execution
VM587:14 new value

5.1 this in static block

The this inside a static block refers to the constructor object of the class.

class MyClass {
  static staticProperty;

  static {
    this.staticProperty = "new value";
  }
}

console.log(MyClass.staticProperty); // new value

5.2 super in static block

The super can be used inside a static block to reference properties of a super class.

class Parent {
  static parentProperty = "parent value";
}

class Child extends Parent{
  static childProperty;

  static {
    this.childProperty = super.parentProperty;
  }
}

console.log(Child.childProperty); // parent value