Javascript Scope: code block vs a code block with a self executing function cacoon

117 views Asked by At

I'm trying to wrap my head around a scope issue. Take the two examples:

a)

var sels = ['.a', '.b', '.c'];
while ( (var sel = fieldsets.shift()) !== undefined ) { 
    (function(sel) {
        $(sel).click(function() {
            console.log(sel);
        });
    })(sel);
}

In this example, when one of the referenced elements is clicked, the output will be .a, .b, or .c.

b)

var sels = ['.a', '.b', '.c'];
while ( (var sel = fieldsets.shift()) !== undefined ) { 
    $(sel).click(function() {
        console.log(sel);
    });
}

In this example, a click will result with undefined.

I'm clearly misunderstanding how scope is applied in these two examples, because as I see it, when .click is called in either case, sel no longer exists at all.

What is the difference in the way scope is applied between these two cases?

1

There are 1 answers

1
Pointy On BEST ANSWER

The key is in this statement of yours:

... because as I see it, when .click is called in either case, sel no longer exists at all.

In a language like C, that would be true. Not JavaScript! When a function is instantiated (as is done in both of your examples to create the event handlers), it "captures" the enclosing context. When the function is executed, that context remains available, unlike in a stack-based language. (The topic of "closures" is what we're talking about, and you can find much more lucid explanations elsewhere than I could type in here in this brief answer.)

The key difference is that your first example introduces a new layer. In that example, each instantiated event handler effectively gets its own private "sel" variable, that being the parameter to the anonymous wrapper function. The outer "sel" is made inaccessible by that because the names match.

In the second example, because all the event handlers share access to the same unique variable "sel", they all see the same thing when they're called: the value of "sel" as it was at the end of the loop. That value would be undefined because that's when your loop stops.