Lesson Description
The "Stack Memory vs. Heap Memory" Lesson is part of the full, JavaScript: The Hard Parts, v3 course featured in this preview video. Here's what you'd learn in this lesson:
Will introduces stack and heap memory. JavaScript stores primitive values directly in memory (stack) but stores objects by reference in a flexible memory area called the heap. When comparing objects, JavaScript compares their references (memory addresses), not their contents, which means two objects with identical properties are not equal unless they reference the same memory location.
Transcript from the "Stack Memory vs. Heap Memory" Lesson
[00:00:00]
>> Will Sentance: Without further ado, we have our clean whiteboard, and we are going to build out our very sophisticated authentication feature. On this side of our whiteboard is our web browser, where we have our user submitting their name, and we have our users submitting their ID number. Oh my goodness. And then we have a submit button down here. There it is. Very sophisticated, and when these inputs are entered, we're going to have our user submitted properties updated with that data.
[00:00:47]
And you can see here, I'm immediately going to have coerced my 105 string that came off the DOM. My DOM string came off the web page into the number 105 when we filled that out. But let's get to that in a second. For now, Chris, can you talk me through what I have stored in my global memory? Uh, go ahead, Chris. From the top, right? From the top, he makes space for something called the user stored.
[00:01:23]
Yeah, in it, we put a hash. Absolutely, we have an object with a property of name that has a value of the string Will. Oh no, it's me, and I should have had. OK, something else, ID of what? What, the number 105. Number 105. Beautiful. Then we have our next object by the name of what, Chris? User submitted. User submitted, this is going to be another object. Yeah. Yeah, so, you know, for now, and I would have done undefined here people, but I didn't have room on my, so these are, uh, but it's, you know, a value as yet not known, uh, ID the same.
[00:02:11]
Then we save what function, Chris? Uh, on submit. And people, I feel almost bad, we've been so rigorous so far with our thread of execution, and yet now we're being much more relaxed because this on submit call is going to be triggered when the user clicks submit. It is absolutely not going to be called at this moment, but that's not really our interest here. We're interested in working with our data types, particularly ones that came from the web browser, uh, and in this case, when the user enters Will and 105, we're going to have Will and oh dear, 105, the string pass through, but don't panic, we're going to save them onto our object, immediately coerce, run to number, maybe by unary, maybe by the call to the number function on our 105 string and get the ID 105, the number.
[00:03:09]
OK, and we are then going to have the user press submit and call our on submit function where we're going to create, just for everyone's joy, a brand new what? Execution, execution context. There it is, and into it we go, and we are going to be doing some conditional checking. Is our user submitted object the same as our user stored object? What do we think, people? Do they look the same?
[00:04:02]
Yes, yes. So presumably they are. No, uh. But maybe our prob. We're going to see why in a second. Maybe our problem, what does it say here? When user enters Will and 105, user submitted object is updated. There it is, Will and 105, and we compare our user submitted with our user stored, and if they're true, we're going to allow our user to submit their purchase. But it's false.
[00:04:33]
Hmm, how come? Hmm, false. Maybe what we need to do is do our, what's our strict equality symbol? Chris, what's the 33 equals, exactly, 3 equals where we're not, maybe we're doing some unexpected, unintentional coercion on our two objects. But that's false too. Oh, we need to distinguish people, we're going to see it here, we need to distinguish people between how data is stored directly in our memory by value, we don't have any here, and when data is stored by reference.
[00:05:19]
Data is stored not directly in our memory, but in a place known as the heap, that is a larger, more flexible part of memory, which we can do let's say in red or orange, I guess. Which is in fact where in JavaScript, all of our non-primitive data is stored. In JavaScript, so far, the values that we've been seeing, at least within type coercion, 7, the string 3, true, have been what's known as primitives.
[00:05:52]
They're stored directly where we save them in our memory. Now, we'd use the term stack, but in JavaScript, these aren't explicitly defined. It is to say they're stored directly versus our objects that can combine up multiple primitives and can be as big as we want and are stored not directly but in a flexible memory store called the heap, and all we're going to store in JavaScript is not the actual object itself but instead, a link off to the heap.
[00:06:41]
And that is going to have some profound consequences for how we're able to use those objects. Specifically, it's going to make comparing them very, uh, interesting. So what actually happened when we stored user submitted, user submitted and user stored? We did not store them directly in memory, and we've had references to, we've had references to this point multiple times within the workshop.
[00:07:09]
Instead they got stored off in the heap, and we merely got in the JavaScript memory directly, a link off to that store, that heap in our memory. So when we declared user stored, rather than directly storing in memory, name Will, ID 105, that instead was stored off in our heap. Now again, JavaScript doesn't explicitly give us access to this heap, it doesn't even necessarily explicitly think about this as a, um, uh, a place that we are able to work with beyond the notion that in JavaScript, we get directly only access to this object via some sort of address.
[00:08:06]
So we can think about that almost as like a zip code, and if you've done some other programming languages, you might know very well that this pointing, this pointer to the underlying object in memory is something that we could even in some languages do math on, that we know this position in memory is something that we can evaluate to enable us to say, well, how much further room, how much further in our memory is the next bit of free space that we can do some work in.
[00:08:36]
In JavaScript, we just declare our user stored, we know our objects there, but it is important for what we're going to see here, that we know that actually what we get in JavaScript is a link to this underlying position in memory. And the same thing with our user submitted, rather than us directly storing our object in user submitted, we get that down here in our big old flexible store of data where we have our name Will, ID 105 and, our position, again, these are sort of informally defined, what we really know is it's a link to some position in memory, I'm calling it 1001, I'm calling it 1002, but really a position in memory.
[00:09:29]
And as I say, in some languages, we can actually directly work with these numbers and use them to exactly, specifically position data in our heap. Pretty cool, and we can do math, pointer math, work on those positions, addresses, locations in our computer's memory. Or treat it as a function. Or treat it as a function. Yeah, it's even better, Chris. So what does that mean, Chris?
[00:09:54]
We're actually comparing here that even though our objects look so similar, even though I feel like surely my user submitted and my user stored, they've got the same stuff in them. They were the same, I looked at, I didn't dwell on this enough, they were the same. What am I actually comparing when I use even my strict equals? Am I comparing the contents of the objects, Chris? No.
[00:10:24]
What am I comparing? The pointers. The pointers, the addresses, the references. Exactly, I'm comparing 1002. Is it equal to 1001, the position in memory? Is it the same position in memory? Is it the same location? And the answer is absolutely not. And so I get false. In fact, if I were to declare here, let's declare another link, I'm just going to put it here. Another link is going to be user stored, I am going to be assigned to another link which I want, I shouldn't call it another, I want to call it a backup.
[00:11:05]
This is a backup, surely I'm going to do a copy of user stored in that final line. Chris, am I effectively, am I doing a copy of user stored when I assign user store to another link? No, not at all. Instead, I am doing a copy of its address, its pointer, its reference to the underlying heap position in memory, meaning another link and user stored, now they're the same. But they ain't a copy, and they ain't a backup.
[00:11:38]
And people, this means to compare the object's contents, there's no such built-in thing in JavaScript. I cannot compare user stored and user submitted in terms of their contents because all I have when I'm evaluating them is their position in the underlying memory, a reference to them. So I can compare their position and I would find that another link is both single and double equals, sorry, double and triple equals to user stored, because it's the same location in memory.
[00:12:16]
But I would not find their contents to be something I could evaluate. How can I compare them? I will have to manually traverse. That means I gotta go in and say grab user submitted name, ID, pull them into the memory directly, where I can then make comparisons. In fact, it's one of the problems and the challenges, is the uh assignment to build a full comparison, deep comparison for objects.
[00:12:53]
And the same thing for copying objects, the another link assigned to user stored absolutely is not copying the user stored data, it's copying the reference to it. So a deep clone, meaning a deep copy of an object, would be grabbing all of the elements, all of the properties, and maybe they have objects stored on them. You might also start to see why having a flexible place for this sort of data where it could have potentially many embedded objects is sensible.
[00:13:22]
Uh, and it's historically why we have a distinction between the heap and the stack. Uh, but I can then, I will have to traverse and maybe recursively do so, cause I don't know how many layers deep it would go in order to copy an object's actual contents. And that's going to be a big problem, people, as there's actually two objects that we have available, or there's an object that we have available to us in JavaScript that could really improve our user experience on our login page, on our buy page.
[00:13:54]
And that is the output of calling date, and we're going to pause on all this in a second, but I just want to flag, it is a great shame that we won't be able to compare objects because there is actually a built-in object that we can create by calling the date function that has a timestamp of right now, by the way, on a hidden property. Uh, and that we could use to make sure that our user doesn't accidentally double click submit and make two purchases.
[00:14:22]
That we could do a quick timestamp and say if you click submit too fast, let's say 1 or 2 seconds after the first, we don't allow that submission to happen. But I'm pretty worried that we're not going to be able to make comparisons, and if those timestamps are on objects and it turns out that as a result of running date, we get an object with a timestamp, how am I going to compare them?
[00:14:46]
Even worse, you're going to see, by the way, that those hidden properties, sorry, those uh timestamps are going to be on a hidden property of those objects. So how can I compare them? Well, hopefully, something's going to happen, but for now, let's have thumbs, people, because we heard a lot of questions throughout on the idea of passing by reference, referring to our underlying stored object.
[00:15:18]
Now maybe we start to see that the thing that we were technically passing in when we pass in a function to another uh function was rather than being an actual um object or function itself, it was a link to that function, and on that note, actually let me make that clearer, by showing that even functions, technically, are not stored directly, and maybe someone was going to ask this, but are instead themselves, because they are first class objects also, stored in the heap, and the reason we don't do this all the time in our diagramming is just that a lot of the time it doesn't have a profound consequence on what we're doing.
[00:00:00]
So there's no need to kind of highlight it. But when we're talking about making comparisons between objects, that's when it starts to become incredibly important that we know that we're not able to do so because we're not dealing directly with the details of the objects, but just their position in memory.
Learn Straight from the Experts Who Shape the Modern Web
- 250+In-depth Courses
- Industry Leading Experts
- 24Learning Paths
- Live Interactive Workshops