STATIC METHODS
We can also assign methods to the classes themselves, not just their “prototype”. These methods are called static. Inside the
class, these are preceded by the keyword static, as we can see in the example:
class User {
static staticMethod() {
alert(this === User);
}
}
User.staticMethod(); // true
The value of this in the User.staticMethod() call is represented by the constructor of the User class (the rule of the object before the dot). Usually, static methods are used to represent functions that belong to the class, but not to a particular object. For example, we may have objects of type Article and need a function to compare them. A natural solution would be to add the Article.compare method, like nell’esempio:
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 Article.compare stands “above” the articles, as it is intended to compare them. It is not a method of an article, but rather of the whole class. Another common example is that of the “factory method” (a particular design pattern). Let’s imagine we need different ways of creating an article:
- Creation with the parameters provided (title, date etc).
- Creating a blank article with today’s date.
- … Or any other way.
The first method can be implemented through the constructor. While for the second, we can create a static method belonging to the class.
Like Article.createTodays () in the example:
class Article {
constructor(title, date) {
this.title = title;
this.date = date;
}
static createTodays() {
// ricorda, 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 digest”, we can invoke Article.createTodays(). Let’s repeat it again, this is not a method for a specific article, but rather a method of the entire class. Static class methods are defined on the class itself. You cannot call a static method on an object, only on an object class.
class Car {
constructor(name) {
this.name = name;
}
static hello() {
return “Hello!!”;
}
}
let myCar = new Car(“Ford”);
// You can call ‘hello()’ on the Car Class:
document.getElementById(“demo”).innerHTML = Car.hello();
// But NOT on a Car Object:
// document.getElementById(“demo”).innerHTML = myCar.hello();
// this will raise an error.
If you want to use the myCar object inside the static method, you can send it as a parameter:
class Car {
constructor(name) {
this.name = name;
}
static hello(x) {
return “Hello “ + x.name;
}
}
let myCar = new Car(“Ford”);
document.getElementById(“demo”).innerHTML = Car.hello(myCar);
STATIC PROPERTIES
It is also possible to define static properties, these are very similar to the properties of the class, but are preceded by the keyword static:
class Article {
static publisher = “Ilya Kantor”;
}
alert( Article.publisher ); // Ilya Kantor
INHERITANCE OF METHODS AND STATIC PROPERTIES
Static properties and methods are also inherited. For example, Animal.compare and Animal.planet in the code below, are inherited and then become accessible as Rabbit.compare and Rabbit.planet:
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;
}
}
// Eredita da 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 when we invoke Rabbit.compare, the inherited Animal.compare method will be invoked.
How does it work? Again, using the prototypes. As you may have guessed, extends gives Rabbit the reference to Animal’s [[Prototype]].
- The Rabbit function inherits from the Animal function.
- prototype inherits the prototype of Animal.prototype.
As a result, inheritance works for both regular and static methods. Now, let’s verify this by looking at the code:
class Animal {}
class Rabbit extends Animal {}
// per proprietà statiche
alert(Rabbit.__proto__ === Animal); // true
// per proprietà regolari
alert(Rabbit.prototype.__proto__ === Animal.prototype); // true
Leave A Comment