Page 5: Another Closure Example
Here is a variant of the example from the last page. I am making two counters that count different things. First, read the code and see if you can understand what it does. Then try it and see if your understanding is correct. Some explanations follow. The files are F-05-01.html and F-05-01.js, but I’ll put the code here so we can refer to it
|
|
And here it is running…
Some things to observe…
- I define a function
makeCounters
that takes a list of buttons (line 2-28). It will change each one to a counter. - Within
makeCounters
, it defines a variabletotalCount
- this is one variable for the whole function. It will be shared by everything inside of the function. - Within
makeCounters
it defines a functionmakeCounter
- you saw this on the last page. But notice, this version has access to both its own variables, but also the variables of its outer block. - Within
makeCounter
we define a function that is not named, but is assigned to the button’s click handler. You saw this on the last page. The difference here: this function has access to all of its enclosing scopes. So it can access the variables both inmakeCounter
but also inmakeCounters
. - Line 20 uses a JavaScript template literal - it basically creates a string with both numbers in it. To learn about template literals check out Template Literals Documentation
- Remember, the function in lines 17-21 only gets run when a button is pressed, and only updates the one button that is pressed. This is why when you click a button, only that button updates - but the variables inside get updated for the next button press.
- Notice how each row is a separate invocation of
makeCounters
so it gets its owntotalCount
variable. Just like each button is a separate invocation ofmakeCounter
so it gets its owncounter
.
In my mind, this is a useful use of a closure. Yes, I could have written this by creating objects for each button (that store counters) and for each row (to store the “total count”). But that would have required defining two classes of objects, … I find the closure to be concise. But it is a style thing. You rarely need to use a closure - there is always some other way to do it. Closures are just often an elegant solution.
That said, the use of closures for the button
variable (line 20) is gratuitious. This inner function probably should have been written:
|
|
button
makes the assumption that button isn’t going to change. But I used a closure because this workbook is about practicing closures.
Closures
That probably really isn’t enough examples. Most students need to see many examples. But hopefully, this will help you get started. The key is to practice. Try using them!