0

Here is my code:

for (let i = 0; i <= 100; i++) {
  let output = "";

  if (i % 3 === 0) {
    output += "Cool";
  }
  if (i % 5 === 0) {
    output += "Breeze";
  }
  console.log(output || i);
}

In this code, I use a for loop to vary the value of the binding i from 0 to 100.

In the first if statement, I use the modulo and the addition assignment operator to add the string "Cool" to the binding output.

In the second if statement, I use the modulo and the addition assignment operator to add the string "Breeze" to the binding output.

The function of my last statement in the body of my for loop is to print the value of the output binding in the browser console. I do this through short-circuiting. Now, I understand the logic of short-circuiting with the "OR" operator, since the interpreter will short-circuit its full logic of comparing both operands and automatically choose the operand on the left if it can be converted to true, which strings and numbers can, so the operand output is always going to be chosen.

What I don't understand is why short-circuiting is needed to visibly print every value in the console. If I were to use the statement console.log(output); it consolidates the number type values, stating how many were printed in a row before it had to print a string.

Can someone please explain this logic? Why is short-circuiting needed here to prevent the consolidation?

Snow
  • 3,820
  • 3
  • 13
  • 39
Custer
  • 119
  • 1
  • 8
  • Does this answer your question? [Logical operator || in javascript, 0 stands for Boolean false?](https://stackoverflow.com/questions/9579262/logical-operator-in-javascript-0-stands-for-boolean-false) – VLAZ Jan 01 '20 at 21:13
  • [Also relevant](https://stackoverflow.com/questions/4535647/logical-operators-in-javascript-how-do-you-use-them). – VLAZ Jan 01 '20 at 21:14
  • Simply put, when you OR values, you get he first *truthy* value. So, if `output` has been changed, it will be truthy, so `output || i` will return `output`, however if `output = ""`, the empty string is *falsy*, so `output || i` returns `i` – VLAZ Jan 01 '20 at 21:15
  • That simply explains the logic of short-circuiting. I already understand that 0, NaN, and empty strings count as false, and would never be chosen if they were the left operand. – Custer Jan 01 '20 at 21:15
  • 1
    If you just `console.log(output)`, then for `i` equal to `0`, `1`, `2`, `4`, `6` and so on, you're only printing an empty string and you never print the number. – VLAZ Jan 01 '20 at 21:18
  • What you are asking is why can you not just simply do `console.log(output)`? You can do it and it should work well the only difference is that it will print empty string when `i` is neither a multiple of 3 nor multiple of 5. – John David Jan 01 '20 at 21:19
  • Thank you, VLAZ and John David, I just had a eureka moment. – Custer Jan 01 '20 at 21:51

1 Answers1

2

If I were to use the statement console.log(output); it consolidates the number type values, stating how many were printed in a row before it had to print a string.

In case it isn't clear to others, what you're referring to is this:

enter image description here

This is an artifact of the browser console, which consolidates duplicate logs together, to make debugging easier. Here, it's consolidating the duplicate logged empty strings. It's not a issue with your code's logic. If you were to log the output by any other method, the blank outputs would be displayed serially, as you'd expect, rather than being clumped together:

const table = document.querySelector('table').children[0];

for (let i = 0; i <= 100; i++) {
  let output = "";

  if (i % 3 === 0) {
    output += "Cool";
  }
  if (i % 5 === 0) {
    output += "Breeze";
  }
  table.innerHTML += `<tr>Cell value: ${output}</tr>`;
}
<table>
  <tbody>
  </tbody>
</table>

Your code is perfectly fine, you just need to find a way to display it other than console.log so that its unintuitive clumping doesn't mess things up.

You can also turn off the grouping by unchecking "Group Similar":

enter image description here

Snow
  • 3,820
  • 3
  • 13
  • 39
  • 1
    "*This is an artifact of the browser console,*" it's also configurable - you can turn off the grouping behaviour. – VLAZ Jan 01 '20 at 21:20
  • Thank you for your input, Snow. You're right, I was referring to the artifact of grouping in the browser console. Why does short-circuiting bypass it? Is there a deeper logic, or is it pretty much "that's the way it works." Also, I tried using the template literal, like you suggested, and I still got the same result. – Custer Jan 01 '20 at 21:29
  • @Custer The `|| i` ensures that if the empty string would have been logged, the current index is logged instead, and the current index will never be duplicated, so there's no grouping. – Snow Jan 01 '20 at 21:32
  • @Custer there is nothing to do with short-circuiting. You simply print *different* lines: `0`, `1`, `2`, `Cool`, `4`, `Breeze`, etc. Since no two are the same, they aren't grouped. – VLAZ Jan 01 '20 at 21:33
  • If you had done `|| 'something'` instead, you'd see grouping on the `'something'`s because they'd occasionally be duplicates of what was just logged. – Snow Jan 01 '20 at 21:34