Monday, June 30, 2014

Repurposing Function Variables

Sometimes, I create too many local variables inside my functions. This can help with code-readability, especially if the function is involved. So what's the overhead in declaring these new variables that exist for a fraction of a second before they're garbage collected? Probably not too high — you're not going to see any perceivable performance improvements by declaring less variables.

However, there are certain cases where an added local variable in your function definition exists for no good reason, including readability. Regular expressions are a good example of something I use an intermediary variable for. Consider this function.

function v1( search ) {
    var result = ( /(\w+)\/(\w+)/ ).exec( search );
    return result === null ? [] : result.slice( 1 );
}

This function is pretty simple. It has two local variables — search and result. The search argument is some string that gets passed to the function while the result variable is something I've created to store the result of evaluating the regular expression. You can tell which one's the intermediary value just by it's name — result — what's that supposed to mean? The reason I need this variable in the first place is that I need to perform a check, to make sure there's actually a result. Then, if that check passes, I need to call slice() on result, and return the value of that.

But do we really need to create a new result variable that's local to this function? I mean, it's a really straight-forward function that's probably called frequently — maybe there's a way that we could implement this simple function that doesn't sacrifice readability? Here's one way to do it.

function v2( search ) {
    return ( search = ( /(\w+)\/(\w+)/ )
        .exec( search ) ) === null ? [] :
            search.slice( 1 );
}

Here, we're assigning the result to the search argument — it's just another variable like anything else we'd define ourselves, only it's already defined. I think part of the reason I've been reluctant to use this approach in the past is because I didn't really think of function arguments as variables. But since we've already called exec() on the regular expression, it's served it's purpose, and so not we can use it again.

Where we would have assigned the result of evaluating the regular expression to the result variable, we're just assigning it to the search variable, since we're no longer using it for anything else. This is all one in the same expression that checks for a null value and returns the sliced array.