Now that we know what a closure is, let's use it to solve the problem in the first video. As you'll see, we can not only reduce our dependency on global variables, but we can also make our code much more compact as well.
Now that we've seen how to create a closure. 0:00 Let's apply that to our functions countBirds and countDogs. 0:02 Firstly in the countBirds function, we want to make the count variable private. 0:08 In other words, countDogs cannot access this variable. 0:16 However, if we'd leave it like this, when we call countBirds, 0:22 the count will reset to 0 every time it runs, and it will never get past 1. 0:27 What we need to do is define an inner function inside of countBirds. 0:33 Because the inner function is defined inside this function, 0:46 it has access to the private scope of this outer function, 0:51 including the count variable. 0:56 Because the count variable is declared outside the inner function, 1:02 the count won't reset every time the counter runs. 1:07 Now we can return the counter function. 1:13 Even though the countBirds has exited, the inner function, 1:18 It returns, saves and uses this private scope. 1:25 This return function forms our closure. 1:33 I just want to make one small adjustment, 1:36 often you'll see the function returned directly. 1:39 So we can get rid of the name function of counter like this. 1:47 Now because countBirds doesn't count birds anymore, 1:55 it returns a bird counting function. 1:59 Let's rename it to 2:03 makeBirdCounter to keep our variable names more meaningful. 2:08 Let's preview this now. 2:13 Let's create a variable called birdCounter, 2:21 and call our new closure producing function, makeBirdCounter. 2:26 birdCounter now holds the counting function. 2:36 Let's run it now. 2:41 And we see it counts in upwards. 2:47 And you'll see when we countDogs, it holds a separate global count. 2:54 Even though this code works now, 3:01 we know that using global variables is still a bad idea. 3:04 Let's rewrite our dog counter the way we did the bird counter. 3:08 We see we can completely eliminate the global variable, great. 3:23 We're able to separate out two counters using closures. 3:34 And notice how they both are using the same variable, count. 4:01 Let's look at what happens when we create another birdCounter, birdCounter2. 4:09 What do you think will happen when we call it? 4:22 It has its own private scope as well, separate to birdCounter. 4:30 Every time our counter maker function runs a new scope is created, 4:41 and all those count variables are private values, because every scope is separate. 4:47 We don't actually need two functions for our dog and bird counters. 4:55 You can see that both are identical, except one uses 5:06 the string birds and thee other uses the string dogs. 5:11 If we could give the string to the closure instead of the counter function 5:18 the inner function would be able to access that as well. 5:24 So let's delete MakeDogCounter, and 5:27 rename makeBirdCounter just to be makeCounter. 5:32 Let's use a parameter to introduce another variable into the private scope, noun. 5:40 Now we can count whatever we want. 5:52 Let's see how to make a count for birds and 5:57 dogs with our new improved makeCounter function. 6:00 birdCounter is equal to makeCounter 6:03 birds, and then dogCounter, 6:08 makeCounter dogs. 6:17 When we call makeCounter we can put it in a string, and then 6:20 the function we get back is configured to the animal or thing we specify. 6:26 Let's make sure it works. 6:32 It does. 6:44 We could count fish as well. 6:46 And that's the first look at closures, in the next video, 7:03 I'll show you where they are used in the real world. 7:07
You need to sign up for Treehouse in order to download course files.Sign up