This lead me to the Google Closure compiler.
The closure compiler is both a compiler and minifier, it analyzes the source code and show warnings and errors, it can for example be set to show errors whenever it detects an undeclared variable.
I was a bit surprised by the amount of errors (undefined variables) it did find in my code. A few where false-positives, but the majority actual errors.
I don't want to have errors in my code so I set out to fix them.
Fixing one of the bugs however created an error! Can you spot the bug in the code below ?
The code above calculates the last index of a text row, by taking the start-index of the row below it and
subtracting the length of the line-break and indentation-characters.
The closure compiler said variable length was undefined.
I was a bit puzzled why this even worked. But I had a lot to do. So I made a note to investigate later, then made the naive fix by changing file.lineBreak-length to file.lineBreak.length (dot instead of minus sign).
The next day when working on another issue, and got an error because of the code I "fixed" above.
Investigating the bug
I began by writing a test, to confirm that the test actually detects the bug before fixing it. This is called regression testing, and effectively prevents the same bug from comming back at ya.
So I made sure the test failed, then "fixed" the error by reverting the "bug fix",
and lo and behold the test passed.
So what the heck is happening?
This means that the variable length the closure compiler said wasn't defined, actually is a variable, a global variable, defined somewhere ...
"foo"-1 (string minus one) also evaluates to NaN ...
Why doesn't file.lineBreak-length become NaN!?
"\n"-1 (string with new-line-character minus one) evaluates to -1 (minus one)!!
So the line-break characters "\n" minus length (which have value zero) ... becomes zero.
So the proper fix was to remove the line-break-character's length from the equation.
Global variables are bad
But what about that length variable? I don't want global variables in my code. Most of the time global variables exist because someone has forgot to put var in-front of the assignment. And it usually means there's a error in the code.
I searched for length in my code,
I went through hundreds of places where length was assigned, but all of them was local variables ...
Did I miss something ?
I searched for ways to detect global variable declaration's, maybe it can be done in chrome-dev-tools ? But found nothing.
Just as I had asked for suggestions on IRC it came to me:
Maybe length is a global variable built into browsers!?
I opened a new browser tab and tried www.google.com.
Opened the dev tools (F12 or Control + Shift + I),
went to the console and typed in "length" in the REPL and it evaluated to 2.
I though maybe Google had a bunch of global variables, so I opened about/blank (a blank web page), and length still existed as a global variable!
It turns out the global variable length is the number of iframes on the page!
And my page/app has 0 iframes, so "\n"-length becomes 0.
Written by Johan Zetterberg Mars 22, 2019.