ES6 — classes and inheritance
Let’s talk about ECMAScript 2015
OO keywords is probably the most awaited features in ES6. Classes are something like another syntactic sugar over the prototype-based OO pattern. We now have one, concise way to make class patterns easier to use.
Over the prototype-based OO pattern to ensure backwards compatibility.
Overview — an example of ES6 class syntax and ES5 equivalent
class Vehicle {
constructor (name, type) {
this.name = name;
this.type = type;
}
getName () {
return this.name;
}
getType () {
return this.type;
}
}let car = new Vehicle('Tesla', 'car');
console.log(car.getName()); // Tesla
console.log(car.getType()); // car
It’s naive example, but we can see a new keywords as class and constructor.
ES5 equivalent could be something like this:
function Vehicle (name, type) {
this.name = name;
this.type = type;
};
Vehicle.prototype.getName = function getName () {
return this.name;
};
Vehicle.prototype.getType = function getType () {
return this.type;
};var car = new Vehicle('Tesla', 'car');
console.log(car.getName()); // Tesla
console.log(car.getType()); // car
Classes support prototype-based inheritance, super calls, instance and static methods and constructors.
It’s simple. We instantiate our classes the same way, but let’s add some..
inheritance
..to it and start from ES5 example:
function Vehicle (name, type) {
this.name = name;
this.type = type;
};
Vehicle.prototype.getName = function getName () {
return this.name;
};
Vehicle.prototype.getType = function getType () {
return this.type;
};function Car (name) {
Vehicle.call(this, name, ‘car’);
}Car.prototype = Object.create(Vehicle.prototype);
Car.prototype.constructor = Car;
Car.parent = Vehicle.prototype;
Car.prototype.getName = function () {
return 'It is a car: '+ this.name;
};var car = new Car('Tesla');
console.log(car.getName()); // It is a car: Tesla
console.log(car.getType()); // car
And now look at the ES6 version:
class Vehicle {
constructor (name, type) {
this.name = name;
this.type = type;
}
getName () {
return this.name;
}
getType () {
return this.type;
}
}class Car extends Vehicle {
constructor (name) {
super(name, 'car');
}
getName () {
return 'It is a car: ' + super.getName();
}
}let car = new Car('Tesla');
console.log(car.getName()); // It is a car: Tesla
console.log(car.getType()); // car
We see how easy is to implement inheritance with ES6. It’s finally looking like in other OO programming languages. We use extends to inherit from another class and the super keyword to call the parent class (function). Moreover, getName() method was overridden in subclass Car.
super — previously to achieve such functionality in Javascript required the use of call or apply
static
class Vehicle {
constructor (name, type) {
this.name = name;
this.type = type;
}
getName () {
return this.name;
}
getType () {
return this.type;
}
static create (name, type) {
return new Vehicle(name, type);
}
}let car = Vehicle.create('Tesla', 'car');
console.log(car.getName()); // Tesla
console.log(car.getType()); // car
Classes gives us an opportunity to create static members. We don’t have to use the new keyword later to instantiate a class.
static methods (properties) are also inherited
and could be called by super
get / set
Other great things in upcoming ES6 are getters and setters for object properties. They allow us to run the code on the reading or writing of a property.
class Car {
constructor (name) {
this._name = name;
}
set name (name) {
this._name = name;
}
get name () {
return this._name;
}
}let car = new Car('Tesla');
console.log(car.name); // Teslacar.name = 'BMW';
console.log(car.name); // BMW
I use ‘_’ prefix to create a (tmp) field to store name property.
Enhanced Object Properties
The last thing I have to mention is property shorthand, computed property names and method properties.
ES6 gives us shorter syntax for common object property definition:
// ES6
let x = 1,
y = 2,
obj = { x, y };console.log(obj); // Object { x: 1, y: 2 }// ES5
var x = 1,
y = 2,
obj = {
x: x,
y: y
};console.log(obj); // Object { x: 1, y: 2 }
As you can see, this works because the property value has the same name as the property identifier.
Another thing is ES6 support for computed names in object property definitions:
// ES6
let getKey = () => '123',
obj = {
foo: 'bar',
['key_' + getKey()]: 123
};console.log(obj); // Object { foo: 'bar', key_123: 123 }// ES5
var getKey = function () {
return '123';
},
obj = {
foo: 'bar'
};obj['key_' + getKey()] = 123;console.log(obj); // Object { foo: 'bar', key_123: 123 }
The one last thing is method properties seen in classes above. We can even use it in object definitions:
// ES6
let obj = {
name: 'object name',
toString () { // 'function' keyword is omitted here
return this.name;
}
};console.log(obj.toString()); // object name// ES5
var obj = {
name: 'object name',
toString: function () {
return this.name;
}
};console.log(obj.toString()); // object name
Like it? Recommend it!
Whole series is also available as an ebook. I published it on leanpub.com
Future is bright!