-1

The code:

    /**
     * Converts all numbers in text from old unit to new unit
     *
     * @param {string} Text Text that will be converted
     * @param {string} UnitName Name of current unit
     * @param {string} NewUnitName Name of the new unit
     * @param {function} UnitConvertFunc Function that takes current unit float and returns new unit float
     * @return {string} Text with all old unit floats replaced by new unit floats
     */
function ReplaceUnit(Text,UnitName,NewUnitName,UnitConvertFunc) {
        let NewText = "";
        let lastUnitTextIndex = -UnitName.length;

        let unitTextIndex = Text.toLowerCase().indexOf(UnitName);
        let unitTextFragment = Text.slice(lastUnitTextIndex+UnitName.length, unitTextIndex)
        lastUnitTextIndex = unitTextIndex;

        console.log(unitTextFragment) //ok
        while (unitTextIndex!=-1) {
            console.log(unitTextFragment) //ERROR: variable is not initialized!!!
            let i = 0;

            LfragmentLoop:
            while (i < unitTextFragment.length)
            { 
                let firstDigitPos;
                let lastDigitPos;
                for (i; ;i++) { //Searches for first digit symbol
                    if (i == unitTextFragment.length) { 
                        console.log(`${DebugText}no Number found before \"${UnitName}\" text: ${unitTextFragment}`);
                        break LfragmentLoop;
                    }
                    if (isFloatNumber(unitTextFragment[i])) break;  
                }

                firstDigitPos = i;

                for (i+=1;i < unitTextFragment.length; i++) {
                    if (isFloatNumber(unitTextFragment[i])) lastDigitPos = i;
                    else break;
                }

                let UnitNumber = unitTextFragment.slice(firstDigitPos,lastDigitPos+1);

                unitTextFragment = unitTextFragment.slice(0,firstDigitPos) + UnitConvertFunc(UnitNumber) + unitTextFragment.slice(lastDigitPos+1);

                i++;


            }

            NewText+=unitTextFragment + NewUnitName;
            let unitTextIndex = Text.toLowerCase().indexOf(UnitName, NewText.length+UnitName.length);
            if (unitTextIndex==-1) break;
            let unitTextFragment = Text.slice(lastUnitTextIndex+UnitName.length, unitTextIndex)
            lastUnitTextIndex = unitTextIndex;
        }
    }

enter image description here enter image description here

I'm shocked, why does this happen?

It looks like my post is mostly code, but I don't know what more details can I add. Descriptions of my actions aimed at solving the problem are useless, because thanks to them I found a specific point where something is wrong, and I can't imagine what can be written incorrectly in one line of the while-loop opening. I tried to include '-1' in quotation marks, it didn't change anything

Титан
  • 41
  • 1
  • 9
  • 1
    What is the *exact error* that you're observing, and is it happening at runtime or is it a warning by your IDE? – David Aug 24 '21 at 17:31
  • Please do some work, reducing the code to the bare minimum necessary in order to still produce the error. It is quite likely that while doing this, you will also find the cause. – trincot Aug 24 '21 at 17:32
  • It happends during the run. The error is about unitTextFragment is undefined. If console.log is here it's "Uncaught ReferenceError: Cannot access 'unitTextFragment' before initialization". If not, it's in next while and says that can't get length of undefined – Титан Aug 24 '21 at 17:33
  • Noting the correct answer--most IDEs and linters will identify issues like this. Unrelated--the naming isn't typical JS convention and makes things a bit harder to think about, and my initial impression is that it's more complex than it needs to be. – Dave Newton Aug 24 '21 at 17:39

1 Answers1

3

You have this line in the outer loop, near the end of it:

let unitTextFragment = Text.slice(lastUnitTextIndex+UnitName.length, unitTextIndex)
        

This means you define a new variable, with block scope: its scope is the body of the while loop. Due to the hoisting rules, it will not be defined in the first iteration of that loop (look up: What is the temporal dead zone?).

Solution: remove let.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • `let` in a closed loop? Wow, I was expecting an error like "the variable has already been declared" if I make such a typo, so I didn't even think about it. I will now have to rethink about the declaration of variables and scope in JS, thank you! – Титан Aug 24 '21 at 17:45