function first(){
var items = document.getElementsByTagName("li");
for(var x = 0; x < items.length; x++){
items[x].onclick = function() {
console.log(x);
}
}
}
function second(){
var items = document.getElementsByTagName("li");
for(var x = 0; x < items.length; x++){
(function(val) {
items[val].onclick = function() {
console.log(val);
}
})(x);
}
}
function third(){
var items = document.getElementsByTagName("li");
for(let x = 0; x < items.length; x++){
items[x].onclick = function() {
console.log(x);
}
}
}
There are 4 elements in the list. Outputs of the 3 functions:
first: 4 4 4 4
second: 0 1 2 3
third: 0 1 2 3
I am not able to understand the output from the third function. In the second function, each call to the IIFE creates a new function object and hence, a new val variable. But in the third function, there is a single copy of the variable x, then how is the output: 0 1 2 3
Please correct me if I am wrong.
In the documentation for let from MDN they have an example covering this exact case in the Cleaner Code in inner functions section:
for (let i = 1; i <= 5; i++) {
let item = document.createElement('li');
item.appendChild(document.createTextNode('Item ' + i));
item.onclick = function(ev) {
console.log('Item ' + i + ' is clicked.');
};
list.appendChild(item);
}
The example above works as intended because the five instances of the (anonymous) inner function refer to five different instances of the variable i. Note that it does not work as intended if you replace let with var, since all of the inner functions would then return the same final value of i: 6. Also, we can keep the scope around the loop cleaner by moving the code that creates the new elements into the scope of each loop.
The same thing applies to your case, because you use let
each anonymous function refers to a different instance of x
. There is a different instance on each iteration of the loop. This happens because let
has a block-level scope instead of the global function scope that var
has.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With