Daily Tips & Tricks for Web Enthusiasts

JavaScript

Tips for Naming Variables

One of the hardest problems in programming is naming things. Today, I’m going to give you a few tips for picking useful names for your variables in JavaScript. Don’t worry, future tips will cover naming other things.

The most important thing to keep in mind when choosing names for your variables is who you’re naming them for. Many people have the misconception that the computer cares about the name of your variables, or that different variable names have some kind of performance impact. This is not true. Decades ago, when memory was incredibly scarce, programming was brand new, and every byte mattered, keeping your variable names short actually did have an impact. Thankfully, those days are now well behind us.

Another common fallacy is thinking that as long as your variable names make sense in the moment, you’re fine. Maybe you think you’ll never need to come back to this code in the future (chances are you will), or that you’ll be able to pick things back up quickly and easily. Nothing could be further from the truth.

When you’re writing code, you’re thinking about the entire program. You have some version of it running in your head. You have context. Naming a variable a or temp or aThing might make perfect sense in the moment, but you have to remember that your current coding mindset is temporary. If the names of your variables aren’t clear, it will be incredibly hard to remember what you were thinking in two weeks, let alone two months or two years from now.

You don’t name variables for the computer, and you don’t name them for the you of today. Your target audience when naming variables is Future You, and anyone else who might need to understand your code later.

The trick to naming variables correctly is twofold:

  1. Keep Future You, and other people, in mind.
  2. Walk the line between too short and too long.

One way to tell if your variable names are conveying what they need to convey is to try reading your code like a sentence. If you come up with something like, “This function takes A and add B and C to it and then returns the result,” that’s a bad sign. You want to aim for something like “This function takes a price and adds tax and shipping to it.”

On the other end of the spectrum, I’ve seen variable names like thePriceWithTaxAndShippingAdded and postsAfterFilteringHTML. In some situations names like these might be warranted (when in doubt, Future You will appreciate more verbosity instead of less), but names like these usually point to bigger problems in the code, like a lack of clarity and context in the surrounding functions, comments, and/or methods.

If you find yourself being overly verbose with your variable names ask yourself why you feel the need for that level of detail. Has your code gotten away from you? Are you not adding in proper comments? Find and fix those underlying problems first, then try naming your variables again.

When all else fails, ask yourself this question: “If I look at this code six months from now, will the name of this variable sense?”

Embrace Curly Braces

In JavaScript (and many other C-style languages) you can do this:

if (condition)
    foo();

While this code is perfectly valid, and will run as expected, you should never omit an if statement’s curly braces like this. Why? Take a look at this code:

if (condition)
    foo();
    bar();

This code is also perfectly valid, but it’s incredibly deceptive. In this example, only foo(); is attached to the if statement. Despite appearances, bar(); will run no matter what.

This code is functionally identical, but much clearer:

if (condition) {
    foo();
}
bar();

Leaving out curly braces might save you a few keystrokes, but it’s a nightmare for code readability and maintenance. Save Future You from confusion and hassles: always use curly braces!

Don’t Trust Client-Side JavaScript

It’s important to remember that the JavaScript embeded or attached to your website is going to be run inside a web browser you don’t control, which is running on a computer you don’t control. Your code can be disabled or altered by various browser extensions, configurations, and developer tools.

Most of the time your code will run just fine, but you can’t count on it. Make sure your site works well even if JavaScript is disabled, and don’t use client-side JavaScript for anything critical.

The most common mistake made with trusting client-side JavaScript is relying on it to validate form input. It’s a great idea to give people a better experience by letting them know about issues before they even submit a form using JavaScript, but you have to remember that JavaScript may never even be executed. Data validation and sanitation must be done on the server side regardless.

Note that this tip only applies to client-side JavaScript running in the web browsers of your visitors, not JavaScript (or other code) running on your server.

Beware of typeof

The typeof operator in JavaScript is full of strange quirks. Before I show you what to watch out for let's take a look at what it does correctly.

First of all, typeof will always return a string that (supposedly) describes what follows it. Here are some examples that work as expected, with the resulting string shown in a comment following each statement:

typeof undefined; // 'undefined'
typeof true; // 'boolean'
typeof 42; // 'number'
typeof 'foo'; // 'string'
typeof function () {}; // 'function'
typeof { foo: bar }; // 'object'

So far, so good. But what about using typeof on an array?

typeof [foo, bar]; // 'object'

Well, okay, arrays are technically objects in JavaScript, so that's cool, I guess.

What about null?

typeof null; // 'object'

So that's, uh, also an object? Okay, sure.

What about a class?

typeof class baz {}; // 'function'

So a class is a function? Again, technically true, but maybe not the result we were expecting.

What about NaN, which literally stands for "not a number"?

typeof NaN; // 'number'

Oh, JavaScript, you precious thing.

Now that you know to watch out for those unexpected results, let's talk about how to get some more useful information from unknown types.

The Object class in JavaScript has a toString method prototype that can be called directly to produce a string that's a bit more descriptive and useful:

Object.prototype.toString.call(undefined); // '[object Undefined]'
Object.prototype.toString.call(true); // '[object Boolean]'
Object.prototype.toString.call(42); // '[object Number]'
Object.prototype.toString.call('foo'); // '[object String]'
Object.prototype.toString.call(function () {}); // '[object Function]'
Object.prototype.toString.call({ foo: bar }); // '[object Object]'
Object.prototype.toString.call([foo, bar]); // '[object Array]'
Object.prototype.toString.call(null); // '[object Null]'

Much better. We can now tell the difference between an object, an array, and null!

Alas, this method still falls short when it comes to classes and NaN:

Object.prototype.toString.call(class baz {}); // '[object Function]'
Object.prototype.toString.call(NaN); // '[object Number]'

The class situation makes sense; classes in JavaScript are really just fancy syntax for special functions, but it would be nice to see something like [object Class] returned here all the same. Oh well.

So, be careful when using typeof, and use Object.prototype.toString.call() if you need something a bit more descriptive.

Avoid Comparison Surprises

Get in the habit of using the strict comparison operators (=== and !==) in JavaScript. When you use == or != JavaScript will, depending on the values being compared, perform automatic type conversion, which can cause some odd and unexpected behavior.

Take this example:

'0' == 0; // Evaluates to true.

How is a string containing the character 0 equal to the integer zero? Because, when using == or !=, JavaScript converts the string into a number before performing the comparison. Using the strict comparison operators works as expected:

'0' === 0; // Evaluates to false.

That’s just one example of how automatic type conversion can get you into an unexpected and hard-to-debug situation. Using === and !== will avoid such nonsense and always do what you expect.