·

photo credit: Game Prototyping With Wooden Blocks & Pieces via photopin (license)

How I Write JavaScript nowadays

When it comes to JavaScript, I’ve come a long way. When I was a kid, I wrote my first sample of JavaScript with a simple alert() -method. Later, at school, I learned using different frameworks to accomplish various tasks, like MooTools for accordeon menu’s and Prototype for my first taste of AJAX. And in the end I – like many others – embraced jQuery for my everyday JavaScript accomplishments.
But things change… JavaScript used to feel a bit quirky, and with the many browser differences in the past (and I’m talking about browsers like Internet Explorer 4/5/6 and Firefox 2 here), libraries like the ones described above were almost mandatory just to get things working and keep the fun in development. In fact, I think that the success and innovations in JavaScript are a direct result of the huge embrace of these libraries. For most web developers these were in fact the first steps into writing JavaScript.
But times change, browsers become better, JavaScript evolves, EcmaScript 6 is around the corner, and you see that many developers prefer writing lean and mean JavaScript instead of importing one giant do-it-all library and smudge all their code in one big pile of JavaScript and jQuery mixed together. And so do I. In this article I’ll show you how my JavaScript skills have changed in time and even more so: how I write my JavaScript nowadays.

In the beginning, there was a steamy big pile of …

We’ve all been there: your site needs some neat interaction, widgets, AJAX thingies or whatever you want to call them, and we create it with JavaScript. So where do we start? Most of the times, this was a single JavaScript file for our code and some external libraries that we use. At the end of the day, our JavaScript file looks something like this:

Now time goes by and more features are added, modified and removed in this big script that does it all… Some methods are added outside the document ready scope, because we have buttons or anchors that call them, some variables need to be global, some more methods are added, etc. etc. etc. Quickly, your file begins to look something like this:

Sooner or later you end up with one huge JavaScript file of several hundreds lines of code and it’s a nightmare to maintain. Bugs are appearing more frequent and it’s taking a bite out of your performance too!

Decoupled architecture

Now one thing that is most apparent in the example above is that we try to provide all the functionality of the complete website in one main scope (the all-famous $(document).ready() ). This can be because the project started small and became bigger in time, or that we think it’s best for the server load to keep everything in one file or because we just don’t know any better… The big problem with this is that it’s not separated: all the functionality is in one big file and it’s the perfect recipe for a nice bowl of spaghetti code.

Use separate files

The first thing you need to do is use separate files for your functionality. Got a hamburger menu? Create a hamburger.js -file and put the only the functionality of that specific item in that file. Got a search form with an autocomplete-functionality? search.js  or autocomplete.js  to the rescue!
The benefits gained when you keep your functionality divided across multiple files are great:

  • You keep you code nice, clean and tidy.
  • It’s easier to divide tasks to multiple programmers.
  • It forces you to keep your JavaScript well-contained and independent of each other.

Of course, having all these tiny, separate JavaScript files isn’t ideal for our page load. After all, we don’t want to load 20-30 JavaScript files each time do we?

Task runners

Lucky for us there are numerous task runners to help us in our every day task as a web developer. Two of the most known are Grunt and Gulp. A little while ago, I wrote an article about how I watch, build and deploy my projects with Gulp. One aspect about that article was the concatenating of JavaScript. In this article I’ll show a more basic Gulp example that only focusses on the JavaScript-part. The npm packages I use are:

And the gulpfile.js  looks like this:

The 2 most important tasks in this setup are js  and build-js . What these tasks do is nothing more than concatenate all of our separate JavaScript files and combine them into 1 file, called scripts.js . That way, our HTML pages only have to include 1 JavaScript files, even though we develop in multiple files.
The difference between these 2 tasks is that js  creates a source map, so we can see in our inspector window where the original JavaScript file is located, whereas the build-js  function creates a minified / uglified scripts.js , and can be used by a build server for example.

Keeping functionality isolated

One major change in the way I write JavaScript nowadays is how I handle the scopes of the different functionalities. As I mentioned in the previous section, each functionality of the website should be in it’s own file. The same goed for the code of this method: the functionality should be in it’s own object. This can be easily done by using JavaScripts’ prototype .
For example: let’s say we’re creating a search with autocomplete. The HTML could look something like this:

Now in the past I might have done something like this in jQuery:

I’m pretty sure many of you have as well.
But:
Defining element ID’s and such directly into the JavaScript files could be considered as bad practice: after all: your JavaScript is assuming that your HTML has those elements and it makes the whole functionality less flexible or even more important: less recyclable. As in: it can’t be (easily) used for other projects without knowing exact how the HTML must be.

Defining the functionality

To overcome this, I first define the functionality in a separate JavaScript function/object. For example:

This file is going to be nice, clean and tidy and it only serves one purpose: the autocomplete function of the search form. Some things to notice:

  • I use parameters in the constructor, these are used to initialise the functionality.
  • I also setup some event listeners in the constructor. Note the usage of the bind(this)-method to make sure that the this-scope in the called method refers to the SearchAutocomplete object.
  • I try to write as little anonymous methods as possible to keep the script readable and prevent a callback-hell.

How to implement this? Well, easy! Just after our form add the following:

And this is how I write JavaScript nowadays: I keeps the HTML nice and tidy, my JavaScript nice, tidy and readable but most import: it keeps my mind nice and tidy as well!

 

Visitors give this article an average rating of 3.6 out of 5.

How would you rate this article?

Leave a Reply