for (var i = 1; i <=4; i++) {
...
}
makes a loop that iterates four times. The value of i
is 1
in the first iteration, then 2
, then 3
, then 4
.
(function(j) {
...
})(i)
creates an anonymous function with one parameter, j
, and immediately invokes it by passing the value i
. This is called IIFE, and you can read more about it at What is the (function() { } )() construct in JavaScript?. As a result, j
is the value of i
, but it will not change as i
changes.
setTimeout(function() {
...
},j*1000);
sets a timeout for a certain number of milliseconds, and execute the function when the timeout expires. Note that setTimeout
exits immediately, it only schedules the function to be executed later. In JavaScript world, this is called asynchronous execution.
console.log(j);
prints 1
, 2
, 3
or 4
on the console. Remember that due to setTimeout
, this will happen 1
, 2
, 3
or 4
seconds later.
As a result, for
executes almost instantaneously, as the only job it does is to schedule four functions for the future. The value of this execution is undefined
, which is what will be printed to the console if you execute the snippet there. 1000ms after the snippet exits, the first scheduled function is triggered, and prints the value of its local variable j
(which is 1
). 2000ms after the loop (1 second after 1
is printed), the next scheduled function is executed, printing 2
. This happens two more times.