A closure is when you return a function inside a function in a way that the child function keeps reference to any variables defined in the parent function. Take the following example.
If you wanted to specify a different target and weapon each time you were caught battling monsters you could call:
target("zombie")("shotgun"); and pass in the arguments for both the target and the weapon. This works because the target function returns the action function, so when target finishes running it allows you to pass in the argument for attack.
To break this apart:
return "You attack a " + threat + " with a " + weapon + ".";
It is important to note that the inner function, attack, is not called inside the target function, simply defined. So when you put another set of parentheses after the target function, you are calling the attack function as well.
"You attack a zombie with a undefined."
But, what is we’re up against a hoard of zombies. We don’t want to have to pass in the zombie argument each time we want to attack. That’s a recipe for disaster.
Since attack is returned by target, we have the ability to make sub-functions that will always attack specific monsters. If we assign target to a variable while passing in zombie, it allows us to make an instance of the function that will exclusively attack zombies.
var targetZombie = target("zombie"); Now we can just pass the weapon to the targetZombie variable, and no matter what weapon we pass in a zombie will always be targeted, and our odds of surviving the zombie apocalypse will be significantly greater.
Now, to attack a zombie with a shotgun we only need to type
targetZombie("shotgun"); and we can easily and quickly substitute the shotgun for any other zombie-slaying implement we may have on hand.
targetZombie("chainsaw"); will return “You attack a zombie with a chainsaw.” and
targetZombie("banjo"); will return “You attack a zombie with a banjo.”
If the town suddenly received an influx of other supernatural creatures, we could easily adapt our parent function to target other monster types. We could use the parent function by passing in individual targets and weapons, or we could use closures to lock in the targets.
var targetWarewolf = target("warewolf");
var targetVampire = target("vampire");
With two more lines of code, setting target(“warewolf”); and target(“vampire”); to variables and closing over the “warewolf” and “vampire” arguments, we significantly increased our monster-slaying abilities. This is much more efficient than having to specify the monster type each time, or creating a new function for each monster type. It also allows us to easily change our weapon type based on what’s currently on hand. Now we could simply call
targetWarewolf("silver bullet"); and