JavaScript is probably the most misunderstood language out there today. It has a lot of flexibility, which might be seen as a weak point, but I consider it to be an opportunity to be expressive and to make decisions about patterns based on problems and not the other way around.

Two such patterns have intrigued me lately so I decided to dig into how and why we use them. The first is the constructor pattern (see example), where you use a function called a constructor function to initialise properties and functions on an object, using the new keyword. This is what I’ve been using for a while and am comfortable doing, but that’s not to say it’s not without its challenges.

JavaScript’s latest version – ES6 (EcmaScript 6/2015) – is widely adopted so its safe to say if you’ve been around JavaScript recently, you’ve seen the new class syntax. It’s important to note that it is just a cover for what’s really going on under the hood. Using a transpiler like Babel, by the time your code sees the light of day in the browser, it will be in ES5 with your class methods changed to prototype functions. Eventually, we should be able to use this code in browsers, but for now we transpile.

Defining classes using the new class syntax provides a cleaner and more explicit way of structuring code, in my opinion. There’s something that has always bugged me about it, and I could never quite put my finger on it. I’m sceptical that it’s doing what we really need JavaScript to do. When we create new classes, we’re basically taking that whole class for what it is and ever will be and instantiating a new object from it. Meaning, when you need to make changes to it down the line, it will inherit that functionality too and so will any other instances.

This can cause a heap of unintended side effects when you start to use classes as you would in classical languages such as Java or PHP. When functionality is duplicated across classes, it’s typical to pull that function out and put it in a parent class, from which two child classes can inherit and behave in the same way. On one hand this is great, because now you’ve removed redundant code so maintenance is easier and you could create more subclasses as necessary to inherit that functionality again. But now, we’ve introduced an indirect relationship between those two child classes, where they both now depend on the same code. If they have to change, we need to set up some kind of if statement or config setting to tell them apart and split functionality. This is starting to get messy. I’m not convinced we want to use JavaScript in this way, as I can see issues arising when you introduce subclasses unless it’s because you want to adopt functionality from a third party source. To me, that seems like the only viable use of classical inheritance in JavaScript.

Another pattern I’ve been researching is the Factory pattern. The factory pattern (see example) is to use a function to create a new object, without using the ‘new’ keyword, typically via an object literal. We know objects in JavaScript can hold properties, functions and other objects, so to compose them we take a few different objects and join them in a single object for a specific purpose. Each object that is added, when necessary, can be interchanged with any other. This can’t really be done easily with classes, where you end up getting more than you bargained for. For the longest time, learning the this keyword in JavaScript and all of its existential meanings was beyond difficult. Luckily, using objects means we can refer to private variables, rather than properties set on an instance, so this is less of a concern.

Being at this low level of objects made of other objects can be really powerful but I’m not seeing a clear structure, which is a really big selling point for classes. As someone who has loved object oriented programming, particularly with classes in PHP, it’s difficult to see how the factory pattern would scale as easily as classes in terms of structure and reasoning of modules. However, as is most things in JavaScript, we’re free to dictate how to solve this. There’s a lot that can be said about each of these patterns, and ones I haven’t mentioned but the point is to choose a pattern that suits the problem or project rather than having a strict opinion on which is better. It goes without saying, but I’ll say it anyway – most, if not all things you do in programming will have about three other ways of achieving the same result.

What I would much rather advocate is that you spend the time learning these concepts yourself so that you can make an informed decision.