Hacker News new | past | comments | ask | show | jobs | submit login

My point is that for the i++ to make the loop advance (whether it is written inside the block or outside it in the header), behind the scenes, the value of the old i is copied to the new i at the beginning of each iteration.

I think to then understand why my two examples produce different results, you have to know that the i++ in the header happens to be executed after that copying has been made (an arbitrary choice?), while the i++ within the body will be (naturally) executed before the copying.

I suppose the way it works can be intuitive, but it can also be confusing if you think of the i++ as the last action of each iteration in both of my example cases.

Actually, there's a third way to write the example loop, but who can guess which result it gives?

    for (let i = 0; i++ < 10; ) {
        setTimeout(() => {
            console.log(i);
        }, 1000);
    }
... it will print 1...10! So even within the loop header, one part is run before the copying and another part after the copying. How is this intuitive and where is this documented apart from the language spec?

EDIT: My bad, of course the iteration condition has to be checked at the beginning of the iteration, so in this third example i == 1 during all of the first iteration).

Here's the relevant spec section 14.7.4.3 ForBodyEvaluation: https://tc39.es/ecma262/multipage/ecmascript-language-statem...

There we can finally see that on the first iteration, an environment is created (and iteration variables copied) before the test ("step 2"). After that, a new environment is created (and iteration variables copied) towards the end of each iteration, before the increment step ("step 3.e" and "step 3.f").




Another commenter links to a great video that explains the same thing about the spec and how confusing the environment creations can be: https://news.ycombinator.com/item?id=33160373




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: