In my code, I create buttons that use the variable i
in the loop declared via var
keyword. Now each button will log 10, i.e. the last value of the variable. The question is, where does the variable in the handler come from? Does he pick it up from the main scope? And in the case of let
, 9 scopes are created and the handler, when clicked, accesses i from each of them? I always thought that the handler remembers i
at each step of the loop
<html>
<head></head>
<body>
<h1>test</h1>
<script>
const start = () => {
const body = document.querySelector('body');
for (var i = 1; i < 10; i ) {
const button = document.createElement('button');
button.onclick = function() {
console.log(i);
}
console.log(i)
body.appendChild(button);
}
}
start();
</script>
</body>
</html>
CodePudding user response:
In Javascript variables are reference typed. So in the for loop scope there is only one i
. And it is increased at every iterative. Thats why every button prints the last value.
CodePudding user response:
The simple answer is due to scoping and closures. variable defined with var is function scoped and since onClick is a function, closures comes into play and at the end of loop, value to closure is 10.
variables defined with let is block scoped and hence a new scope is created for each loop with value 1.
CodePudding user response:
It is classical js problem caused by function scope of 'var'. It is solved since ES6 via 'let' and 'const' because they have block scope (every {} creates scope for variables created via 'let' and 'const'). If you change iterator declaration from 'var' to 'let' it will works as expected.