Friday, September 6, 2013

Operators, trickiness, and while loops

I've seen a few comments on forums discussing JavaScript that mention Crockford's comment that the increment (++) and decrement (--) operators are tricky and people don't really understand why. I thought I'd take a short post and explain it.

For a number of people, increment and decrement do not appear tricky. They're used to seeing them in a format similar to i++ or c--, or occasionally as ++i or --c, and, because of their use in other languages it appears straightforward. Why are they tricky?

There are a few reasons, but let's go with one of the easiest, and let me explain it with two simple code examples using an array of month names and a loop index.

Formatted code sample demonstrating that while(i--) { /* outputs n */ } and while (--i) { /* outputs n-1 */ }

The primary thing I'd like to point out with this example is that the while using the operator on the right side of the variable will process n instances, which in our case is all 12 months) and the loop using the operator on the left side of the variable will process n minus 1 instances, or 11 of the 12 months.

Of course one of the other things you must be careful of is that when you're using this approach with an array is how you use the length as a boundary. You'll notice since I'm using a decrement operators I'm using the array length rather than length minus 1. I use this because the index is decremented before the being passed to the array to reference the element.

There are a couple of reasons you might want to adopt this approach (or something similar), however. First, a decremented while loop is faster than other loops, at least in JavaScript. The loop is faster yet when there isn't a comparison, e.g. index > 0 as in while (index > 0).

Second, by placing the operator in the evaluation statement you avoid infinite loops caused by carelessly forgetting to add the statement that increments or decrements your loop index.

Of course adopting such an approach means the operators aren't the only thing that's tricky. While this approach is faster and generally more efficient, you must take care in choosing your continuation statement, which in this case is the i-- or --i part of the while. You'll notice that I use the array length as the initial value of our variable because 0 evaluates to false. If I used length minus 1 as our initial value, I might have an initial value of -1. In such cases, our loop would start with a negative array index, because while 0 evaluates as false, all other numbers, including negative values, evaluate as true.

While those of us who understand the trickiness these operators impose and the nuances of the while loops and how numbers are evaluated as true or false may write fast, efficient code using this design pattern, not all JavaScript programmers understand these nuances. As one last tip, I'd recommend that any time you use this pattern you also include a note that explains at least some of what I've covered here. By adding documentation we reduce the chance that someone will copy and paste our code without really understanding it and get themselves, and their users, into trouble.

That's it for today's quick lesson. Happy coding.

No comments:

Post a Comment