JavaScript classes introduced in ECMAScript 6 are syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax is not introducing a new object-oriented inheritance model to JavaScript. JavaScript classes provide a much simpler and clearer syntax to create objects and deal with inheritance.
In ES5 and earlier, constructor functions defined “classes” like this:
function Person() {};
var me = new Person();
ES2015 introduces a new syntax. Defining a class involves the class keyword followed by the name for the class
class Person {};
var me = new Person;
With just those two lines you have created a class and one instance of a that class and assigned it to variable me. That easy :D
An important difference between function declarations and class declarations is that function declarations are hoisted and class declarations are not. You first need to declare your class and then access it, otherwise code like the following will throw a ReferenceError
:
var p = new Polygon(); // ReferenceError
class Polygon {}
The optional constructor method allows you to perform actions when an instance of a class is instantiated although you probably just want to take this opportunity to define properties.
The constructor runs every time a new instance is created with the new
operator.
class Person {
constructor(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
}
var me = new Person('Flip', 'Stewart');
NOTE: Currently there are no access modifiers in javascript, like private
and protected
. So in case you're wondering, prefixing a method with an underscore is a convention for indicating that the referred method should not be invoked from the public API.
As an example, you can see buildLink
function in the code below.
class Person {
constructor(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
this.getLink = () => {
return this._buildLink();
}
}
var me = new Person('Flip', 'Stewart');
We can use class inheritance to reduce code repetition. Child classes inherit and specialize behaviour defined in parent classes.
extend
allows you to create a subclass !!!
When creating a sub class, you call super
with the necessary parameters for the base class. Any additional properties must be defined after that super
call.
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
class Client extends Person {
constructor(firstName, lastName, typeOfClient) {
super(firstName, lastName);
this.typeOfClient = typeOfClient;
}
}
var me = new Client('John', 'Doe', 'distinguish');
From outside of the constructor, you can also call super, but as an object. Methods from base classes are available on super within their corresponding sub classes.
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName() {
return this.firstName + ' ' + this.lastName;
}
}
class Vendor extends Person {
constructor(firstName, lastName) {
super(firstName, lastName);
this.fullName = super.getFullName();
}
}
var me = new User('John', 'Doe');
console.log(me.fullname); // "John Doe"
static
methods may only be called on the class itself as opposed to on its instantiated instances.
Static methods on a base class may be called on super from within a subclass.
class Cat {
static getGreeting() {
return 'meow';
}
}
class LoudCat extends Cat {
static getGreeting() {
return super.getGreeting().toUpperCase();
}
}
Cat.getGreeting();
// "meow"
LoudCat.getGreeting();
// "MEOW"
var zemo = new LoudCat();
zemo.getGreeting();
// Uncaught TypeError: zemo.getGreeting is not a function
Getters and setters work!
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
get fullName() {
return (this.formattedPrefix ? this.formattedPrefix: '') + this.firstName + ' ' + this.lastName;
}
set prefix(string) {
this.formattedPrefix = string + ' ';
}
}
var me = new Person('Mario', 'Bros');
me.prefix = 'Super';
me.fullName
// "Super Mario Bros"