Yes, indeed section 13.7.4.8 of the EcmaScript 2015 specification, point 4.b describes that the body of the for
loop (the statement, as identified in 13.7.4.7) is evaluated, which in your example case means that the function object f
is created.
This happens in each iteration (step 4).
You can spy on the double creation as follows:
let set = new Set;
for(let x = 0; x < 2; x++) {
function f() {}
set.add(f);
}
console.log(set.size); // 2 in Chrome, Firefox and Edge
I get output 2 in Chrome, FireFox and Edge. Some report 1 as output. This may well be a possible optimisation by the JavaScript engine.
In this context, mdn notes:
Functions can be conditionally declared, that is, a function statement can be nested within an if
statement, however the results are inconsistent across implementations and therefore this pattern should not be used in production code. For conditional function creation, use function expressions instead.
This remark applies to loop constructs as well, since they also execute conditionally. So a more reliable result would be achieved with function expressions:
let set = new Set;
for(let x = 0; x < 2; x++) {
var f = function f() {};
set.add(f);
}
console.log(set.size); // 2 in Chrome, Firefox and Edge
Note that in both snippets, f
is not scoped within the for
body, but in the surrounding scope. So f
is accessible after the loop has finished.