Transcript from the "Exercise 3: Solution" Lesson
>> Kyle Simpson: I imagine many of you are probably still doing your copying and pasting of dot prototypes, and dot this references all over the place. We won't spend a lot of type delaboring this, cuz this is mostly just tedium, but I want to point out a couple of things.
[00:00:17] First of all, it was asked can I do something like notesmanager.prototype equals and do an object literal and just do things like add note and function expressions. And the question was asked, is that possible to avoid some of this typing. The problem that you've done there is you've thrown away the built in dot prototype that was there.
[00:00:37] And that has things that some people want like the dot constructor reference and it might have had a linkage to a different object that you were throwing away. So you want to be careful about sometimes, you want to be careful about you dot prototypes because sometimes you can end up losing information.
>> Speaker 1: Could you
>> Kyle Simpson: And the best way is to generally do this dot prototype stuff all over. Over and over and over again.
>> Speaker 1: Could you use something like j query extend to get around that problem?
>> Kyle Simpson: Most of the class libraries out there do provide some sort of shortcut to this, because this is one of the many things that people don't like dealing with.
[00:01:15] So j query extend, as well as a hundred other utilities that are like it, are all about trying to pave over some of these problems.
>> Kyle Simpson: All right, so, a couple of other things to point out, like this showHelp one. I don't know if anybody got to working on that one, but if you do prototype.showHelp= function, Unindent.
>> Kyle Simpson: There's a certain special problem that we're going to have to deal with here. Alright so we know inside of here we can do list.help. And I can do my document.addevent listener. Now this function handler thing that I'm binding to there, I'm gonna need to do a disc reference inside of it.
[00:02:06] But, what's gonna happen to that disc reference if I just pass that function like I'm doing?
>> Speaker 2: You're gonna get the scope of-
>> Kyle Simpson: It's gonna be the button in this case J query. Both the API and the j query API manually will bind it to the element that fired that.
[00:02:26] So that's not good. So one solution is to do hard binding, to dot bind this on the end of that function so that we force the function reference to be bound to the proper this. That fixes one problem and creates another problem. And the problem that is creates is now, you might not have seen this, but I had a name for this function so that I could unbind it.
[00:02:50] But I can't unbind it by name anymore, because the name of the function isn't the actual function that was bound. The function that was bound was that new hardbound function. We in fact don't have a reference to the hard line function. So we have no way to do this remove event listener properly.
[00:03:07] So really this isn't a good solution for [COUGH] doing .binding this. [COUGH] Now typically I would advice against this particular thing, but you've probably seen people do stuff like var self = this. And they can do self here and then rather than doing a this reference, we can do a self reference.
[00:03:28] Now, most of the time I'm going to tell if you're doing stuff like that you're completely shooting yourself in the foot because you went to all the trouble to do a this mechanism style code and then you fell back to lexical style code. The var self=this is usually a code smell that you're doing something wrong, in my opinion.
[00:03:49] But, this is one tiny exception case with these event handlers, where the other way of doing it is much harder. So it's easier to fall back in this exception case to a var self=this. But in general, if you see people doing var self=this, I think that's them not understanding how the mechanisms work.
[00:04:10] All right. I won't belabor most of these other ones. A lot of these other ones are helpful, but let's just point this one out. Down here in our init function, we're definitely going to need to manage all of these references. So I'm gonna have this.open_help. I'm gonna bind it to this.handleOpenHelp and do a manual bind this.
[00:04:33] So I have to do that on every one of these, which kinda sucks.
>> Kyle Simpson: Does everybody see why I'm doing that?
>> Kyle Simpson: And so on. Now all of these things that were private variables down here we no longer have any private variables so we can get rid of all of those.
[00:05:04] We no longer have any of this stuff. Assuming we had finished the rest of our conversion, then all of this stuff would be just things that were added to that prototype object. And so down here instead of having a NotesManager we would say something like var mynotes=new NotesManager.
[00:05:28] And we'd reference myNotes.loadData, and myNotes.init. And lastly, because we are keeping track of some state like our Notes variable, for instance. Up in our constructor we're gonna wanna initialize this.notes = . Yeah?
>> Speaker 2: So which do you like better, the module, or the prototype.
>> Kyle Simpson: Unequivocally, the module pattern is much more useful in my code than the prototype pattern.
[00:06:07] But we haven't really seen my favorite pattern yet, so. We're getting there.
>> Kyle Simpson: Okay. So in addition to all the clunky syntax and all of those things that are falling over, it's just a more complicated mental model to try to pretend that this is classes. Most people solve that problem, as I said, by using some library to pave over the differences.
[00:06:34] And any time you have to use some library to pave off the differences, you should ask yourself, is this too difficult? Am I doing it the hard way? Is there a better way?