Understanding Closures Through Telling Mad-Lib Like Sagas
How did one thought about closures end up in creating the Saga Creator seen below? (Or, if you’re on mobile- check out the CodePen here!) Well- it’s a long story, but I’m glad you asked-
When I first saw a closure used, it felt like it flew in the face of everything my newbie-programmer self knew (a common experience while learning).
Scope to me was a simple thing: long ago during the dawn of ES6, JavaScript programmers received let and const to address some of the issues experienced with var. Var could be redeclared, but neither let nor const could be. And of the two, const could never be redefined. Unlike var- variables declared by let and const could not be accessed before the code execution reached the line they were declared on (creating something called a temporal dead zone).
Take these concepts and mix it in with the idea that when something is locally scoped in a function, it cannot be accessed in the global scope- and you can see why initially, I struggled with the idea of a closure. At first glance- it seemed to defy to strict scoping rules I knew. How in the world could we possibly use an inner fuction to pass on the values of variables from an inner scope?
The answer, dear reader- is the closure. Per MDN, “A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives a function access to its outer scope. In JavaScript, closures are created every time a function is created, at function creation time.”
As a visual learner, I decided that the best way to tackle this was to create some sort of side project, and I was enamored with an idea presented in my class that involved generating a series of random sagas.
How hard could it be? I knew I’d need some sort of container for random variables within my function- and quickly settled on arrays that would exist within my newSaga function, since I knew the array elements would be easy to access with their indexes:
And of course, we would also need some sort of randomization function to pull from our lovely arrays of strings- a classic Math.random() implementation seemed like a great idea:
Then we need an inner function, one that both creates our mad-libs style sentence and returns it:
And just like that- our newSaga function was built! I took a moment to bask in all of its glory. Not only was I using closure to pass on the value of all the various elements within my arrays- I had also created a function within a function that was using closure to pull the value of another function, random(). And the more I thought about it, the more it made sense. Whenever this function was called- of course every value would be evaluated and resolved- this is one of the most basic concepts of programming and one of the first things I learned.
I think seeing how the call for this newSaga function works really tied it all together for me, I’ve added a console.log that illustrates the output:
We receive our data correctly calling newSaga()() (the second set of parentheses are needed to immediately execute the returned inner function). We’re using the closure and call to access values we would never be able to access globally. This is the power of closure!
Get Clairehap’s stories in your inbox
Join Medium for free to get updates from this writer.
Notice how here there are no arguments or parameters- if there were, we might hit on another fascinating concept: currying. To explain it briefly, currying breaks down one parent function with many arguments into a series of child functions- with each child handling one of those arguments. For more info on that- I highly recommend: “ Currying: Functional Programming Made Simple”, by Lince Matthew. Closures are often used to implement currying, so I highly recommend learning about one when you’re learning about the other.
Fascinating detours aside- I realized that since there’s a lot of visually inclined people like me in the world, they might benefit from having not just all this lovely code, but some sort of functionality they can see.
And so my project expanded into the world of CSS and HTML, seeking to implement something minor that showed in real time the importance and value of closures-
The first step was to get some HTML fleshed out:
And from here, the major changes to our JavaScript were pretty straightforward:
- We made sure that our “sagaOutput” id from the above HTML got the data from const saga sent to it safe and sound.
- We attach our closure to our “generateBtn” id and add the click functionality. Our function is passed as a callback to the event listener- meaning when we click our “generateBtn”, we’ll get the data from a brand new saga placed before us.
Looking at the final result- I was struck by a sense of how incredibly useful it was to have the encapsulation a closure provides — that is, my variables for saga need never fear any change since they are only accessible within the function. Even if I created a whole brand new set of variables for random, names, adjectives, titles, objects, adverbs, people, actions, and terrors… Even if they were all consts… Even if they were all in the global scope (the highest scope available). Not a thing would change-
Because closures don’t defy scope, they epitomize it.
In the last bit of my project stretch, I styled up the page with some CSS. I made it look nice for anyone looking to do something similar. Here’s the final result:
And so the saga of a Saga Creator made by a “Saga Creator” creator reached its end with a very visual representation of the power of closures.
As a last sign off- Feel free to check out or play with the code using the CodePen link at the top of the page, or use it to make your own saga- may it aid you in your own learning quest!







