JavaScript's Functional Class Pattern
Tags: javascript, objectorientation, javascriptclasses
Published: 2018-01-17 20:16:35

---
title: JavaScript's Functional Class Pattern
published: true
description: A beginner's guide to understanding classes in JavaScript
tags: Javascript, Object Orientation, Javascript classes
---

*This article was originally published a few years ago on my [blog](http://www.thegreatcodeadventure.com/). This month, I'm teaching the [Intro to JS/Accelerated Bootcamp Prep](https://flatironschool.com/programs/accelerated-bootcamp-prep/) class at [The Flatiron School](https://flatironschool.com/) (and having a great time!). Answering the questions that such a large, diverse group of students raise always surprises me by forcing me to look at old concepts with new eyes, and even learn something new. Prompted by a question one Bootcamp Prep students asked me, I revisited an article I wrote a while back when I was first grappling with the concept of classes in JavaScript. I thought I'd repost it here for newbies and more experienced folk alike. It never hurts to re-think foundational concepts, even if we think they have nothing left to teach us––in my experience, they almost always do.*

---

In Ruby, we think of classes as entities that are capable of producing objects handle just one responsibility. For example, in a blogging application you would have a "Post" class that is responsible for creating posts. 

In Javascript, the definition of class is very similar. 

**What is a Javascript class?**

Put simply, a class in Javascript is any function that is capable of producing of fleet of similar objects--that is, objects with similar properties. 

In Ruby, creating a class is simple, and, unlike many other things in Ruby, there's only one way to do it:

```ruby
class Cylon

 def initialize(number, attitude)
   @number = number #cylons don't have names, they 
   have numbers, it makes them much scarier, trust me. 
   @attitude = attitude
 end

 def human_disguise(human_name)
   @human_name = human_name
 end

end

```

The Cylon class is responsible for making new super-intelligent and human-like robots and each robot that it makes will share properties with it's siblings. (That's right, we're back in Battlestar Gallactica land, sorry guys). 

In Javascript, there are several ways that you can produce similar objects. Let's take a look at a few before we dive into the functional class pattern. 


**Delegation**

In order to write re-usable code and keep our code DRY, it can be necessary to create Javascript objects that share properties.

For example, if you have trying to take over the world (or save it? The end of BSG always really confused me), you need to produce a lot of Cylons. These Cylons need to share at least some of their properties--for example, they must all want to take over the world. 

Let's take a look at using delegation to achieve this aim. 

The code below creates a variable `cylon` and sets in equal to an object with the properties we need. 

```javascript
var numberEleven = {species: "Cylon", attitude: "subdued"} 
```

Now, if we want to create more Cylons, we can use delegation: 

```javascript
var numberEight = Object.create(numberEleven)
```

The object stored in the variable `numberEight` now has all of the properties associated with the object stored in the variable `numberEleven`. 

This means that when we call `numberEight.species`, the lookup for that value is delegated to `numberEleven`. This delegation is ongoing and it is preformed in real-time, whenever the code is run and that particular line is read. 

You can still interact with the `numberEight` object in the same way you would interact with any other object. That is to say that we can give `numberEight` its very own properties. For example: 

`numberEight.humanName = "Sharon"`

Now, `console.log(numberEight.humanName)` will output "Sharon" without having to delegate that lookup to the `numberEleven` object.  


**Object Decorator Pattern**

So far, we've used delegation to create Javascript objects that share properties. What if we need to have similar objects that have similar functionalities or methods? 

For example, all Cylons need to share the ability to lie about the fact that they are Cylons. 

In other words, `lie(numberEight)` should output "I'm not a Cylon! I'm a human!" The same should be true of the object stored in `numberEleven`. 

Keeping out code DRY, we don't want to define *both* objects with the same functionality--that would cause us to repeat ourselves every time we create a new Cylon. 

Let's abstract out the `lie` functionality:

```javascript
var lie = function(cylon){
      cylon.attitude = "aggressive";
      console.log("I'm not a Cylon! I'm a human!");
}
```



So far, we have a very basic example of a cylon object, one method of producing additional cylons(delegation), and one function that handles cylon objects and adds stuff to them. 

There are a few reasons that we're not very happy with our code as it currently stands. 

Right now, in order to invoke the `lie` function, we need to pass it an argument of a cylon object. What if we wanted to call `.lie` on a cylon ojbect? In other words, what if we want each Cylon to come with the ability to `lie` right out of the box? That's not possible with our code right now. 

Additionally, as our program grows and becomes more complex and as the Cylons come closer and closer to destroying Earth, we may want to be creating Cylon objects that have more complex functionality and additional properties. Our earlier delegation--`var numberEight = Object.create(numberEleven)`--just won't cut it anymore. 

Let's step it up a little: 

```javascript
var cylonLike = function(obj, number, attitude)

    obj.number = number;
    obj.attitude = attitude;
    return obj;
}

```

Ta-da! We have our very first **decorator**. The `cylonLike` function's job is to take in an object and augment it with the properties needed to be considered a Cylon. 

When a function takes in an object and augments that object with additional properties or functionality, that function is considered a **decorator**. 

Let's use our decorator to create a new Cylon object with all the attributes that a Cylon needs:

`var numberSeven = cylonLike({}, 7, "subdued")`

We invoke the `cylonLike` function, pass it an empty object, a number and an attitude. Then, `cylonLike` goes to work on that object in the manner defined above. 

Decorators are not limited to adding properties to an object. They can also add functionality, i.e. methods. 

Our previously defined `lie` function can be added to the `cylonLike` decorator so that all cylon objects passed through our decorator function can have the ability to invoke the lie function and escape human detection to carry out their evil plan. 

```javascript
var cylonLike = function(obj, number, attitude)

    obj.number = number;
    obj.attitude = attitude;
    obj.lie = lie;
    return obj;

}

```

We *almost* have the ability to call `.lie` on a Cylon object. We need to refactor our `lie` function to that it no longer needs to take in an object, but is instead called on one: 

```javascript
var lie = function(){
      this.attitude = "aggressive";
      console.log("I'm not a Cylon! I'm a human!");
}
```

This example was simple, and we found ourselves passing an empty object into the `cylonLike` decorator function. Decorator functions are usually used to add some property/functionality to an object that already has properties attached to it. 

**The Functional Class Pattern**

Earlier, we defined a class as any function capable of producing a fleet of similar objects. Our decorator function above certainly has that capability. However, we still wouldn't consider that to be a class in the commonly used sense of the term. **A class builds the object its going to augment, while a decorator accepts the object it will augment as an argument.** 

Since the objects we decorated above were empty, let's just ask our `cylonLike` function to build Cylons for us in the first place:

```javascript
var Cylon = function(number, attitude){

  var obj = {number: number, attitude: attitude};
  obj.lie = lie;
  return obj;

}
```

And there we have our very first class! The functions that produce our similar objects are called *constructor functions*. 

When the constructor function is invoked, it creates an *instance* of our `Cylon` class:

`var numberThirteen = Cylon(13, "subdued")`

But, what if I want to *add* methods to instances of the `Cylon` class? Or, what if I in fact *don't* need *all* of my Cylons to have the ability to lie? Remember when Sharon didn't even *know* she was a Cylon? How could she lie about it then? Enter **prototyping.**

**Prototyping**

We already know that any object can be made to delegate its failed property lookups to another object. Currently, however, we're in a bind. If we leave our constructor in its current state, we are aren't being DRY--we're allowing the `lie` method to be read and stored at run-time, every time we make a new Cylon. We only want that to happen when the `lie` method is actually invoked. But, if we take the `lie` method, any other methods, out of the constructor, how can we give our Cylon instances access to it?

We can use the **prototype object** to store shared methods. If we refactor our constructor code slightly, we can give all instances of the Cylon class the ability to delegate failed lookups to methods stored in that object.  
 
First, let's create our prototype object: 

```javascript
Cylon.prototype.lie = function(){
  this.attitude = "aggressive";
  console.log("I'm not a Cylon! I'm a human!");
}
```

Now, let's refactor our Cylon constructor:

```javascript
var Cylon = function(number, attitude){

  var obj = Object.create(Cylon.prototype);
  obj.number = number;
  obj.attitude = attitude
  return obj;

}
```

Now, each instance of the `Cylon` class is able to have `.lie()` called on it but the compiler won't read and store that function until it is called by an instance of `Cylon`. 

That's all for now! This has been a brief intro to object orientation in Javascript (and Battlestar Gallactica).