Search code examples
javascripttypescriptloopsscopeactionscript

Redefining variables for multiple for loops, good or bad practice?


I primarily program in AS3 at work, where the lowest scope is the function and not the executing block. This means the following code works fine

for (var i:int = 0; i < 3; i++) {trace(i);}

but this code results in a warning because apparently i is being redefined.

for (var i:int = 0; i < 3; i++) {trace(i);}
for (var i:int = 0; i < 3; i++) {trace(i);}

That means that I generally have to do something like this to avoid warnings from the compiler (and reprimands from my superiors about "bad practice").

var i:int;
for (i = 0; i < 3; i++) {trace(i);}
for (i = 0; i < 3; i++) {trace(i);}

I've been experimenting in TypeScript lately and I find the let concept for defining executing block scopes very practical. I discussed this with a coworker and he insisted that using let within a loop would be bad practice since the variables get redefined every loop.

Is there a fundamental difference performance-wise between the following two methods in TypeScript?

for (let i:number = 0; i < 3; i++) {console.log(i)}
for (let i:number = 0; i < 3; i++) {console.log(i)}

and

let i:number
for (i = 0; i < 3; i++) {console.log(i)}
for (i = 0; i < 3; i++) {console.log(i)}

Solution

  • When you define a variable with let, the variable is local to the scope.

    So when you do this

    for (let i:number = 0; i < 3; i++) {console.log(i)}
    

    i is scoped into the loop for.

    Is not a bad practice to declare i into each loop.

    For exemple if you loop on two different array, you can create two loop to iterate it.

    If you use an specific iteraztor name for each you can have code like :

     const arrFoo: Array<number> = [0, 1, 2];
     const arrBar: Array<number> = [0, 1, 2];
     for (let iteratorFoo:number = 0; iteratorFoo < arrFoo.length; i++) {console.log(iteratorFoo);}
     for (let iteratorBar:number = 0; iteratorBar < arrBar.length; i++) {console.log(iteratorBar);}
    

    In this case it's a good practice to declare two differents iterator.


    Unless you use the same i in each loop.

    Like :

    let i:number
    for (i = 0; i < 3; i++) {console.log(i)} // show 0, 1, 2
    for (; i < 6; i++) {console.log(i)} // show 3, 4, 5
    

    And for the performance-wise, the difference is clearly not noticeable to a human.


    Edit based on comment :

    What about in a case where the loop iterates tens of thousands of times?

    for ([initialization]; [condition]; [final-expression])
    

    initialization An expression (including assignment expressions) or variable declaration evaluated once before the loop begins. Typically used to initialize a counter variable. This expression may optionally declare new variables with var or let keywords. [...]. Variables declared with let are local to the statement.

    Reference

    So the initialization is evaluated once, even if your loop iterates tens of thousands of times.