1.1 - The source code examples here are on github
One of the simplest definitions of a closure that I have come across in my travels on-line can be summarized like this.
- A closure is a function within a function*
This is defiantly true, but just saying that alone does leave a great deal to the imagination. To really do closures justice I would need to elaborate a bit more than just that. One way would be to give another definitional that is a little more long winded. Maybe something alone the lines of:
A closure is a collection of two functions where there is an inner and outer function, the outer function closes over the inner function, and provides a function level scope that can be accessed from within the inner function, and in addition the inner function level scope can not be accessed from within the scope of the outer function.
1.3 - Using globals
This will work find for just this simple little example, but there is all ready some draw backs to talk about. First off the x and y values are global values that might conflict with other code on the page. Another draw back that will drive some developers nuts is that I am making use of global variables inside the body of the move point function.
1.4 - Using a Class
So then another option for this sort of thing would be to make a Point Class. This works by creating what is called a constructor function that will be used with the new keyword to create an instance of the Point class. I can then add a move function to the prototype of the class and then call that method off of the Point instance.
1.5 - Using pure functions
Another option is to get into the habit of writing pure functions. The basic idea of pure functions is to not mutate source values of function arguments, always return the same result for the same arguments, and to not use globals inside the body of the function.
1.6 - Basic closure example
So then here is a basic example of a closure where the outer function is one where I pass and x and y argument that I want.The returned result of the outer function is then in turn also a function. When I do so those arguments that I give when calling the outer function become local variables within the scope of that outer function. The inner function that is returned then has parameters of it’s own, that are used when calling the inner function that is returned. When passing arguments to the inner function that inner function has access to the values that are closed over into the scope of the outer function.
So now when I call this point function that is a closure, the returned function is then my move point function. I can then pass the delta values that I want to use to the returned inner function that will return a point object. This comes in handy now and then when a situation arises that calls for it, the nature of this is one that helps to sore a state, and keep things organized.
This might not be the expected output when doing this. The reason why is because the while loop will step the i value to then end and finish long before the first settimeout function call runs the function that is given to it as a callback. So then the value of i will remain at the index value of the last index in the array. One way to go about resolving something like this would be to use a closure.
By passing the value of i to the outer function the value of i is copied by value because it is a primitive. Things will get a little more complicated if we where taking about an object, but that might be a whole other can of worms when it comes to the subject of copying objects. Any way when each function is called one second later, the value of n is what will be used to get the element in the array, and the result is getting them in order rather than just the last element for each.
3 - Call once, and log once methods
4 - Random selection without replacement and closures
In my post on the math random method I worked out a simple example that has to do with random selection without replacement. This is just something that comes up when it comes to the topic of random numbers, as often the situation is random selection with replacement. Often replacement is just fine in many cases, however in other situations I might want to go threw everything, just do so in a random rather than ordered way.
There are a number of ways of going about doing this sort of thing without using closures of course, however doing so might often involve the use of one or more global variables, or at least one that holds some kind of state object. Still this is very much a post on closures so of course I am going to go over the first examples that I made for that post here that makes use of a closure.
4.1 - A create hat method that uses a closure
So the the result of running this script is random selection of elements in the copy of the source array. Once the copy is emoty the reset method is called and the copy is reset back to the state of the source array again.
5 - Conclusion
So closures are functions that return a function, or a collection of functions that can be used to work with an internal state. When doing so that inner function or API has access to the outer functions local variable scope. So then the use of closures is great for having private internal helper functions, objects, constants and so forth, while having a way to present this public API that can be used to work with the project as a whole.
The basic idea of a closure is not so hard to understand, but it can lead to things that might result in hard to debug code of they are used carelessly. One draw back is that a closure can result in this state that is separate from that of what might be passed using just arguments. In other words the use of a closure goes against the rules of the use of pure functions.