JS.Next: ES6 / ES2015

JS.Next: ES6 / ES2015 Collection Maps & Weakmaps


This course has been updated! We now recommend you take the ES6: The Right Parts course.

Check out a free preview of the full JS.Next: ES6 / ES2015 course:
The "Collection Maps & Weakmaps" Lesson is part of the full, JS.Next: ES6 / ES2015 course featured in this preview video. Here's what you'd learn in this lesson:

Maps, similar to JSON objects, are name-value pairs. Get and set methods are used to read/write values to the map. Weakmaps are similar to maps, except their reference to an object doesn’t prevent garbage collection.

Get Unlimited Access Now

Transcript from the "Collection Maps & Weakmaps" Lesson

>> [MUSIC]

>> Aaron Frost: Okay, maps. Okay, so JSON I just make a map like this, right. The very first thing, I say name is Aaron, right. Well in a map, I make a map and I say map.set name Aaron. And I can say map.getaaron or name and it will give me Aaron back, okay.

[00:00:22] So that's how you make a map. So you get map.set and map.get. Again there's no type casting on them. So if I say map.set one and I set it to true, if I say has one, it's gonna be false. But if I then set one, it will has one at that point too.

[00:00:40] So, that makes sense, no type casting? Cuz on an object, on a JSON object, it's gonna type cast, right. So if you say object sub one it's gonna cast that to a string and make a property on the object that's called one, right. So this is not gonna do that.

[00:01:00] So this is like a JSON object but these two things would both be treated as separate keys as opposed to the same key. So, the old way, if I take a user,
>> Aaron Frost: So let's say I create this user, and maybe I got this user from the server, maybe I got out at local storage.

[00:01:24] I don't know where I got this server object, I got it from something though, okay? Something gave me this user object and I'm gonna make a new map for user hobbies, okay? And I can actually use an object as the key, okay. So for hobbies, I can put in there, and the key can be the user.

[00:01:44] So instead of having to go through and reference it based on ID and use primitives only as the keys, you can use objects, functions, primitives distill as well. But you can use complex objects as the keys as opposed to just primitives. So here I have a hobby map and I get my hobbies out by just passing it the user.

[00:02:11] So I would say userHobbyMap.get and I'd pass up my user and give me back my hobbies. That's one thing you can do. So, it can't be a second copy of an object that looks identical cuz here, I've got two users that look a lot alike, right. And by a lot alike, I mean they have all the same values but in memory, they're two different objects, right.

[00:02:41] So if I make this HobbyMap when I set user1 and I set his hobbies, if I'm trying get user2 it's gonna be undefined. So even though they look alike, it is completely separate key because it's using the pointer instead of the object itself. Does that makes sense? Okay, so yeah.

[00:03:04] And then usage, some people were like hey, I'd like to make a map of my DOM elements and put them into a map so that I don't keep querying them. And I could get their properties just by referencing them themselves. So you could go get some element off the DOM and you could set element and you could say loaded is true, opacity is zero, right.

[00:03:29] And then later on in some other section of your code, you could get the element back out, right? So why is this a bad idea, does anyone know? Can anyone think of it?
>> Off Camera 1: The DOM might change.
>> Aaron Frost: The DOM might change, right? Yeah, so if something happens and the DOM changes, anything that's not in my map memory, the garbage collection's gonna go, I'm gonna kill that he's gone.

[00:03:58] Just because you're removed it from the DOM doesn't mean it's not in your JavaScript memory, right. So if you've thrown all these references to DOMs inside your map. Now all of a sudden we got a problem because you got a huge memory leak. Because anytime the DOM changes, you're still flooding out memory because you're packing them into your map, and this is a problem, right?

[00:04:19] Okay, I'm gonna talk about why this is bad. I'm gonna show why this is bad in a second. The one last thing I didn't show about a map, and let's just show it real quick.
>> Aaron Frost: There is a question in chat, I don't know if you wanna do it after you're done with this or?

>> Aaron Frost: Yeah, one second. So, you can get a map iterator out of it and you can iterate over all the properties inside the map. There's not a size is there? Yeah, yeah, there's a size. So you can pull the size off of a map as well, just to see how many things in my map, how many key value pairs.

[00:05:32] So yeah, what's the question?
>> Off Camera 2: Do you see the chat there?
>> Aaron Frost: Yeah, so it says, can you provide a custom-
>> Off Camera 2: There's one right before that, then maybe you can ask that one next.
>> Aaron Frost: The ones by James G?
>> Off Camera 2: No, the one above it Mike.
>> Aaron Frost: As I understand, let is occupying only one position in memory.

[00:06:00] So we can't use it with map set because they always have more than one values, is that right? Yeah, I'm with James G, I'm not sure that I understand the question. So I'm gonna go to the next question. Can you write a custom hash function for sets and maps?

[00:06:23] Robby, I don't know what a custom hash function is.
>> Off Camera 2: I think he means like to tell what a key is. In Java or whatever other languages, sometimes you can control a get hash such that it's not just based on the object itself. It could be unique by its name plus value boundary.

>> Aaron Frost: Not really, not built in to the framework, you would just make that the key, right. So yeah, sorry dude, I don't think so. So yeah, so last thing I need to show is the size. And that really matters because we're about to show a different kind of map.

[00:07:02] I talked to you about the memory leak that you're gonna get if you try and put these DOM objects into a map. It's gonna be efficient because you're like dude, this is actually really fast. But once at first, but then all of a sudden, it's gonna get really slow because you're throwing DOM elements into a map.

[00:07:19] The DOM releases its reference but your code never released its reference. So garbage collection can't pick up, your map just grows and explodes. So a weak map is a different thing, okay, altogether. So, a weak map is like a map except for it doesn't have that, it potentially can avoid that memory leak problem.

[00:07:45] So if we have a weak map and we set name equals Aaron, we can get name, and Aaron comes out. So, a lot like a map, right, has a user. So, if we say has user, we'll say false. We can set the has(user) true. We can delete me, you won t have many more anyway.

[00:08:05] So it's just exactly like the map, okay, that's all I'm trying to show here. But it's not exactly. When I said exactly, I meant not exactly, it's just a lot like a map. So inside a map if you go ahead and set, let's say we put the same user set of a map in a WeakMap.

[00:08:31] The map has a size, the WeakMap doesn't have a size. And it's important, because what that means is it's not actually keeping track of how many things are inside of it, okay. It's kind of hard to explain but If you put a key, let's say my user key, or let's say I get some DOM element and I store that inside my map as the key and the value can be foo, I don't care, right.

[00:09:03] If my map is, let's say the DOM goes in and removes it. And so the only thing on the whole planet referring to that DOM anymore is my map, my WeakMap anyway. If a WeakMap sees that it's the only thing holding onto an object, it will release it, okay.

[00:09:18] So you can go ahead and you could set the key to be some DOM element. And then once it's gone, your WeakMap's the only thing holding a copy or reference that DOM element. The WeakMap will let it go, okay? And because that only has a weak reference to it, that's why it doesn't know like how many things are in it.

[00:09:37] It doesn't know its size or anything. That make sense?
>> Aaron Frost: But it's okay because if the DOM element was gone and you were the only thing pointing to it, then there's no way you could unlock it anyway. So it should get rid of it, cuz there's no other pointers to it.

[00:09:53] You would never have the cipher to get it back out because the DOM element was the cipher, right, that's how you could get it out. [INAUDIBLE] hopefully, I didn't weed.
>> Off Camera 3: [INAUDIBLE] believe if you have multiple WeakMaps pointing to the same [CROSSTALK] key, then they'll still let it go, or not.

>> Aaron Frost: I don't know, that's a good question. Great question, actually, yeah.
>> Off Camera 3: I think maybe the one that you didn't understand, they were just wondering why you have to use bar instead of let when you're assigning map me, version, and set.
>> Aaron Frost: No, you don't have to.
>> Off Camera 3: So you can use LET?

>> Aaron Frost: Yeah.
>> Off Camera 3: Okay, I think that's [CROSSTALK]
>> Aaron Frost: I'm just doing it to be friendly, I don't want to freak anyone out with the let word. I don't know dude, I wasn't paying that much attention. It wasn't intentional let's just say that. Good question though. Okay, a weakmap holds only a weak reference to a key.

[00:10:47] Which means the reference inside the weakmap doesn't prevent garbage collection of that object, okay. And Nic Zakas wrote an article about it and that was, he summed it up and I thought that was an elegant way to state it. So if the only pointer is my map, the map gives up and says take it, okay.

[00:11:07] So if that element right there, if that's the only pointer to that element is right there where I've set it in my WeakMap. It just lets it go, okay?