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.
Transcript from the "Types as Arguments" Lesson
[00:00:00]
>> [MUSIC]
[00:00:04]
>> Justin Meyer: Quick question for the audience if anybody is brave enough to answer. What is the value gonna be when all of this code is run of a, b and c? And try not to cheat and just write it out. And just so you know, the prefix plus plus operator that returns the incremented value.
[00:00:20] So, if x was going to be let's say 10, it would increment it to 11 and return, the result of the parentheses would essentially be 11. Any ideas on what a, b, and c are going to be?
>> Student: They're not gonna change.
>> Justin Meyer: That's true of one of them.
[00:00:45] [LAUGH]
>> Justin Meyer: Any other?
>> Justin Meyer: Sorry, well, c is not really changed, but yeah, c will change, I guess, from undefined to have a value.
>> Student: Val 1, 2, 3?
>> Justin Meyer: Be 1, 3 and then 5. So, let's see how that works. So b.val will be 3. So again, when everything is run, when all code is run, there's always this kind of global call object, this global container for all variables.
[00:01:26] And we're gonna treat this code just like how kind of JavaScript processes it, think like a computer. So, the JavaScript processor is going to come see this first kind of statement here. And it's going to do what's on the right hand side, the expression on the right hand side of the equal sign.
[00:01:46] And it's going to create a function in memory first. We'll be using this a little bit later, but I want to give a sneak peek to it. Whenever a function is created in memory, it has a prototype property that points to an object in memory. We'll be using that later, but just saying, whenever of you see a function created in memory, we create a little function on our kind of two dimensional representation of memory.
[00:02:11] Whenever it's created in code, we create one in memory with a prototype property and a circle for its object that the prototype property points to. And then we're gonna do the what's on the left hand side of the equal operator. We're gonna create a sum variable in our call object, and then we're going to set that sum to point to the function in memory.
[00:02:33] That's what JavaScript does. And JavaScript doesn't know what's going on inside the func, you can think of it, it has no idea what's going inside the function. It has no idea about x or y being incremented, any of that, it's just kind of blind to at this point.
[00:02:51] The next thing it's gonna do is run these two things. It's gonna create an a variable, point it to 1. And it's gonna create an object in memory with a val property and it's gonna point b to that.
>> Justin Meyer: The next thing is it's going to call the sum function.
[00:03:14] And I apologize if the font is a little small up there, couldn't really make it much bigger. The important thing though is, whenever a function is called, whenever you see that call operator, some function followed by parentheses. There's a bunch of things that happen. The first thing it does is it creates a new call object that's going to contain the arguments and variables.
[00:03:42] And also, the reference to this that when that function is invoked, it's going to contain its variables, arguments, and things like that. So, that's another call object for the invocation of sum with the variables a and b. So, creates this little place in memory to contain variables and things like that, and it starts putting things in there.
[00:04:03] So, it's called with a and b, but it's gonna translate that to values that it contains of x and y. So, because a is a primitive, it's passed by a value. So x is going to point to essentially a copy of a. You can think of it is creating new one in memory, it really doesn't, but think of it that way.
[00:04:33]
>> Justin Meyer: And then y is going to be passed by reference, so y is going to point exactly to what b points to. So, this is what gets set up. And then the function, its code is going to be run. So, it's going to say hey, look, give me the value of x in memory, I'm gonna increment that, and give me y.val, look up that and increment that.
[00:04:59] So, it's going to increment x to 2, and y.val to 3, and then return the sum of those two things as c is 5. Any questions there? Make sense? So, two things to remember. Whenever a function is defined, a kind of function is created in memory, it's created in memory with a prototype property.
[00:05:33] And the second thing, whenever a function is called, a new call object is created, and the arguments passed to the function are kinda translated to what the names of the arguments the function defines out. So a and b gets translated to x and y.
>> Justin Meyer: [COUGH] So, another summary.
[00:05:55] [LAUGH] Primitives passed by value, you get a copy objects passed by reference. So, another question, what's gonna happen? What's gonna be alerted when this code runs?
>> Justin Meyer: And then bonus points for explaining why.
>> Student: Any? I can tell you my guess. I would assume looking at this code, I would probably think it's gonna be 012.
[00:06:32]
>> Justin Meyer: You're an idiot. [LAUGH] No, it won't be that. It will be, any other guesses? If it's not gonna be 012, what else could it be, and maybe why? And brave souls, we should start taking names, and then give rewards, like cookies or something tomorrow. Yes and well, maybe yes, maybe bring some something nice for the those who are.
[00:06:59] Do you have a stab in the dark here?
>> Student: Well.
>> Student: I ran across something like this two or three years ago, where it ended up being something like 222, but.
>> Justin Meyer: That's, you're right on, you're so close. Yeah. [LAUGH]
>> Student: But I forget why that was [LAUGH].
[00:07:17]
>> Justin Meyer: It's good, it's going to be 333. Anybody know why? Yeah.
>> Student: Cuz i is the reference, and it's the last reference to the order once the loop finishes. And so, as each line then executes afterwards it's using the same reference.
>> Justin Meyer: Yeah so, once the i is going to be left at 3, because the conditional will fail for the for loop.
[00:07:48] So, i will be 0, then 1, then 2, then 3, this will fail, and it'll exit the for loop. But it's because a lot of people think well, but shouldn't the i be 0, 1, then 2? It's because JavaScript doesn't have block level scope. So, this i is kind of global, it's in the global call object.
[00:08:07] So, it's just gonna output the value of i as it stands every single time. So, we'll come back to this and show how to fix it and explain the problem a little bit better, but. Yep?
>> Student: A couple of question come up a little bit back here. He was asking if objects are all call by reference.
[00:08:25] And then also kind of related, call object is a synonym for scope.
>> Justin Meyer: Call objects are called by call. So, call objects, so you can't really pass a call object to a function, so you can't really, that pass by reference, pass by value thing. I don't know how, maybe the phrasing of the question I'm missing.
[00:08:57] What was the?
>> Student: He's not talking about call, that was the gentleman talking about objects are called by reference?
>> Justin Meyer: Yeah.
>> Student: [CROSSTALK]
>> Justin Meyer: So objects aren't called by reference, they are passed by reference. And then is call object a synonym for scope? Call object is a piece of a scope.
[00:09:25] You could think of it as if the whole scope consists of, if inside this function, I can reference a, b and c. But also, inside this function, I can reference x and y. If that's what, a lot times people refer to as the scope. It's all of the call objects combined is the scope, right?
[00:09:46] It's kind of related.
>> Student: So, you kinda asked a followup question there why x isn't called by reference in this example.
>> Justin Meyer: So, x is not called, it's passed, right? There's a difference between called, so, when the sum function is called, it passes a and b. So, a is passed by a value, because it's a primitive type, it's just a 1.
[00:10:19] b is an object, so it's passed by reference. Sorry, did I say, x was passed, x is passed by value, y is passed by reference. b is passed by reference to sum, so y, when it kinda translates the arguments, y is gonna point to b, but x is gonna get a new copy of a.
[00:10:44] So, that makes sense, hopefully. So, why isn't x called by reference? Maybe it was also referring to when I said x isn't, when I said it's not actually a new copy is made. The reason is it can be, and it could not be, you don't know, because again, real primitives in JavaScript, you can never mutate a number, or in a string, or anything like that in place.
[00:11:14] You always get a new copy, whenever you increment x, that actual value here. Really, we're showing it as being, I kind of try to show that it's not so much the number has changed in place, instead, a new number has been instead of x, is really pointing to a new number.
[00:11:35] That's what's really happening when you increment x, because you can't actually change primitives. So, that's why it's not necessarily, it could, the engine could optimize and say okay, well, I see that this function is constantly changing the number. So, I'm just gonna copy the number that was passed and pass a fresh copy that it can increment in place, or it could decide they just want the number, and they do almost nothing with it.
[00:12:03] I'm just going to pass the same number as if it was passed by reference. So, I don't know if that's the question that was being asked, but there's a whole lot of complexity that can happen, because primitives are not mutable, that engines can decide whether to do reference or value, but think of it as pass by value.