Write Bulletproof JavaScript

While display issues have long been the bane of a web developer’s existence, current web development projects tend to have much more client side interactivity, focusing ever more attention on the reliability and resilience of the JavaScript you write to deliver the complete interactive experience. Many things can cause unexpected errors in your carefully crafted code.

However, there are a few things that you can do to make sure that your site degrades gracefully and still provides a basic level of functionality when something in the browser goes wrong. The following snippet of code illustrates a few best-practices for defining your JavaScript namespaced modules.

if(typeof namespace !== "undefined") {
    var namespace = {};
}

namespace.module = (function($) {
    var _privateInit = function() {},
    _privateAction = function() {},
    _hiddenAction = function() {};
    
    return {
        init: _privateInit,
        action: _privateAction
    };
})(jQuery);

Let’s begin with the first if statement. It checks to make sure that the object we are using for our namespacing of all of our modules exists. If it does not exist, it creates it in the global scope here. This particular piece of code can be reused in each and every module that you create that is part of the same namespace without having to worry about overwriting the namespace object.

I am utilizing the Revealing Module pattern here to help isolate any errors or exceptions that may inadvertantly be thrown by my code. If an exception were to be thrown in the global scope, nothing in the global scope that was evaluated after the exception would be evaluated, leaving much of your JavaScript unable to be executed by the browser. Using modules that are narrowly focused on a single piece of functionality help to reduce the damage than an unexpected JavaScript error can cause.

Whenever you get around to actually using your module, namespace.module, there are a couple of precautions you should take as well. The first is that you should always call your module as seen in the snippet below.


if(typeof namespace !== "undefined" && typeof namespace.module !== "undefined" && typeof namespace.module.init === "function) {
    namespace.module.init();
}

The if statement above may be a bit overly protective of the code, making sure that all of the parents of the init() function exist and that namespace.module.init is actually a function and not a string or another random object before trying to execute it as a function. This also serves the situation where your namespace.module is provided in a separate JavaScript file from where it is being called, making us unsure of whether that file was successfully loaded or not. When using the namespacce.module in our separate script file, we want to make sure it exists before we attempt to use it so that we prevent any errors from popping up if something happens on the network and the file does not load in time.

If you truly want to write bulletproof JavaScript, you should be checking each function call to internal functions to ensure they exist and if they are in namespaces that the namespaces and modules exist before they are refrenced. Not all JavaScript applications are that sensitive to not ever having an unhandled error, but if yours is, you should do all you can to protect it.

Related Posts

Jul 7, 2014
2 minutes

AddThis Can Cause Your Site To Not Load

Over the last few days, I have run across quite a few websites that seem to never finish loading. After waiting for 20 seconds or more, I give up, realizing that whatever content was on the site wasn’t worth it anymore for me to stare at a blank white browser until it loaded however much longer. Unfortunately for those websites, they are losing traffic that they will never get back.

Jul 3, 2014
2 minutes

== and === in JavaScript and HTML Input Elements

If you read any current information about best practices in JavaScript, you will typically find the following advice somewhere in the list of things to do.

Always use === and !== while avoiding == and !=

While I will never argue against this advice, there are a few things that a developer shoule realize when using === and !== instead of == and !=.

  1. === and !== first do a check of the data type of the two objects you are comparing. JavaScript never forces you to explicitly define the datatype for an object you are creating as it will automatically assign one based on the contents of the object and how it was created.
  2. The output of all of the Math functions produce integers or floats as the datatypes for the resultant numbers. For example, Math.floor(10.39438) will produce 10.
  3. When retrieving the value of any select or input or textarea is always return as a string. This means that even though the value of the string may be a perfectly good number, it will never match a number data type. For example "10" is not equal to 10 when using the ===.

You should always use === and !== instead of == and !=, but you should make sure you understand the datatypes you are dealing with so that your comparison works as expected without any surprises at runtime.

Jun 11, 2014
2 minutes

Defensive Development Failure

In the past, I have argued that devensive development is a useful tool to ensure unexpected exceptions are not introduced into a piece of software as well as ensuring that the error conditions are handled in an appropriate manner. Unfortunately, if defensive development is implemented poorly, it achieves none of its goals and can cause errors and exceptions to occur. One example that I found while reviewing some code recently is below: