Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scope with a self-invoking function in Javascript

Take below code iterates over 6 input buttons and attaches an onclick event to every button that alerts the index number of the respective iteration:

for (var i = 1; i < 6; ++i) {
    var but = document.getElementById('b_' + i);
    (function (el) {
        var num = i;
        but.onclick = function () {
            alert(num);
        };
    })(but);
}

As you can see, in each iteration there is a self-invoking function that creates a scope to store the iteration index in that scope.

I have always used this type of pattern to attach an event that is dependant on a variable that is changed during iterations.


Can anyone explain to me exactly why the above works, and how the num variable is captured in the scope?

Also, is the self-invoking function used above called a closure ?

like image 587
Andreas Grech Avatar asked Dec 29 '22 11:12

Andreas Grech


2 Answers

Yes this is a closure.

Everytime a function is executed a new object is created to hold (as its properties) the variables that are declared with var and every function declared inside it. This object is called the execution context (or sometimes the scope object).

Everytime a function is declared (or defined in an expression) the new function has attached to it the execution context object that is current. This creates what is known as a scope chain.

When executing code needs to resolve an identifier to a value it first looks for it in the properties of the current execution context. If the identifier is not found it uses the exection context object attached to the function that is being executed. It keeps going up the scope chain until it reaches the global level.

In your example each time "self-invoking function" gets executed a new execution context object is create holding the properies el and num. Since the function assigned to onclick is created inside this execution context you will get a new instance of this function each time. These instances will each have the corresponding execution context object attached. Hence the first will have the execution context when num has been assigned 1, the second will have the execution context where num has been assigned 2 and so on.

When each of the onclick functions run the code will initially look for the identifier num in the current execution context. However this inner function doesn't var a num so its not found. So Javascript looks to the execution context attached to the function when it was created. Here it will find num, the num will contain the value assigned to it during that iteration as described above.

like image 71
AnthonyWJones Avatar answered Jan 12 '23 18:01

AnthonyWJones


Hey guys. Yep it is a closure. If you want to know what exactly occurs when function is creating then study following article. http://www.jibbering.com/faq/faq_notes/closures.html

like image 40
Danil Avatar answered Jan 12 '23 19:01

Danil