ES6 Classes, when to use them & how they work

My team and I had a discussion about the use of classes within our applications. There were some concerns about them being used as if they were Java classes (think StrategyIteratorDescriptorAdapterOrderBroadcaster). However, we came to the conclusion that there is a clear distinction between when to use them, and when not to.

When to use them

Our team came up with an interesting point: what’s the difference between a class and a function? In javascript, not a whole lot. However, when thinking about it in the broader sense, my teammate stated:

We should use classes for functions that have state.

That sentence clarified it so precisely for me. As an Angular developer, I’ve used classes for Services and Controllers without problems. I’ve loved the syntax and clarity they bring my applications. However, I always struggled to use them in Directives and Factories.

Ultimately, what it comes down to is: Angular is instantiating (calling on the argument passed in representing the function or class) Services and Controllers, but not directives, factories, filters etc.

The reason they are instantiated as opposed to called and having the returned object used, is that they contain state throughout the application. In the case of Services, they are used as singletons, and can have application wide data set inside of them. In addition, controllers maintain the state of their component or view.

However, directives, factories and filters are simply functions used to generate objects or a result that cares nothing of the state of the application.

tl;dr If it has state, and functions that utilize that state, a class is a good option.

How classes work in Babel

Classes are simply syntactic sugar. Ultimately, when transpiled by Babel, the classes become simply functions.

Constructor functionality is executed immediately in the function declaration, followed by the setting up of the prototypical functions on the class.

Babel adds an additional failsafe to prevent developers from executing a class as a function, but that’s it. The transpile functionality is pretty straightforward!

class Test {  
constructor(name) { = name;
sayHi() {
console.log(`Hi, ${}.`);
new Test('Evan').sayHi();


function _classCallCheck(instance, Constructor) {  
if (!(instance instanceof Constructor)) {
throw new TypeError('Cannot call a class as a function');
var Test = function () {
function Test(name) {
_classCallCheck(this, Test); = name;
Test.prototype.sayHi = function sayHi() {
console.log('Hi, ' + + '.');
return Test;
new Test('Evan').sayHi();


Babel allows for us to utilize (what I consider) to be a very clean syntax. I will highlight this syntax in my next post in implementing classes in Angular (more specific examples). If you are interested in viewing a more in depth explanation of class features and syntax, check out the video below.

Front End Developer