Daily Tips & Tricks for Web Enthusiasts

JavaScript

Access Object Properties with Variables

Typically object properties in JavaScript are accessed using the dot notation, like this:

var object = {
    foo: 'bar'
};

var example = object.foo; // example is now 'bar'

But what if you don’t know the property name at runtime?

Let’s say you wanted to write a function called propertyOfObject() that took two arguments, object and propertyName, and returned the value of the specified property. Dot notation won’t work in a situation like this:

function propertyOfObject(object, propertyName) {
    return object.propertyName; // This doesn't work!
}

That would look for a property that was literally named propertyName, which is not what we want.

The solution is to use bracket notation to access the property value, like so:

function propertyOfObject(object, propertyName) {
    return object[propertyName]; // Bingo.
}

Any object property can be accessed using bracket notation, and you can put any expression you want inside the brackets, as long as that expression evaluates to a string for the property you’re after. All of the following are valid approaches:

object['foo'];
object[propertyName];
object[someFunctionThatReturnsAPropertyName()];

Now you can access object properties at runtime without knowing their names in advance.

Be Careful with Code Formatting

Usually code formatting is a matter of personal preference, with no impact on how code actually works, but there are exceptions.

Let’s start with this if statement:

if (foo) {
    // Do something if foo is true.
} else {
    // Do something else if foo is false.
}

Some people prefer to format their code differently, and would write the if statement above like this:

if (foo)
{
    // Do something if foo is true.
}
else
{
    // Do something else if foo is false.
}

So far, so good. This code looks different, but it works exactly the same.

Now let’s look at a function that returns an object:

function foo() {
    // Imagine some code here.

    return {
        property1: value1,
        property2: value2
    };
}

Good times, no problems here. But what if we try to format this differently, like before?

function foo()
{
    // Imagine some code here.

    return
    {
        property1: value1,
        property2: value2
    };
}

Everything might look fine, but making these formatting changes actually broke the function! Depending on where and how this code is run the foo() function will either return undefined or the code will refuse to run at all and throw a syntax error.

Why? It has to do with semicolons!

Yes, you heard me correctly: semicolons! As you may know, semicolons in JavaScript are (mostly) optional. The reason they’re optional is that JavaScript parsers have a step called automatic semicolon insertion (ASI) which inserts semicolons for you. The problem with the function as written above is, after the parser adds semicolons, you get this:

return;
{
    property1: value1,
    property2: value2
};

So now you’ve got a return statement with nothing attached, meaning one of two things will happen:

  1. The function will return undefined when it hits the return statement and the code following it will never be run.
  2. The parser will throw a syntax error when parsing the code because there’s an object hanging out down there doing nothing, and will refuse to even run the code in the first place.

This also applies to arrays. This is okay:

return [
    value1,
    value2
];

But this is not:

return
[
    value1,
    value2
];

So, regardless of how you format your code, watch out for situations like this. Generally speaking, you’re fine formatting blocks and scopes however you wish; however, object and array literals may need to be treated differently depending on your preferred style.

Naming Functions & Keeping Them Simple

Every time I write a function or method, I take a moment to describe it to myself in plain English. Doing so serves two purposes: It helps me determine if the function is too complex, and it helps me come up with a good name for the function.

If the description I come up with for a function is more than a single sentence, or if that single sentence contains the word “and”, that indicates the function is too complex. In order to keep code understandable and maintainable, each function should serve a single purpose. There are, of course, exceptions to this rule, but they’re few and far between.

If a function does more than one thing it’s likely I’ll end up needing to do those individual things separately at some point in the future, so it’s a good idea to stop and break the function up into individual pieces now before things get too out of hand. It’s also much easier to understand and maintain code that’s broken up into small, easy-to-digest chunks with few (if any) dependencies on each other.

Once I have a function that produces a proper single-sentence, single-purpose description it’s usually easy to turn that sentence into a good, descriptive name for the function. Reduced code complexity and great function and method names with one simple technique!

So, how would you describe your functions?

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.