Classes

A class in JavaScript provides a cleaner, more intuitive syntax that serves as a template for creating new objects, with related attributes and methods. Objects of the same class can be understood as objects of the same type, with common attributes and methods.

  • To declare a class, we use the class keyword, a name, and {} to enclose the block of all its contents. To create a new object from a class, we use the new keyword, the name of the class, and () like calling a function, this is known as instancing an object

class Person {
  greet() {
    console.log('Hello!!');
  }
}

const alan = new Person(); // This is instances as an object of type person
alan.greet();

const laura = new Person(); // This is also an object of type person
laura.greet(); // Can do the same actions

  • In classes, there is a special method called a constructor that is called every time an object is instantiated, and helps initialize the attributes of new objects. In the instance of an object, we pass values as parameters to be processed by the constructor

class Person {
  constructor(name) { // The constructor receives a parameter
    this._name = name;    // The this keyword must be used
    this._behavior = 50;
  }
  checkBehavior() {
    console.log(this._behavior);
  }
}

const alan = new Person('Alan'); // We pass a value to the constructor to be set
alan.checkBehavior();

  • In classes, we create getters and setters to access and manipulate attributes, as well as methods to perform actions. The syntax is the same as an object, but we don't use , to separate methods

class Person {
  constructor(name) { // The constructor receives a parameter
    this._name = name;
    this._score = 50;  // This is set by default
  }
  get score() {
    return this._score;
  }
  set score(newScore) {
    this._score = newScore;
  }
  incrementScore() {
    this._score++;
  }
}

const alan = new Person('Alan');
const ana = new Person('Ana');
console.log(alan.score); // Use a getter
alan.score = 60; // Use a setter
console.log(alan.score);
alan.incrementScore(); // Use a method
console.log(alan.score);
console.log(ana.score); // The values are different for each instance


  • We can also define private attributes with the # character, which cannot be accessed from outside the class

class Counter {
  #count = 0; // Private field
  increment() {
    this.#count++;
    return this.#count;
  }
  getCount() {
    return this.#count;
  }
}

const counter = new Counter();
counter.increment(); // This works as the method is inside the class
console.log(counter.getCount()); // Access through a getter from inside the class
console.log(counter.#count); // Accesing it directly generates an error

Inheritance

With inheritance, we can create a parent class (superclass) with properties and methods that multiple child classes (subclasses) share, to reutilize code and create objects that share properties. The child classes inherit the properties and methods from their parent class.

  • In the declaration of the child class, we use the extends keyword and the name of the parent class to specify the inheritance. Then we use the super() method in the constructor to pass the arguments to the constructor of the parent class, which will assign all methods and attributes of the parent class. However, child classes can also have properties of their own

class Animal {  //   The parent class
  constructor(name) {
    this._name = name;
    this._behavior = 20;
  }    
  get name() {
    return this._name;
  }
  get behavior() {
    return this._behavior;
  }
  incrementBehavior() {
    this._behavior++;
  }
} 

class Dog extends Animal{  // The child class that inherits from the parent
  constructor(name, bark) {
    super(name);    // This passes the arguments to the constructor of the parent
    this.bark = bark; // This is exclusive of the child class
  }
  play(){
    console.log('Happy Woof')
  }
}

let doggy = new Dog('Jake','Woof'); // Instance the child class
console.log(doggy.behavior); // We can access the properties inherited
doggy.incrementBehavior(); // And use the methods inherited
console.log(doggy.behavior); 
console.log(doggy.bark); // We can also access the exclusive properties
doggy.play(); // And use the exclusive methods

  • Also, static methods can be defined, which can only be accessed by calling the class itself and not through the instantiated objects. We use the static keyword to define these methods

class Animal {  //   The parent class
  constructor(name) {
    this._name = name;
  }    
  get name() {
    return this._name;
  }
  static generateName() {
    const names = ['Angel', 'Spike', 'Buffy', 'Willow', 'Tara'];
    const randomNumber = Math.floor(Math.random()*5);
    return names[randomNumber];
  }
} 

class Dog extends Animal{  // The child class
  constructor(name) {
    super(name);
  }
}

let tyson = new Dog('Tyson'); // Instance the child class
console.log(Animal.generateName()); // Called from the parent class
console.log(tyson.generateName()); // This generates an error
let snow = new Animal('Snow'); // Instance the parent class
console.log(snow.generateName()); // Even with this generates error

Last updated