In a for loop when concatenating strings and numbers why does i-1 need parenthesis but i+1 works

Viewed 41

My question is simple but I couldn't search using the right keywords to find an explanation:

Why does this cause a NaN:

for (let i = 0; i < 10; i++){
            document.body.innerHTML += 'Number:' + i-1 + '.';
        }

But simply changing the minus to a plus doesn't:

for (let i = 0; i < 10; i++){
            document.body.innerHTML += 'Number:' + i+1 + '.';
        }

Snippet for testing:

for (let i = 0; i < 10; i++){
                document.body.innerHTML += 'Number:' + i-1 + '.';
            }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

</body>
</html>

2 Answers

+ is both addition and concatenation, and they're left-associative. So the expression

'Number:' + i-1 + '.'

is parsed as

((('Number:' + i)-1) + '.')

When you concatenate 'Number:' + i the result is not a number, so you can't subtract 1 from it. Trying to subtract from something that isn't a number results in NaN. You need to use parentheses so that you calculate i-1 first, then concatenate that to Number:.

But when you use +, (('Number:' + i)+1) means to concatenate 1 to the result of 'Number:' + i. Since both operations are concatenation you don't get NaN.

Note that the + version doesn't produce the expected result, since it's not adding. It will print Number:01.Number:11.Number:21..., not Number:1.Number:2.Number:3.... To get the latter output you need to put i+1 in parentheses, too.

You are adding an integer to a string here. That results in a behavior where the integer is converted into a string (for example 1->"1") and then that string is appended to the other string (so "Number:"+"1" -> "Number:1").

This kind of behavior, however, is not defined for subtracting. You cannot subtract a string from another string let alone an integer from a string.

That's why you are getting NaN.

When you place the i-1 in parentheses it will first be evaluated as a singular integer (0 if i is 1 etc.) and then this integer is appended to the string using the logic that's described above.

Related