Does this example use closures? I know it has functions within functions, but is there a case where the outer variables being preserved is being used?

Am I using them without knowing it?

Thanks

Update

Would this make a closure if I placed this beneath the $(document).ready(init); statement?

return {
scrollDown: scrollDown
};

Could it then be, if I wanted to make the text scroll down from anywhere else in JavaScript, I could do

pageScroll.scrollDown();

Another Update

Wow, looks like that worked! Here is the code on JSbin. Note the page scroller doesn't exactly work in this example (it doesn't seem to go to the bottom of the text), but that's OK :) Bonus points for anyone that can tell me why it's not scrolling to the bottom.

10 Answers
10

Any time you define a function, that function will "enclose" the scope chain it was defined in. When that function is executed that scope chain is available in its body. When a function is defined inside another function, the scope chain includes:

The parent function's locally defined variables

The parent function's arguments

The parent function's parent function's local vars and arguments, etc..

Global variables

The real value of closures is to return an inner function that has captured an enclosed variable that isn't going to change, like so:

I don't think you're using any closures, because you're not returning the inner functions from your outer function, so those variables will always be in scope when they're called. In other words, init(), scrollDown() and scrollUp(), have to be called from within pageScroll(). If pageScroll() returned any of its three inner functions, and then you called them outside of pageScroll(), the use of the $page, $next, $prev, etc. variables would be closures. I think.

The short story is; function declarations, or function expressions placed inside a function(declaration or expression) will have the parent functions scope added to its scope chain. Therefor it has access to all the variables contained in every function up the scope chain (ending with the global scope). But so far we are not talking about a closure.

The concept of a 'closure' appears when you create a reference to such a contained function outside the scope chain, either by returning a reference to the function, or by adding a reference to it as a property on an object higher up in the scope chain. [so that you by calling the function (by that reference) can modify variables hidden inside a non-accessible scope.]

This reference will also cause all variables contained in said scopechain to have at least one reference (from each scope) meaning that none of the variables present in the scope chain can be garbage collected. This is a so called memory leak (unless you are actually planning to use the variables that is!).

I'm no expert on Javascript, but from what I read here, yes, you have closures.

Note that all of the inner functions share the variable $page, for example. init assigns to it, and later the scrolling functions update it. So in principle the inner functions are closures of the outer function. The outer function passes init to document.ready, so in some Javascript-ish way, it returns a closure.

That said, I also have to say that this code is a very bad example of functional programming, since that pure functions are not supposed to have side-effects (like assigning to a shared variable). Nevertheless, it has closures.

Closures have access to its parent variables in this case our function 't1' accesses privately declared var x; also as you stated 'inner function has access to its parent function's variables, even after that parent function has returned.' when you click 'Test me 2' you will get an alert with x=10 even those that the function test() have already returned, does this make sense.

Yes, there are a number of closures in the sample code. The confusion may come from applying too strict a requirement on closures from your definition. While a closure does have access to its bound free variables for the lifetime of the closure, it is not necessary for the closure to extend the lifetime of those variables beyond their normal environment for the function to be considered a closure.

For example, let us say we have a function findAllPeople that finds in a list all of the people that have a first name that is supplied as a parameter to the function. We could create an inner function that takes a person and tests their name against the supplied name. That inner function would have two free variables--namely, the person and the name to test against. The name to test against is bound to the parameter supplied to findAllPeople. Hence, the inner function is closed over that free variable. The fact that the inner function is created, used, and discarded all while executing findAllPeople and is not used anywhere outside of findAllPeople does not have any bearing on the fact that the inner function is a closure.