Transcript from the "Objects Linked as Other Objects" Lesson
>> Kyle: Let's simplify. Let's try to find that beautiful program inside of that ugly program. Let's try to find what OLOO, Objects Linked to Other Objects looks like.
>> Kyle: Here's that old and busted code, okay? Remember the prototypes and all of the ugly, unnecessary complexity. And you recall that I pointed out that the beautiful part of this program is the b1 object links to the Bar.prototype object linked to the Foo.prototype.
[00:00:29] Unfortunately, to get that object in linkage we had to do all this other stuff. What if i could show you how to make those objects without all that other complexity? What if we could just link objects together? So what I'm gonna do is walk you quickly through a derivation of OLOO's style, step by step.
[00:00:50] You don't have to do all these steps yourself, it just shows you how to refactor, if you will, to embrace OLOO's style.
>> Kyle: So what I'm going to do is little by little remove the unnecessary complexity and replace it with a simplicity.
>> Kyle: In other words, I'm gonna perform a Vegas style magic trick right before your very eyes.
[00:01:14] But unlike a Vegas magician who wants to distract you over here so you don't see how the trick is done, I wanna show you exactly what to look at. I want you to keep your eye on those three objects. Because the changes that I'm about to make to this code are gonna have absolutely zero functional impact on the code.
[00:01:32] It will have exactly the same behavior, it'll just have a cleaner, simpler style of getting there. Keep your eye on those objects and don't get lost. The first step of my magic trick is that new keyword down there on line 17. I got to get rid of that new function call, cuz the new keyword is the gateway to doing poorly designed class oriented coding.
>> Kyle: So let's get rid of the new keyword. You remember how I told you before that the new keyword does four things. It creates, it links, it passes in, and it returns.
[00:02:13] If you divide those into two separate things, you'll notice that the first two are kind of about creation and the second two are kind of about initialization. The new system does two different things, creation and initialization. I wanna separate those. That's how we're gonna get rid of the new keyword.
[00:02:33] So what I'm gonna do is replace the new keyword with an Object.create call that does the first two things. It creates and links, and then, line 18, I'm gonna call the bar functions so that we do the initialization. Now, that code does look a little bit, well, more verbose for sure than the previous version of the new keyword.
[00:03:00] Just hold on because we're gonna make that code better too. But I would argue that even though it looks more verbose now, it's actually simpler. Simpler by definition that it's not conflated together. We have two separate steps. Have you ever needed to create an object but not initialize it?
[00:03:18] Maybe you've created like objects in an object pool before. I've done that on many occasions. When you use the new keyword you don't have that option, so what do you do? You make an empty constructor so that it creates but it doesn't do any initialization. Why don't we just give ourselves the utility that allows us to just create without initialization, that's what Object.create does.
[00:03:41] So I would argue that even though this is more verbose, it's actually simpler. But we're gonna work on the verbosity as well.
>> Kyle: We still have a b1 object linked to a Bar.prototype linked to a Foo.prototype. Same behavior.
>> Kyle: The next step of my magic trick is to take all the references to Bar.prototype and get rid of them.
[00:04:07] And in fact, get rid of the bar function entirely. Because we don't really need a bar function. The function is really not even necessary.
>> Kyle: So I'm just gonna make a bar object instead of a bar function with a bar prototype object.
>> Kyle: Line 8 creates a bar object using Object.create and make sure that it's prototype link where it needs to be.
[00:04:34] And you'll notice that I just start adding methods directly to bar, Bar.init, bar.speak. Why do I need a bar.protoype when I can just do a bar object itself? Because the bar function with a prototype object was just an indirection of complexity.
>> Kyle: Now look at how much simpler line 16 and line 17 look.
[00:04:58] To make a b1, I just make a b1 that Object.creates from bar. There's no Bar.prototype there. And to call this init function, I just say b1.init, and I let this binding rules do what they do.
>> Kyle: And I still have a b1 linked to a Bar linked to a Foo.prototype.
>> Kyle: One last step to this magic trick. I need to do the exact same thing to Foo.prototype that I just did to Bar.prototype. We don't need a foo function and we definitely don't need foo.prototypes cluttering up the code. We just need a foo object.
>> Kyle: So now I have a foo object with methods directly on it.
[00:05:47] That init function that I temporarily had on bar has now been moved up to foo because you know what? That's the place where the initialization was happening anyway. That whole indirection of constructors thing was just unnecessary complexity. So now I have an init, I'm linking to foo I have an init there and when I, down on line 17 call b1.init.
[00:06:12] It delegates two levels up the chain to that init function calls it in the context of b1 and adds the me property to it.
>> Kyle: And at the end of the day, I still have a b1 linked to a Bar linked a Foo.
>> Kyle: Now I don't know about you, but I look at that code, that expression of the program, and I feel like there's a lot fewer moving pieces.
>> Kyle: So this is the OLOO style of code, wired up with the b1 and b2 in it. So now we've got both of those objects being created.
>> Kyle: And here's our Object.create function. This is the polyfill for Object.create. Look at what I'm doing here. I'm making an object and I'm linking its dunder proto to the o that I asked for.
[00:07:47] So it's actually not a very complex concept at all. I just make an object and link it. But this isn't really the polyfill. You know what the real polyfill is?
>> Kyle: That's the real polyfill. And you'll notice something interesting about what it's doing. It makes a function that nobody cares about, it sets it's prototype and it calls new against it.
[00:08:15] Same equivalent outcome behavior. What I love about this visualization, and it may be lost on you, because I see some tired faces at this point in the workshop. But this is actually my favorite slide in the entire workshop. What I love about this slide is that it points out just how pointless those functions and dot prototypes and new keywords actually were.
[00:08:40] I took all of that complexity out of the program and hid it inside of Object.create.
>> Kyle: It really hammers home the point that all we care about is linking objects together.
>> Kyle: And it's not just simpler style, I would also argue, it's simpler mental models as well. Here's the old and busted code, the prototype style code, and here's the old and busted mental model.
>> Kyle: We could ask the question, was ES6 class any better? Maybe, it certainly was syntactically a bit nicer. Still had a bunch of conceptual problems under the covers. The mental model is not significantly better. I claim OLOO as the new hotness. This foo and bar object in the b1 that links to it, but here's the real big pay off, the simplified mental model.
[00:09:46] Cuz it really just embraces that the only thing we need to know about is the objects linked to other objects. That's the only thing that ever mattered anyway.