Categories
javascript jslint postfix-operator prefix-operator syntax

Why avoid increment (“++”) and decrement (“–“) operators in JavaScript?

386

One of the tips for jslint tool is:

++ and --
The ++ (increment) and -- (decrement)
operators have been known to contribute to bad code by
encouraging excessive trickiness. They
are second only to faulty architecture
in enabling to viruses and other
security menaces. There is a plusplus
option that prohibits the use of these
operators.

I know that PHP constructs like $foo[$bar++] may easily result in off-by-one errors, but I couldn’t figure out a better way to control the loop than a:

while( a < 10 ) do { /* foo */ a++; }

or

for (var i=0; i<10; i++) { /* foo */ }

Is the jslint highlighting them because there are some similar languages that lack the “++” and “--” syntax or handle it differently, or are there other rationales for avoiding “++” and “--” that I might be missing?

16

  • 65

    So one should do array[index=index+1] instead of array[++index] (if the former is even permitted!). What a load of hooey.

    Jun 9, 2009 at 17:15

  • 34

    I’ve not seen Crockford do index=index+1. I’ve seen him do index+=1. I think that’s a reasonable alternative. And it’s nice for when you want to change the stride to something besides 1.

    – Nosredna

    Jun 9, 2009 at 17:51

  • 131

    Personally I am not a big fan of Crockford. He seems to regard anything that has ever caused a bug in his code to be evil.

    Jun 10, 2009 at 19:41

  • 38

    In JavaScript you should regard every bug as somewhat evil, since there is no official documentation nor is there a certificate provider nor do you learn JS properly in the University. Crockford and Firebug have filled these holes in JavaScript education.

    Sep 19, 2010 at 16:54


  • 44

    ++ doesn’t cause bugs. Using ++ in “tricky” ways can lead to bugs, especially if more than one person is maintaining the codebase, but that’s not a problem with the operator, it’s a problem with the programmer. I didn’t learn JS at university (because it didn’t exist yet), but so what? I did do C, which of course had ++ first, but that also gets a “so what?” I didn’t go to university to learn a specific language, I went to learn good programming practices that I can apply to any language.

    – nnnnnn

    Nov 9, 2011 at 0:37


438

My view is to always use ++ and — by themselves on a single line, as in:

i++;
array[i] = foo;

instead of

array[++i] = foo;

Anything beyond that can be confusing to some programmers and is just not worth it in my view. For loops are an exception, as the use of the increment operator is idiomatic and thus always clear.

6

  • 4

    Yeah, that’s what I do too. Hard to go wrong, and easier for other people to figure out what you’re doing.

    – Nosredna

    Jun 9, 2009 at 17:46

  • 73

    That seems to be getting at the core of the issue and my confusion. Used alone, i++; is crystal clear. The minute you add other code around that basic expression, readability and clarity begin to suffer.

    – artlung

    Jun 9, 2009 at 17:54

  • 3

    Agree, but it’s not only JavaScript related

    – Tobias

    Feb 4, 2013 at 13:37

  • 6

    You don’t say whether you are writing C or C++. Arguably you should use the prefix increment operator in C++, in case the i variable later becomes a composite class, in which case you’d be needlessly creating a temporary object. I find the postfix operator more aesthetically pleasing though.

    – mc0e

    Jan 11, 2014 at 8:22


  • 4

    I prefer the 1-line version. It reminds of a stack operation. push is array[++i] = foo, pop is bar = array[i–]. (But with 0-based arrays, array[i++] = foo and bar = array[–i] look still better). Another thing, I would hate it if someone added extra code between i++; and array[i] = foo;.

    – Florian F

    Jun 22, 2016 at 21:38


71

There is a history in C of doing things like:

while (*a++ = *b++);

to copy a string, perhaps this is the source of the excessive trickery he is referring to.

And there’s always the question of what

++i = i++;

or

i = i++ + ++i;

actually do. It’s defined in some languages, and in other’s there’s no guarantee what will happen.

Those examples aside, I don’t think there’s anything more idiomatic than a for loop that uses ++ to increment. In some cases you could get away with a foreach loop, or a while loop that checked a different condtion. But contorting your code to try and avoid using incrementing is ridiculous.

13

  • 121

    i = i++ + ++i; made my eyes hurt a little – 🙂

    – hugoware

    Jun 9, 2009 at 17:38

  • 4

    Mine too. Even if they weren’t all the same variable, say I had x = a++ + ++b; — that combination instantly makes x, a and b harder to hold in my head. now, if each were separate statements on separate lines, as in — a++; ++b; x = a + b; it would be easier to comprehend on first sight.

    – artlung

    Jun 9, 2009 at 17:46

  • 11

    Alas, (a++; b++; x=a=b) is not the same value as (a++ + ++b).

    Jun 9, 2009 at 20:48

  • 9

    @Marius: x = a+++b –> x = (a++)+b –> x = a + b; a++. The tokeniser is greedy.

    Sep 27, 2010 at 13:31


  • 16

    For extra job safety, remove the spaces in your last example.

    – mc0e

    Jan 11, 2014 at 8:28

53

If you read JavaScript The Good Parts, you’ll see that Crockford’s replacement for i++ in a for loop is i+=1 (not i=i+1). That’s pretty clean and readable, and is less likely to morph into something “tricky.”

Crockford made disallowing autoincrement and autodecrement an option in jsLint. You choose whether to follow the advice or not.

My own personal rule is to not do anything combined with autoincrement or autodecrement.

I’ve learned from years of experience in C that I don’t get buffer overruns (or array index out of bounds) if I keep use of it simple. But I’ve discovered that I do get buffer overruns if I fall into the “excessively tricky” practice of doing other things in the same statement.

So, for my own rules, the use of i++ as the increment in a for loop is fine.

3

  • Excellent point about the “plusplus” option being just that, an option. Based on yours and other answers I think I’m getting the sense that ++ by itself or a for-loop are not in and of themselves confusing. The second you combine that ++ into another statement you r statement becomes more difficult to read and understand in context.

    – artlung

    Jun 9, 2009 at 17:43

  • 6

    everyone gets buffer overflows. Even OpenSSH with their open source and their multiple comitees of revision

    – Eric

    Jun 10, 2009 at 14:22

  • 11

    @Eric Revisiting your five-year-old comment: oh, how right you were!

    – wchargin

    Feb 3, 2015 at 0:31