How to write a fast (and readable) method in JavaScript

Good methods should read like a story.  They should have an introduction, a climax, and a conclusion.  Here is what a good method might look like:

/**
Returns the first content object in the receivers content array whose key
matches the passed value.  
*/
findContentForValue: function(key, value) {
//
  // INTRODUCTION:  Collect data you will need into local variables.
  // Any data you might reference repeatedly should be collected here (such
// as the array length)
// Normalize your data here when possible to make the rest of the method
// flow...
  var content = Array.from(this.get('content')) ;  // The source content array
  var loc = content.get('length') ;  // The current search location.
  var ret = null ;  // The return value (or null if none found)
//
// CLIMAX:  Do the operation.
  while(!ret && (--loc >= 0)) {
    var obj = content.objectAt(loc) ;
    if (obj.get(key) === value) ret = obj;
  }
//
// CONCLUSION:  Cleanup and return the values.
  return ret ;
}

The Introduction

The introduction is where you collect all of your variables and setup your context.  A solid introduction is important to a good method because it both makes your method easier to read and improves performance.  

By declaring the variables you will work with up front, you help make clear to readers of your code what data you expect to work with.  This will prepare them to understand the rest of your code as it comes along.  It is also helpful to put commented explanations here describing what each method will do.  This way as a reader tries to digest your code, they will have a glossary to refer to when they see an unfamiliar variable.

If readability alone weren’t enough, JavaScript actually rewards you for using this style by making your code faster as well.  Every time you reference a variable (’foo’), JavaScript will search up a “scope” chain to find the value.  This chain begins with your current function and terminates with the “window” object, where global values will go.  By bringing all of the values you will be working with into local variable, you help to short-circuit this process for most calls.

The Climax

This is the part of your code that actual does the work.  Perform some processing, search through some data, whatever.  This code should generally try to work mostly with variable declared in your introduction and it should avoid returning early.  Instead, you should store the return variable somewhere and save it for your conclusion.

I’ve instituted a no-early-return policy for many years and often get a lot of pushback on it; but there are some good reasons for it.  I contend that early returns are one of the biggest barriers to maintaining code over the long term for two reasons.  First, early returns make your code a lot harder to follow.  There is nothing more frustrating than adding a console log or tracing some code only to have it return early before it gets to the part you wanted to investigate.  Second, early returns make it hard to re-factor your code.  How many times have you had to readjust a method because you needed to add some extra step to the process but some earlier code tried to exit before it ever got there?

That said, there are some good reasons to do an early return and I do use them in code when it makes sense.  For example, if you use a cached value to determine if a method needs to run at all, then an early return is fine.  I often put this code into the introduction-portion of the method in fact so that it is obvious to everyone when a method might not run at all.  Second, sometimes your code will have so many exit conditions that not using early returns will make the code harder to read.  This kind of code usually means you need to refactor anyway, but if it is unavoidable, early returns are preferrable to unreadable code.

The Conclusion

Conclusions should be simple.  They should not contain critical logic to your method and they should wrap up any loose ends so a reader can clearly see what they will get back when the function exits.  If you need to notify anyone of property changes or perform any other general housekeeping like that, do it here as well.  You should clearly indicate when you go into your cleanup phase, though, through comments so the reader knows they should not expect to see more application logic there.

My Conclusion

So that’s how you write a good method.  Pretend it is a story.  Introduce your variables at the beginning, do something interesting in the middle and return at the end.  Avoid referencing variables that are not in a local scope and avoid early returns.  If you do this, your JavaScript code will not only be far more readable, but it will perform better too.

 

2 Responses to “How to write a fast (and readable) method in JavaScript”

  1. Great post. I think generally writing code is a lot like writing prose. Sometimes I write just to get ideas out, then go back and edit for clarity. And sometimes I need to rewrite entirely. I also find that commenting my code is a great way to work out bugs, or uncover potential gotchas.

    As I work with other people’s source, I am developing a keen interest in making my own code more readable, more explicit and self instructive (with the hope that others will do the same). It’s great to read an approach that has as much to do with style as substance.


  2. Charles - agree! Good post. I also try to go by the no-early-return rule whenever I can, glad to see that it is used by others as well.


Discussion Area - Leave a Comment