JavaScript for-loops are… complicated – HTTP203




In this episode, Jake and Surma dissect how for-loops actually work and how they’ve evolved. Turns out, it got complicated.

Subscribe to the channel! → http://bit.ly/ChromeDevs1

Watch more HTTP203 → http://bit.ly/2sPq2LB

Listen to the HTTP203 podcast for more content! → http://bit.ly/2Kryv2y
Itunes → https://apple.co/2IQagG6

Original source


26 responses to “JavaScript for-loops are… complicated – HTTP203”

  1. The var vs. let setTimeout examples can be really confusing.

    If the presenters showed the ES5 version of the code, it would make a lot more sense especially to the beginners.

    I used webpack to transpile the ES6 version source code to ES5.

    ES6:

    for ( let i = 0; i < 2; i += 1) {
    setTimeout(() => {
    console.log(i);
    }, 0);
    }

    Becomes ES5:

    var _loop = function _loop(j) {
    setTimeout(function () {
    console.log(j);
    }, 0);
    };

    for (var i = 0; i < 2; i += 1) { _loop(i); }

    In ES5 code, we are invoking the _loop() function during each of the for-loop iteration.

    Because the _loop() function is invoked with the value of i, therefore the value of i is copied to the new lexical scope which is created by the _loop() function.

    Eventually the function setTimeout() is invoked inside the lexical scope of the _loop() function where the variable j holds the copied value of i.

  2. In the first setTimeout with var example, the loop just added 2 separate console.log(i) to the message (event) queue, right? So when the execution stack was completed, the two separate console.log(i) were put onto the stack from the message (event) queue, which is why we had two consecutive console.logs of 2. When those two separate console.log(i) were put onto the execution stack, the global value of i === 2, since var is only 'function-scoped' and not 'lexically-scoped,' correct? Just want to verify that I was visualizing that correctly.

  3. Discussion at 6:55. Not necessarily the case that the incrementer runs at the start. Because you are using a postfix incrementer, the value could be captured before it increments at the end. Try running ++i instead to confirm.

  4. @GoogleChromeDevelopers, @Google Chrome Developers, '@Google Chrome Developers', @'Google Chrome Developers' (sorry – I don't know how @ works with spaces 🙂 )
    An 'old school' for loop can be converted into a while loop really easily, right?

    for(var iterator = initialiseFunc; testFunc; incrementFunc) { bodyFunc }

    behaves exactly as:

    var iterator = intialiseFunc();
    while(!testFunc()) {
    bodyFunc();
    incrementFunc();
    }

    Is it possible to "convert" a let for loop in the same way, to write out in standard JS what it does, as a while loop?
    And is it fundamentally special casing a 'for-let' loop as different from a 'for-var' loop? Or is it doing the same thing in both cases, but constructed so that it behaves differently.

  5. I started messing around after watching this video. I stumbled across another weird one. You can count backwards like this, but removing the timeout or using let creates an infinite loop.

    for (var i = 0; i < 5; i++) {
    setTimeout(() => console.log(–i) )
    }

Leave a Reply