Static Methods & Properties in JS
One of the feature related to properties and methods which exists in javascript es6 or later is static properties and methods.
It allows us to add properties and methods to classes that are not accessed on an instance of a class, meaning that you don’t need to call new ClassName first, you can just access them directly on the class. It is often utility functions or global constants which you want to store in a class.
An example built into javascript is the math constructor function or class that’s globally available, where you can access PI as a constant value to get the number of PI, or functions or methods like POW to calculate the power of a number. These are methods and properties which you don’t access on the instance of math (there is no need to call new Math first, but you can access the properties and methods directly on the class itself. so in this example, math acts more like a namespace which is a common use case for static methods and properties and we can add them to our classes as well.
For example, let’s define a Rectangle class with width and height properties:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}Now we want a method that helps us calculate the area of the rectangle:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
getArea() {
return `Area is: ${this.width*this.height}`;
}
}Let’s say we want a new rectangle:
const rectangle1 = new Rectangle(50, 20);
console.log(rectangle1.getArea());Here the console output: Area is: 1000
Now we want to be able to access getArea without instantiating Rectangle ,because we don’t really want to instantiate Rectangle just to call a utility method.
So we can add the static keyword in front of getArea method and pass width and height as properties to the method instead of using this :
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
static getArea(width, height) {
return `Area is: ${width*height}`;
}
}Now we can just call the getArea method directly on the Rectangle class without the new keyword and therefore we used the class as a namespace:
const rectangle1 = Rectangle.getArea(50, 20);
console.log(rectangle1);The output would be: Area is: 1000
If you’d want to add a static property to your class, just use the static keyword in front of your property.
For example, to add a unit of measurement to our Rectangle class, we can define a unit property:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
static getArea(width, height) {
return `Area is: ${width*height}`;
}
static unit = 'centimeter'
}Now if we log the unit:
console.log(Rectangle.unit);The output would be: centimeter
One thing we should keep in mind is when we add them to a class, we can’t access them from the none-static parts of the class. So if we tried to access unit inside constructor, it won’t work:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
console.log(this.unit);
}
static getArea(width, height) {
return `Area is: ${width*height}`;
}
static unit = 'centimeter'
}We’ll get the following error:
Property 'unit' is a static member of type 'Rectangle'
So we can’t access it because the constructor and all the other methods that are not marked with static will not be able to access static properties, because this refers to the instance created based on the class and the static property is not available on an instance since the idea behind static properties and static methods is the fact that they are detached from instances.
If you want to use static property or methods from inside the class, you’d have to use the class name:
In the end we need to use dispatch our actions in addTodo() and removeTodo() methods in order to change the state:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
console.log(Rectangle.unit);
}
static getArea(width, height) {
return `Area is: ${width*height}`;
}
static unit = 'centimeter'
}