This course is out of date and does not reflect Frontend Masters current standards. We now recommend you take the JavaScript: The Hard Parts course.

Check out a free preview of the full Advanced JS Fundamentals to jQuery & Pure DOM Scripting course:
The "Counter Example 2" Lesson is part of the full, Advanced JS Fundamentals to jQuery & Pure DOM Scripting course featured in this preview video. Here's what you'd learn in this lesson:

Justin repeats the previous counter example to further reinforce the concept of closures. He also answers a number of audience questions.

Get Unlimited Access Now

Transcript from the "Counter Example 2" Lesson

[00:00:00]
>> [MUSIC]

[00:00:04]
>> Justin Meyer: If you can get this this is like closures you actually I think understand more about JavaScript development or JavaScript. How it works as a language and 90% of the developers I'd say most people don't really get the mechanism for how this works. So again, this code. Jobs are just comes to it you know parses it, then builds it all into expressions, and is gonna run essentially the first expression although I'm in a run kind of two at ones.

[00:00:35] It's gonna say I'm gonna first build a function in memory, and like we said functions also know about parent call object. And then, I'm gonna do the counter equals part. So again, it doesn't know what's going on inside that function it just knows there's a function. Then it's going to run that function counter.

[00:00:56] And every time a function is run there's this magical box that variables can go into. And while this code is running, any variables that this code creates are put into that box. So here count is gonna go in and it's going to be 0. Now, this function returns another function.

[00:01:23] So just like before when we created and saw the counter function. We're gonna create another function in memory. And we're gonna return that function's memory address essentially to be set as the C1 variable. So C1 will point to that function in memory.
>> Justin Meyer: Then we're gonna call c1.

[00:01:49]
>> Justin Meyer: And whenever you call a function a call object is created and it's going to run then the code. So whenever a function is called call object is created then it runs the code for the function. So in this case, c1 is that inner function and we're gonna run ++count.

[00:02:10] It's gonna try to look for a count variable in that variable but we didn't create a count or sorry you can look for a count variable in that call object. But we didn't really create, we didn't do a var count inside here. So there's not one in here.

[00:02:28] So it's gonna keep looking up to try to find a count variable, find that count variable and increment it and then return. Because c1 is a function itself, it's gonna return the incremented value of count as one. And we're gonna call c1 again. Same function in memory, we're gonna call again.

[00:02:50] But every time you call a function a new call object is created, and that same process of trying to find count in memory is gonna be looked up.
>> Justin Meyer: Let's give a look at this two.
>> Student: Do you wanna use return then every time you put another function inside that function?

[00:03:09]
>> Justin Meyer: No, you couldn't. It's possible that you could do like window.foo equals a function and then you could I could call foo down here. But it would were it overwrite that foo property every time with a new function. So the cool thing about this is down here if I were to call I could still keep calling c1 and it would still be

[00:03:36]
>> Justin Meyer: It would still be counting c1s variable and not c2s kind of closed variable.
>> Justin Meyer: In some ways, you might like have used jay creek code. We have a lot of nested functions, you're adding event handlers and doing. Ajax calls and things like that. We have a lot of nested functions.

[00:04:03] That's the exact same thing that's going on here. We have function defined inside of another function. It can reference the variables in the parent function. That's how close this count can access the count in its outer function. And it can also reference the other variable c1 and c2 if it really wanted to, even though itself is being created as c1 and c2.

[00:04:31] That's just because closures walk, it just keeps walking up these chains until it finds a variable.
>> Student 2: Maybe, just, there's a question about what is the parentheses after it mean?
>> Justin Meyer: When we're just putting a call object, like, drawing out like that? It's our way of representing that this is a call object, that was created when you called the counter function.

[00:04:58]
>> Student 2: No way, I think like if you have var c1, on the screen it's just c1 and then put your c1 parenthesis after. Open, close.
>> Justin Meyer: So if I did-
>> Alexis Abril: [CROSSTALK] I did c1, semicolon and then c1 so c1 is just a reference to the function in memory.

[00:05:17] Just to point that function c1 with the open-close parentheses is doing two things. It's finding that function in memory, following the pointer to its function memory, and then invoking, or calling that function in memory. If that makes sense. And in the process, creating our call object here. What this is, a nice way to do this is, a really nice example too, of how we In the city links, private variables with JavaScript.

[00:05:43] With this kind of concept, this knowledge, count is not always accessible. I saw in the chat there was some, why isn't count accessible on the window, on the global scope. This is how we can prevent or keep a nice closed, that's where we'll use the word. Set of variables that we wanna use in our methods.

[00:06:05]
>> Alexis Abril: If that answers your question.
>> Justin Meyer: So one fun kind of technical aside for the computer sciencey nerdy Folks in here like me, I mean step back. So when a call object is really, so most are, every language has the idea of a stack, you might heard of a call stack.

[00:06:30] So when a function is called, any variables created inside that function are kinda added to the stack and when the function exits that part of the stack is popped off and discarded. So you enter a function variables, get stored on this thing called a stack. And then, when the function exits they're popped off.

[00:06:49] That's why if you've ever had a stack overflow and not the question site. The actual stack overflow error. That's because you keep calling so many functions that the stack it's so big, that there's just you run out of memory. A call object is really a part of the call stack so each individual part of a call stack that represents a single function.

[00:07:18] That's called an activation frame. And a call object is really an activation frame. So one function one invocation of functions all of it's arguments and variables stored in something but it can be made permanent. A call object is some is a call object or sorry a call object is a activation frame that can exist past when the function has exited.

[00:07:46] So that's why I'll start over here. So when I call this counter function, in some way, what what JavaScript's really doing internally is it's creating a new activation frame for the invocation of this function that stores all variables on it. And because it's returning a function that has c1 pointing to it and this function then points to the activation frame.

[00:08:12] Really, there the call object. It knows I'm not gonna garbage collect that then, because I'm not the one when the function exits. I'm not gonna pop that activation frame. I'm not gonna discard it. I'm gonna save it, because something might still want to talk to a variable inside this activation frame and that's this count here.

[00:08:32] That's the very technical deep reason like can a computer science the reason. Closures are really just someone was like, hey, we've got this stack, let's make a, with activation frames what happen if someone still wanted to access the items in the activation frame later? And how would we make that permanent and the mechanism at which JavaScript uses to make activation frames permanent is a function that's created inside of another function.

[00:09:02] Your function, then if functions know about their parent call object, it will make that call object permanent, as long as and keep it there, as long as, somehow, something is essentially referencing that function.
>> Student 2: Question, is the activation frame still on the stack?
>> Justin Meyer: It will be on the stack while this function is running and at the end when the function exits.

[00:09:29] It will be popped off and kept somewhere else. I think that actually thread that I posted. That were as working through this with the VA core member he I forgot what he said, at what point it's moved off. It's definitely moved off the stack. I don't remember exactly what's done with it.

[00:09:53] Cool. Sorry to get all super hyper technical. But I enjoy it. [LAUGH] Hopefully you guys do to. It's not just just write a comment tell me not to talk about that stuff. I won't be offended. So to finish this, c1 is created. Is return from here it call c1 it's going to run itself, but try to find this count variable incremented to one, then we're going to call c1 again.

[00:10:25] Every time a function is called, a new call object is created just like an activation frame is put on the stack. And it's gonna try to look for count, but because it can't find count, it's gonna walk up these little magic references, to find that version account in incremented to two.

[00:10:45] Now, here comes the crazy part. We're gonna call counter again. So whenever a function is created, or called in new call object is created. And that functions code is gonna be run and any variables created. While that function is or is running are gonna go in that call object so this is gonna get a different separate count variable and then, within this function another function is gonna be returned or created and returned as c2.

[00:11:23] So then we call c2,
>> Justin Meyer: New call object is gonna be created and it's gonna look up a value of count again but this time it's cool cup a different value of count and increment it to one cool. Any questions before I move on?
>> Student 3: Could you pass parameters into the second function?

[00:11:49]
>> Justin Meyer: It is, yeah. These parameters would show up here and then they would also be put in this clause. So if I pass like increment by or something like that. So if I didn't want to increment by one I could pass an optional increment by. So I might have increment by as an argument here and then I might do count plus equals, well I have to figure out how to write that so I'd like return the.

[00:12:15] Count equals count plus increment by I could write it that way. Now, when this call object is created, so when c2 is created it would actually get the increment by saved in here. So when increment by was looked up, it would find increment here but I would find count still up here.