A matter of class: examining the class construct in JavaScript
Tags: javascript, oop, class, inheritance
Published: 2017-02-15 11:52:51

---
title: A matter of class: examining the class construct in JavaScript
published: true
description: The class construct is very handy, but it may lead to serious misconceptions about the Object-Oriented nature of JavaScript.
cover_image: http://i.imgur.com/vexE6Kt.png
tags: JavaScript, OOP, class, inheritance
---

_This article was originally published on my [Medium profile](https://medium.com/@andrea.chiarelli)_

It is more than one year and half since the _class_ construct has become part of the official JavaScript syntax. Introduced by the ECMAScript 2015 specifications, this construct has been enthusiastically welcomed by many developers. Indeed, it has been considered a sign of the formalization of various attempts to simulate classes, inheritance and other Object-Oriented features offered for several years by many libraries, such as [Prototype](http://prototypejs.org/), [ExtJS](https://www.sencha.com/products/extjs/), [Dojo](https://dojotoolkit.org/), [Backbone](http://backbonejs.org/), [Ember](http://emberjs.com/) and others. TypeScript itself was born with the aim of bringing the class-based Object-Oriented programming in JavaScript language. However the _class_ construct may lead to serious misconceptions about the Object-Oriented nature of JavaScript. Let's analyze why.

### A convenient construct
Using the _class_ construct is very handy. Just take a look at the following code to define the _Animal_ class:

```javascript
class Animal {
  constructor(name, legsNumber) {
    this.name = name;
    this.legsNumber = legsNumber;
  }
  
  speak() {
    console.log(this.name + â€˜ makes a noise.');
  }
}
```

Now let's compare it with the equivalent ECMAScript 5 code:

```javascript
var Animal = function (name, legsNumber) {
  this.name = name;
  this.legsNumber = legsNumber;
};

Animal.prototype.speak = function() {
  console.log(this.name + â€˜ makes a noise.');
};
```

The _class_ construct provides a much more compact code. It appears self-contained and familiar to people who have a traditional Object-Oriented programming background.

The convenience of this construct becomes even more noticeable when we use inheritance, as we can see by analyzing the following code where the _Snake_ and Horse classes are defined by deriving from _Animal_:

```javascript
class Snake extends Animal {
  constructor(name: string) {
    super(name, 0);
  }
  
  speak() {
    console.log(this.name + â€˜ hisses.');
  }
}

class Horse extends Animal {
  constructor(name: string) {
    super(name, 4);
  }
  
  speak() {
    console.log(this.name + â€˜ whinnies.');
  }
}
```

Let's consider now the respective definitions with the dear old ECMAScript 5:


```javascript
var Snake = function (name) {
  Animal.apply(this, [name, 0]);
};

Snake.prototype = Object.create(Animal.prototype);
Snake.prototype.constructor = Snake;
Snake.prototype.speak = function() {
  console.log(this.name + â€˜ hisses.');
};

var Horse = function (name) {
  Animal.apply(this, [name, 4]);
};

Horse.prototype = Object.create(Animal.prototype);
Horse.prototype.constructor = Horse;
Horse.prototype.speak = function() {
  console.log(this.name + â€˜ whinnies.');
};
```

The convenience of using the _class_ construct seems clear: in addition to a smaller number of statements we get a greater readability and a similarity to the syntax of most Object-Oriented programming languages. Anyway, regardless of the definition used, in both cases we will use the classes and constructor functions in the same way:


```javascript
var kaa = new Snake(“Kaa the Python”);
var fury = new Horse(“Fury the Horse”);

console.log(kaa.legsNumber);    //0
console.log(fury.legsNumber);   //4
```

This ensures the maximum interoperability between the old and the new approach.


### Not everyone is happy
Despite its convenience, however, not all developers are so excited about the introduction of the class construct. It looks familiar to most programmers, and gives the illusion of using a class-based Object-Oriented programming language such as Java and C #.

But that is the whole point: it is an illusion, a dangerous illusion. Contrary to what might seem, ECMAScript 2015 specifications have not introduced *the concept of class* in JavaScript. JavaScript is and remains a prototype-based Object-Oriented programming language, even with the _class_ construct.

The introduction of this construct in JavaScript syntax seems to extend the chain of errors that characterized the definition of this language: from the choice of the name itself, that has caused (and still causes) a bit of confusion with Java, to the use of the _new_ keyword to create objects, [actively contested by Douglas Crockford](http://javascript.crockford.com/prototypal.html).


The main effect of these choices is that programmers are misguided in the real understanding of the language and are led to blame it because its behavior is not what expected.


### Is it a real class?
But what is the difference between the _class_ construct in class-based languages and the one in JavaScript? As we said, JavaScript is still a prototype-based language, so the _class_ construct is just *syntactic sugar* for creating constructor functions in a more compact way. If we try to get the type of a class, we will find that it is not but a function:


```javascript
console.log(typeof Animal);   //function
```

The definition of _Animal_, _Snake_ and _Horse_ by using the _class_ construct has the same effect of its definition by using the old ECMAScript 5-style code. Objects are not created by referencing a class, but by referencing a prototype, that is another object, as usual in JavaScript. This means that we can dynamically change the structure of our objects without involving its original class. For example, we can write the following code:

```javascript
fury.wingsNumber = 2;

console.log(fury instanceof Horse);   //true
```


We add a couple of wings to our _Horse_ object, and it continues to be a horse. That's perfectly legal in JavaScript, but it is very difficult to implement and to understand in a class-based world.

Even worst, we can overturn the whole structure of our _Horse_ object as follows:


```javascript
var furySnake = new Horse();

furySnake.legsNumber = 0;
furySnake.speak = function() {
  console.log(this.name + â€˜ hisses.');
};
```

We have redefined the structure of a _Horse_ like if it was a _Snake_, but it still remains an instance of the _Horse_ class.That's out of any definition of class, not only in the context of programming languages, but also in philosophy and set theory contexts.

For example, from a mathematical point of view, a class is a collection of objects that can be unambiguously defined by one or more properties that all its member share. Clearly, since _fury_ and _furySnake_ share no properties, they cannot belong to the same (conceptual) class. Also from a class-based Object Oriented point of view the two objects can't belong to the same class.


### Conclusion
Maybe the choice of a name other than _class_ would have sounded strange to developers coming from languages like Java, C# and C++, but it would have created fewer illusions and disappointments.

In any case, now the die is cast. The important thing is that the JavaScript developer is aware of what _class_ really means. You have been warned…



_Andrea Chiarelli is the author of [Mastering JavaScript Object Oriented Programming](https://www.packtpub.com/web-development/mastering-javascript-object-oriented-programming) (Packt Publishing)._