Classes
What are classes in JavaScript?
Just like constructor functions classes in JavaScript are blueprints (or templates) for creating objects.
Classes in JavaScript are built upon prototype JavaScript functionality and are a type of functions.
Class can be initialized through a class declaration or a class expression. Once a class is declared or expressed it cannot be re-declared or re-expressed.
Class Declarations
A class declaration is signalled using the class
keyword.
class Animal {
}
Class declarations - as opposed to function declarations - are not hoisted. Trying to access a class before its declaration results in a RerefenceError
.
Class Expressions
Class expressions - just like function expressions - can be unnamed or named.
const Animal = class {
}
Animal // => class {}
Animal.name // => 'Animal'
const Person = class Human {
}
Person // => class Human {}
Human // Uncaught ReferenceError: Human is not defined
Person.name // => 'Human'
Strict Mode
The body of a class is always executed in strict mode - irrespective of whether use strict
directive is present or not.
Constructor & Initialization
A class can include one (and only one) constructor
method within body. In the constructor
method properties of its particular instances can be assigned.
Instances are initialized using the new
keyword.
class Animal {
constructor(species, name) {
this.species = species
this.name = name
}
}
const geraltsHorse = new Animal('horse', 'Roach')
geraltsHorse // => Animal {species: 'horse', name: 'Roach'}
const cirisHorse = new Animal('horse', 'Kelpie')
cirisHorse // => Animal {species: 'horse', name: 'Kelpie'}
Extending Classes
One of the powerful features of classes is their capability of being extended. An extended class (subclass) inherits features of the class it extends (superclass).
class Animal {
constructor(species, name) {
this.species = species
this.name = name
}
presentMe() {
console.log(`I am a ${this.species} and my name is ${this.name}.`)
}
}
class Horse extends Animal {
}
const napoleonsHorse = new Horse('horse', 'Marengo')
napoleonsHorse.presentMe() // => "I am a horse and my name is Marengo."
Although, the method presentMe()
was not defined on the Horse
class it is available to instances of the Horse
class as the class Horse
extends features of the class Animal
.
Super
When a subclass defines a property that is already defined on its superclass it overwrites it. However, it is still possible to refer to the superclass property with the super
keyword.
If a constructor function is present in a subclass then to use this
the keyword super
needs to be invoked first.
class Animal {
constructor(species, name) {
this.species = species
this.name = name
}
presentMe() {
console.log(`I am a ${this.species} and my name is ${this.name}.`)
}
}
class Horse extends Animal {
constructor(name) {
super('horse')
this.name = name
}
}
const alexandersHorse = new Horse('Bucephalus')
alexandersHorse // => Horse {species: 'horse', name: 'Bucephalus'}
alexandersHorse.presentMe() // => "I am a horse and my name is Bucephalus."
Single Superclass
In JavaScript there is no multiple inheritance. A class can extend only one class.
Extending Classes with Constructor Functions
It is possible in JavaScript to extend classes with constructor functions. However, it is not possible to extend classes with objects that are not constructor functions.
Instance Methods
Functions defined without a static
keyword within a class definition body are assigned as method properties to instances of the class.
class Teacher {
grade() {
return 'You get an A!'
}
}
const profSnape = new Teacher()
profSnape.grade() // => 'You get an A!'
const profHand = new Teacher // Parenthesis are optional with no arguments.
profHand.grade() // => 'You get an A!'
Teacher.grade() // Uncaught TypeError: Teacher.grade is not a function
Static Methods
Functions defined with static
keyword within a class definition body become static (aka class) methods that can be invoked directly from the class object but not from its intances.
class Teacher {
static grade() {
return 'You get an A!'
}
}
const profSnape = new Teacher()
profSnape.grade() // Uncaught TypeError: profSnape.grade is not a function
Teacher.grade() // 'You get an A!'
Private Fields
Both instance methods and static methods - as well as all other non-function properties - are public which means that they are accessible from outside of the class definition body. To make them private the sigil #
can be used.
class Person {
#name // A private field needs to be declared first.
constructor(occupation, name) {
this.occupation = occupation
this.#name = name
}
}
const aKnight = new Person('knight', 'Don Kichot')
aKnight.occupation // 'knight'
aKnight.name // undefined