Check out a free preview of the full Deep JavaScript Foundations course:
The "Challenge 7: Solution" Lesson is part of the full, Deep JavaScript Foundations course featured in this preview video. Here's what you'd learn in this lesson:

Kyle walks through the solution to Challenge 7 and answers students' questions.

Get Unlimited Access Now

Transcript from the "Challenge 7: Solution" Lesson

[00:00:00]
>> Kyle: All right, let's talk about the solution for exercise 7. As I said in the set-up, what we wanna do is take this project factory function and turn it into a project constructor class, whatever you wanna call it in JavaScript. So let's look at how we might do that.

[00:00:17] We're gonna start by still adding a Project function now, but you'll notice that I need to prepend everything with this. Because I'm gonna be setting these properties directly on the instance of this Project class, if you will. So I'm gonna be setting projectId, description, work, and time. All those public properties on an instance.

[00:00:35] And I don't need to include any functions in some closure, I'm gonna add them directly to the prototype. So here, I have Project.prototype.getId, Project prototype.getDescription, getTime, addWork, getWorkEntryCount, and getWorkEntryLocation. So all the functions we had before, but now they're on the prototype. And any place where I was referencing a variable lexically, I now have a this dot in front of it.

[00:01:06]
>> Kyle: And having a this dot in front of it allows me to access that context for each individual instance.
>> Kyle: To use this new project class,
>> Kyle: We call new in front of the capital P project function like we do on line 208. Otherwise, from the outside world that is, the rest of the code inside of app and inside of UI.

[00:01:34] From their perspective, the project object, it doesn't matter how we got it. Because they still call methods on it and they still refer to it.
>> Speaker 2: This might not be a quick answer.
>> Kyle: When is customizing something like this a good idea? A good, because you could do all this without going down this route.

[00:02:00]
>> Speaker 3: What do you mean I could do it without going down this route?
>> Kyle: How would you do it without going down this route?
>> Speaker 3: The same way we've done it before in the sense of just-
>> Kyle: With the module pattern?
>> Speaker 3: The module, or even just creating some kind of, I don't know.

[00:02:13]
>> Speaker 3: Just getting those methods somewhere, bringing them in.
>> Kyle: Okay, so you're asking, what's the benefit of doing the prototype style over the module style?
>> Speaker 3: Or yeah, or-
>> Kyle: We already talked about why modules over just the project entry data. That was exercise 5c when we switched to having the project as its own entity.

[00:02:37] That gave us a set of APIs to refer to, which cleaned up a lot of that code logic that was all mixed together. So that part, I think, we've already probably addressed. But the more important question to the current moment is why would we do this? If we already had a working module package, why would we go with the prototype style?

[00:02:57] To be quite honest with you and to be quite blunt, I don't have any answer to that question. That's kind of my point, is that we have been attempting to do this prototype oriented code for 20 years, and I don't think it buys us anything. I just think it creates unnecessary added complexity.

[00:03:18]
>> Speaker 3: Okay, that had been my opinion just cuz I'd ran into it once. Took me a long time to figure it out.
>> Kyle: But some people in the face of complexity say I need more complexity, to deal with the complexity that I already have. Some people like myself when you see complexity I try to take a step back and say how do I do this more simply.

[00:03:39] When people are faced with these kinds of complexities, what many people have done is they go invent whole frameworks around these things to do all these stuff for them.
>> Kyle: I think it comes from the mindset of classes work really well in my C++ code. I wanna do the exact same class design in JavaScript, I'm really frustrated the JavaScript doesn't do classes the same way.

[00:04:03] Let me invent some other thing to put on top of it, to duct tape it so that it looks right.
>> Kyle: Yes?
>> Speaker 4: So with this approach, there is no way to preserve encapsulation, right?
>> Kyle: Yes, that's definitely a trade off here. I was gonna get to that.

[00:04:23] There is no encapsulation at this point, is there? Everything's a public property on the object instance. Now some people like the fact that it's all publicly available. Cuz now things are easier to test and maybe it's a little bit more flexible. But now we've lost the ability to encapsulation, so that is definitely a trade off with this style of code.

[00:04:43] If you put stuff disoriented, and you put it on a public object prototype, it's all hanging out there for anybody to see and mess with.
>> Kyle: So that's kind of why I still like modules a lot.
>> Speaker 5: But you can get encapsulation if you put this inside of a module and you export the project function.

[00:05:02]
>> Kyle: So the problem with going that route, when you try to mix the module pattern with the prototype style pattern. In theory it sounds great, and I promise you, I have tried it so many times I've lost count. Many others have tried. Doug Crockford has a pattern that he is espousing these days, where he claims to use closure along with objects and other stuff like that.

[00:05:27] There's just a flat out fact that we're never gonna be able to get around, which is that the prototype system and the lexical system do not cross over. So if you go to all the trouble to create your closure inside of your factory, or whatever, and you just export this project function, that'll work for one instance.

[00:05:43] But now you're not gonna be able to have multiple functions sharing across, I mean have a function shared across multiple instances. No matter what you do, I mean you can try it if you want, but you can take my word for it, cuz I've tried. No matter what you do, you're gonna end up creating Frankenstein code that just doesn't actually get any better.

[00:06:02] My best advice to you is either do prototype style code or do module style code. Don't try to mix them in the same piece of code. Cuz if you mix them it's gonna end up like Frankenstein.
>> Kyle: But the response, really to the original question was, the real response is, we do that because we're enamored with the class pattern that seems to get us closer to the class pattern.