What do you want to learn?
Leverged
jhuang@tampa.cgsinc.com
Skip to main content
Pluralsight uses cookies.Learn more about your privacy
Structuring JavaScript Code
by Dan Wahlin
This course walks through several key patterns that can be used to encapsulate and modularize JavaScript code. Throughout the course you’ll learn how closures and other techniques can be used to better organize your JavaScript code and make it...
Start CourseBookmarkAdd to Channel
Table of contents
Description
Transcript
Exercise files
Discussion
Learning Check
Recommended
Why do we Need JavaScript Patterns?
Introduction
Welcome to the Structuring JavaScript Code in HTML5 Applications course. My name is Dan Wahlin with Pluralsight. In this course, I'm going to walk you through the process of converting from more of a function-based JavaScript coding style to more encapsulated and modular-based JavaScript coding, something that's better for reuse and better for maintenance. Now as you go through this course, you can find additional information about this topic and several others on my blog, and I also tweet about various technical topics as well, so if you're on Twitter, feel free to follow me there too. Now in this first module, we're going to talk about why do we need JavaScript patterns in the first place? After all, if you've been writing JavaScript code already and not using any patterns, you probably rolled out successful apps, and they worked just fine. Well, it really boils down to three key areas. Number one: We want to write code in a way that leverages as much reuse as possible. That can be across pages or even across multiple applications. Number two: We want to promote maintenance of our code, and this is especially important if you're in a production support-type of mode at work where not only do you write the apps, but you also have to debug them or other team members might have to debug them when they're in production. With today's HTML5 world, this is really true where a lot of the JavaScript API, such as the Canvas or Geolocation or Web Storage, are all JavaScript based, and so the amount of JavaScript going into HTML5 applications has really significantly increased compared to maybe some of the older applications. So maintenance, of course, is important. And then, finally, how do we avoid naming conflicts? It's very common nowadays to use third-party plugins, whether they're Open Source or just something you found on the internet, that can really increase productivity, the amount of code you have to write, and things like that. And when you combine that code with your code, how do you make sure there are no conflicts between variable names or function names or other things in your code? So, we'll talk about how we can leverage encapsulation and modularization type concepts to do this. So, in this first module, we're going to start off by talking about what I call function spaghetti code. This is traditionally how most people get started with JavaScript. They just create function after function, have some variables. But there is a better way to do it. From there, we're going to talk about how can we encapsulate variables and functions in our JavaScript code using something called closures? Closures provide encapsulation much in the same way that classes provide encapsulation in the object-oriented world. So, I'll explain what a closure is and how you can write closures in your JavaScript code. And then, finally, I'm going to address two different ways you can define variables. There's really not a better way to do it per se, but I like to use one particular technique in my code. And I'll show you that, and we'll be using that technique throughout all the different modules coming up in this course. So to get started, let's jump into our first section here on function spaghetti code and look at the traditional way most people get started writing their JavaScript code in applications.
Function Spaghetti Code
When people first learn JavaScript and start writing code for web apps, they oftentimes just add variables and functions directly into a file and call it good from there. And while there's no problem with that, it's not really spaghetti code per se. I mean, after all, it's all JavaScript. It can be difficult to reuse, maintain, and you can definitely have some naming conflicts. So function spaghetti code is definitely something we want to try to avoid in our JavaScript code. And as mentioned in the first section of the module, this is especially true in HTML5 apps where we have all these JavaScript APIs, and the amount of JavaScript we're going to be adding into apps just seems to be getting bigger and bigger. So we want to eliminate function-based spaghetti code. Now how do you do that? Well, once we get to closures in the next section of this module, I'll show you some of the basics of how to get started avoiding that. Now, why? you might ask. Well, there're several reasons. When you just throw functions and variables out into a file, and they're not wrapped with anything, no encapsulation at all, then those functions and variables are added into what's called the global scope of JavaScript. And basically you can think of that as just one collection area that all the scripts that run get added into. So obviously naming conflicts, especially as you add in third-party JavaScript libraries, become more and more of an issue, especially if they also do kind of function spaghetti code where they just have function, function, function. Now it's really easy to not realize it but have your function named the same as maybe their function or your variable the same as their variable. So this potential for duplicate function and variable names is a problem. Also when you just throw functions out there, it's not modular at all. In fact, it's just functions. There's no rhyme or reason. There may be four functions that are kind of related to each other, but when you just throw functions out there, there's no way to see that unless you put comments or something in the JavaScript file. That, of course, makes things a lot more difficult to maintain. JavaScript code, especially for those that are new to it, is a little bit challenging anyway. And so if you have different skill levels on a team, but everybody's supposed to be maintaining apps, then it's really important to write code in a way that it's easy to know that, hey, if you're working with this grid object, you just go to this file, and it focuses 100 percent on the grid object and avoids naming conflicts. The final thing that's mentioned here is that there's no sense of a container when we just throw functions into a file. The file is the container, really. So what if you did want to write some kind of like classes that you do in C# or Java, but in the JavaScript world? Well, there's not really a way to do that out of the box, but it can be done. That's really the purpose of this course. So, it all boils down to we kind of feel like we're solving a Rubik's cube sometimes when you jump into a JavaScript file, especially if it's not one you wrote, and you're expected to go in and fix it. If there's no rhyme or reason to how the variables and functions are laid out, it's oftentimes very difficult to maintain, so we'll be talking about different techniques as we jump into the upcoming modules. So, let's take a look real quick at the kind of the traditional way most people write their functions and variables and talk about what happens there.
Function Spaghetti Code Demo
Most people start out writing JavaScript by simply throwing a bunch of functions into a .js file or maybe even into the HTML file itself and then working with those. So an example of that is some code shown here. This is actually from a project I did a long time ago, and this has a lot of functions you can see. It's literally just function after function after function, and there's a lot of code here. I think there're almost 2,000 lines of JavaScript just in this file alone. You can imagine how hard it is to maintain something like this. A lot of potential for naming conflicts. And other problems can come up. Now to kind of show this in action, I have a little more simple example here of Local Storage HTML5 web storage. We're going to use the Local Storage feature. And let me run this app as is. And all it does is pops up a little GUI, and the user can type in a name, select a state, and then hit Store Settings, and notice now when I go back, it's going to use Local Storage, and it will be preserved. You should see those same values come up, and I can clear as well. Now to do this, the page itself just has some very basic HTML, so I have a localStorage.js that's referenced. Now this is using jQuery behind the scenes. So you can see jquery.js right there. And this is a very simple file, but you'll notice it's just function after function. There're only a few of them. But, for instance, we have one here called storeSettings. Well, what I'm going to do is let's add a new script. Let's say that we're also going to start selling some products on our site, so we'll add a new item. We'll select a JavaScript file, and I'm just going to call this store.js. And in here, let's say that we also had something very similar, storeSettings, very different, of course, context and meaning, but let's go ahead and add it. So, we'll do storeSettings, and just for this demonstration, I'm just going to put an alert, Storing settings. Okay, so we have the exact same function now. Now, let's assume that somebody else, either on our team or we got this code on the internet, and we're just plugging it in. Let's now come back in, and we'll drag on our store.js, put it right there, and let's go ahead and run this now. Okay, so let's just put in something here. We'll hit Store Settings, and it looks like Store Settings was called, and if we come down into here, everything looks pretty good, but if I come down into, this is Chrome's Developer Tools, we can actually get information about what's in here. Let's go into Local Storage, and you'll see nothing was stored though. Because what happened is I now have a function that conflicted with my other function. If we switch those around, and let's go ahead and put this script first, and we'll run it in Chrome again. And let me refresh this just to make sure we pick it up. We'll do test. Store Settings. And now let's go in and take a look at Local Storage, and you'll see we do have two values because that script came first in the load order. And so you can see right there, that's a problem. We don't want to have naming conflicts across things. Now what really gets worse is if we had variables defined in here just maybe at the top level. If we had, for instance, a foo there, but then our Store also had a foo. We set that to, say, 5. Well, now depending on the order of loading of the scripts, we're going to have a problem, and obviously that's not a problem we want to have. So, this is what I mean by function spaghetti code. Really, there's no rhyme or reason to any of the functions in the particular file. In this big one I showed, some of these files or functions, I should way, are related to each other, while others are very, very distinct and separate and really should be in their own, either in their own file at a minimum, in their own object preferably so that we can reuse that object if possible. So, moving on in this module, we're now going to switch gears and talk about how can we encapsulate variables and functions into a container, and we're going to use closures to do that, and that's what I'll cover next.
Closures to the Rescue
In the previous section, we took a look at function spaghetti code and how we can just throw functions into a file and it just magically works, and really that is part of the beauty of JavaScript. It's very easy to work with. There's not really a specific format you have to follow for structuring your code. But, as your code gets bigger and bigger and, as I mentioned, as HTML5 apps continue to include more and more JavaScript, you're probably going to want to encapsulate and add modules for your JavaScript code. So, in this section, we're going to talk about closures and talk about how closures can come to the rescue and aid us in encapsulating our functions and our variables. So, Douglas Crockford, who's very famous in the JavaScript world, initially defined closures and provided information about it. And he had a great quote that I pulled out. "…an inner function always has access to vars and parameters of its outer function, even after the outer function has returned." Now the first time I read this, I'll have to admit that didn't make a lot of sense to me, and I needed to see something visually to clarify it, which I'm going to show you. Really, what he saying, though, is that in JavaScript, you can nest functions, and if you do that, it changes the visibility or access to variables and other functions, depending on how they're nested. So, most of us are used to doing something like this. This is a non-closure example. So, nothing new really here. We have a function called myNonClosure. You can see that it has a date inside of it that's created. And then we simply write out the milliseconds from that. Now, what's important to note here, though, is that as soon as myNonClosure exits, once this return statement is called, this date variable will be lost. It will go out of scope, and that's pretty normal, and that's how we're used to JavaScript working of course. When we leverage this feature called closures, you'll see that there's a way we can nest these functions to make it so the date variable actually sticks around even after a function's returned. Now why would you want to do that? Well, because when we want to start emulating what classes do, and how they act as containers for functions and variables in other coding frameworks, and if we want to do that in JavaScript, then we're going to need to use closures to accomplish that. So let's look at an example. So this would be a closure. Now you'll notice the date looks the same here. But the big difference is we're returning a nested function that you see right here, and notice that it actually references the date that's up here. What happens behind the scenes is because this nested function references the function up here, this date actually sticks around even after this function returns. And so if this represented our object, this particular variable of the object will still be around even after this function returns this milliseconds. And that's what a closure does. The variable actually sticks around even after this nested function returns its data. Now what that's going to allow us to do in the JavaScript world is leverage this fact to create closures and to actually create containers around our variables and around our functions. And that way, we won't---number one: We won't have the problem of naming conflicts like I showed in the last demo. Instead, we'll actually be able to create a container for our variables and our functions. So let me show you an example of this in action. Because if this is the first time you've seen it, you might wonder right off the bat why would I even do this with a function? So, let me show you an example of how to create closures and how they work.
Closures Demo
Let's take a look at the difference between regular JavaScript functions and functions that can be used to create closures so that variables hang around in memory. So, I have an output div, and what we're going to do is what you saw earlier. We're going to grab the milliseconds of a data object. I'm going to write it to this output div, so let's first take care of handling that. So, I'm going to create an onload. And when that fires, we'll call this function, and we'll create an output variable. And now what I'm going to do is create a regular JavaScript function, one you're definitely used to if you do much with JavaScript. So, we'll call this myNonClosure like you saw earlier. And we'll grab a date object, and we'll simply return the date's milliseconds. Okay, so when this date object is created here, this variable, it's going to be returned, and, of course, as soon as that function loses scope, then we lose the variable. And that's pretty standard. So let's just kind of prove that real quick. So, we'll say innerHTML, and we're going to set that equal to myNonClosure. Alright, then I'm basically going to do the same thing again. We could have done this in one statement. You'll see why I'm breaking it out, though, in just a moment. Because if we run this right now, it's going to run so fast that it's going to look like the date variable did actually hang around in between calls. And you can see it did work. 490490. Let me add a br right here so it's even more clear. Okay, so we'll see that they look the same. Well, there we go. That one's slightly different. And the problem is most of the time they're going to be pretty close. It's just running so fast that we can't see the difference normally. So, to make it really obvious, I'm going to do a timeout, and we'll just do a little nested function here. And we'll say after 500 milliseconds, we'll call this, and then we're going to output the value. And this will really show that it truly is creating a new data object on every call. Okay, and there you see they are definitely different. And that's what you'd expect. Pretty standard. Now, I'm going to create a function that has a nested inner function that references this date variable. So, let's come down and we'll create a new one called myClosure. Inside of here, we'll do the same thing. So, I'm basically going to grab this guy, but I'm going to return a function that's a nested function, so we're just going to return a nested function, and this nested function will do basically the same thing. So, you can see that for all intents and purposes, the code looks pretty close to what you saw up here, but you'll notice that this date variable, which is defined up here of course, is referenced in a nested function. That's going to create a closure around this guy, which means as long as this myClosure is in scope, the date will not change. It's going to stay the same up in memory, and every time we call this, it's going to call the same date object. And that's what a closure is, very much like Douglas Crockford said, you have a nested function in an outer function. If you reference a variable in the nested function that's defined outside here, it will create a closure around it. So to demo this, let's go ahead, and I'm going to create a variable to reference this function here. We'll just call it closure. And this is going to instantiate the function, and we'll then assign it to this variable. Now from here, I'm just going to now call closure. Okay, so now if we run this, you're going to see that we should get the same milliseconds written out across calls, even though this is calling this inner function twice. So let's go ahead and run it. And there we go. You can see we get the same value every single time, and that's correct because we created a closure, which means that this date object hangs around as long as this guy is still in scope, which in this case is our object is still in scope. Now, as soon as that goes out of scope, then the date object would also go out of scope. But, if you think of this as being similar to a class, if you're familiar with classes in C#, Java, or other languages, this would be your class definition, and this would be the end of it, and then inside of it, we simply have a variable and a function. Now, it's a little bit different because we are returning the function, but in part two of this demo, I'll show a different technique that can be used. That creates a closure, though, and allows us to leverage some of these JavaScript patterns I'm going to get into just a little bit later in the course that take advantage of encapsulation and kind of more a modular-type pattern versus a standard function where it always is going to create this new date object every time the function's called. So that's an example of creating a simple closure.
Closures Demo 2
Let's take another look at creating a closure that's a little more along the lines of the patterns that we'll be talking about throughout this course. So, I'm going to come right below this one, and I'm going to create a variable now. I'm going to call this myClosure2, and I'm actually going to assign this to an anonymous function. Now this will be very similar to a class definition here, if you work with classes at all. And inside of it, it's going to be very similar, but I'm going to change things up just a little bit. So, I'm going to come in, and we're going to say that we also want to have an actual function in here, and I'm going to call it---I'm going to give it a variable name of myNestedFunction. And we'll do something like this, and then we're going to return the same thing. We'll return the milliseconds. Okay, so now you can see I actually have a variable to find, and I have a function to find in my code, and if you think of this as kind of the container, we're now encapsulating both of those guys within one container called myClosure2. So now what we can do is come on up, and if I come in and instead of calling myClosure, let's call myClosure2, but I'm going to actually new it, so I'm going to say new myClosure2. And now we can call closure dot, and let's see what happens when we call myNestedFunc. So we'll put that in right there, and then I'll just copy that down below as well. Okay, so we're now creating a new instance of myClosure2, assigning it to closure. We then try to call closure.myNestedFunc, and that of course should return the milliseconds. And because we created a closure, and we know we did because we have a nested function that references the data object, which is defined in the outer function. And that'll create a closure. Let's go ahead and save and run this. Okay, now notice that we don't get anything, and that's actually expected. So, I'm going to go Control +Shift +I. This allows me to get to the Chrome Developer Tools. And you'll notice I have two JavaScript errors here. And it says that, "no method myNestedFunc." And what we've done here is because we've encapsulated this function inside of here, it's kind of a private type of function at this point. So what I'm going to do is I'm going to return and add a return keyword right here, and I'm going to return something called an object literal. Now it's going to look like a JSON object, if you've ever worked with JSON. You have name value pairs. But officially, this is called an object literal, and that's because we're going to have an object we're going to add in here. I'm just going to call it foo to keep it simple. We'll separate it with a colon, and then we'll put that we would like it to call this function. Now what I'm just done there with this object literal, which goes right there, is this is what the external caller will call. They'll call myClosure2, whatever the object is, dot foo, and it will basically forward the call up to here. Now you're going to see a little later in the course, this is going to be very, very similar to what we call the revealing module pattern. So we'll come back to that a little bit later. So now let's come up to here and, instead of myNestedFunc, let's call it foo. And now that we have that return, what'll happen is this will return a reference to my inner function. And so now we have a closure created because of this. And we have a way to get to this function. So let's go ahead and run it. And we should see the two values, and they should always be the same because this object, when it calls the function, we're creating that closure, and the date object is being preserved in memory. So again, this is just like a class, which is encapsulating my variable and my function, a little bit different of course, but this is how we can simulate it with JavaScript. So that's an example of another type of way we can work with closures, and this is going to be very much along the lines of what you're going to see in the remaining modules of this course as I show some of the different patterns.
Defining Variables
To wrap up this module, I'm going to briefly talk about different ways of defining variables. Now most of us are used to defining variables this way. You put a var. You put the variable name and then possibly assign it a value, followed up with a semicolon. And then if you have another variable, you do the same thing over, and kind of repeat and rinse every time. Well, there is another option for defining variables where you don't have to put the var keyword every time. And you'll see this in some of the samples coming up, which is why I wanted to cover it here. An alternative way to define variables is this way. We could define the var keyword once, define the variable, assign it, and then put a comma, and then anything that follows is just a new variable. It's like we put the var keyword right at the front. And this is definitely something you'll see in different patterns. People do it differently for sure. Some people prefer this top way. I prefer this bottom way now. And it just simply saves you a little bit of typing, makes the file a little bit cleaner once you get used to this pattern I think of defining variables. Let me show you how we can convert the closure example shown earlier to use this kind of comma technique with variables.
Defining Variables Demo
There're two different techniques you can use when defining variables, and I'm showing the more common one here in this myClosure2. We're using the var keyword, and then we're defining two different variable names and simply giving them values followed by a semicolon. In the case of myNestedFunc, we're assigning an anonymous function, and we give it a semicolon. Now that way works absolutely fine, nothing wrong with it at all. There're certain tools, though, especially as you start working with the different patterns we'll go into, that may give you some little warnings when you do variables this way. One of those is called JSLint. It'll prefer this. Alright, now I switched over to this way after having a discussion with my good buddy, John Papa. He kind of preferred this way. I preferred the other. And after discussing, I decided, yeah, you know, I do like this better. A couple reasons. Number one: Some of these tools don't give any warnings as you try to validate your JavaScript code, such as JSLint. But, number two: Once you get used to this way, I actually think it keeps things a little more clean. You don't have var littered all throughout your file. Now some people like this; some people don't. It really doesn't matter from a performance perspective. It really comes down to personal preference and if you really get bothered by some of these warnings other tools will throw at you. What I would do if I had multiples is something like this. If I had myVar equals 5 comma, and I could just keep listing variables and keep putting commas. And by lining them up, it keeps it pretty easy, makes it easy for you to know that these are all variables. But you could do it the other way as well. I'll leave that up to you, but that's an example of both ways you might see for defining variables in JavaScript files.
Summary
In summary, function spaghetti code can lead to some bad side effects, especially if you're merging in code from different team members or some third-party script libraries with your code. We don't want variables having naming conflicts or functions. Now closures can come to the rescue to provide some encapsulation. And I showed a demonstration of how we can use a nested function to reference a variable in an outer function and make that variable stick around as long as the outer function is in scope. Showed a couple techniques for doing that. And then, finally, we looked at two simple techniques for defining variables. You can pick either one. It really doesn't matter. But in the samples coming up, I'll use the technique that leverages the comma. So that's wrap on this first module on working with JavaScript patterns.
Prototype Pattern
Introduction
Several different patterns exist for structuring JavaScript code to make it reusable, maintainable, and help it avoid naming conflicts. The first one we're going to talk about here is the prototype pattern. Now prototyping is a feature in the JavaScript language, and this particular pattern is going to leverage prototyping functionality. So the agenda is as follows. We're going to start off by talking about what is the prototype pattern as far as pros and cons and why you might want to consider it in some situations and not in others. From there, we'll take a look at how to structure your JavaScript code and actually use this pattern and apply it. And you'll see there're two parts to this--a constructor and a prototype section. And then, finally, I'll walk through a demonstration of a couple of ways you can use the prototype pattern to structure JavaScript code. So let's jump right in to the pros and cons.
Prototype Pattern Pros and Cons
There're several different types of patterns you can follow to structure your JavaScript code, and each of those has its own set of pros and cons of course. And the prototype pattern's no exception. Now it has a lot of different pros going for it, though, that we'll talk about here, including the fact that prototyping is native to JavaScript. Now, if you're new to prototyping, it allows you to extend an existing object and add new functionality or even override functionality that the object may expose. So because it's built in, there're some nice benefits that we'll talk about here in just a moment. Now, by using this pattern, you can modularize your code, much like I showed with the closures in the previous module of the course. And by modularizing or encapsulating your functions and your variables, we can avoid some of the naming collisions you might run into. We can definitely make our code reusable, and we can set ourselves up for easier maintenance down the road as this code needs to mature and change over time. Now by taking variables and functions out of the global namespace, you won't have the problem I showed in the first module where if you have two functions named the same, and they're in the global scope of the JavaScript, then it's kind of a hit or miss as to which one is going to get called based on the order of the scripts getting loaded. Definitely not a problem you want to have to deal with. One of the main benefits, though, of this pattern that I'll show is that the functions are actually loaded up into memory once, so if you define 50 functions using this pattern, those 50 functions will be loaded up in the memory one time. So if you create let's say a hundred objects, they'll all share those same 50 functions in memory. It won't create a duplicate copy of each function. Now, normally, you'd be up to a lot more than that in memory if you had a hundred times say 50 functions, you're up at 5,000 functions now across all the objects. That's not the case with the prototype pattern. Because prototyping is used every time a function is added, that function gets created in memory one time. And if you create 50 new objects, 100 new objects, it doesn't matter, they're all going to tie into those same functions. Now, what's really nice about prototyping, especially if you come from an object-oriented type background where you're used to being able to override methods for instance, is that prototyping can be used to override different functions you might have in an object, and that's actually a big deal. The prototyping pattern plays in very nicely in situations where, for instance, you might build a library, and you know other people are going to use your library, but they might want to override parts of that library, and you don't want them to have to go into your source code to do it. Well, by using this pattern, you could actually allow them to do that very easily. Now, it's not all roses. This pattern does use a keyword in JavaScript called 'this' fairly frequently, and so some people might call this the 'this' pattern because it does use 'this' quite often. But it's something, once you get used to it, it's not too big of a deal. And it does have two parts, so you don't have just one piece of code like you traditionally have with a class or even in the closures demos I showed earlier, kind of everything was compartmentalized in a wrapper function. With the prototype pattern, you're going to have two parts to it, which I'll show you next, and that is going to be the constructor--and this will be where you typically define your variables--and then you'll have a separate section, normally right below that, that's going to be your function prototypes. So, we're going to be looking at that in the next section. So, that's some of the pros and cons of the prototype pattern.
Prototype Pattern Structure
Now that you've seen some of the pros and cons associated with the prototype pattern, let's take a look at how the code looks and the general structure that you'll follow for this pattern. Now, what's nice about all these patterns that I'll show you in this course is that once you get the general pattern down, you can apply it to virtually any object out there, whether it's a car object, an invoice, a calculator like I'm going to show, or something else. In the case of the prototype pattern, the way it works is you first have to define your object and associate it with a constructor. Now the way we do that is you simply say the name of the object, and then you follow that with a function. Now any parameters that you want to initialize that object with can be passed in through this constructor here. So you see I'm passing in an eq parameter, and then using that eq parameter to locate a DOM element that has that ID, and then associating that to the eqCtl. Now, the eqCtl parameter that you see there, you'll notice that we're prefixing it with the 'this' keyword, and I mentioned this in the previous section that you'll see 'this' used fairly frequently with this pattern. Now the reason for that is when 'this' is called, when Calculator is invoked and there's a new instance created, we want to associate this variable with that instance, and we do this by saying this.eqCtl and then assigning it to the value passed in up here in the constructor. So that's kind of the first section is we have this anonymous function, which inside of it will have all our variables. And if you had 50 variables, you'd have, of course, 50 of these lines right here. Now the next part is we need the actual functions. Now, there're a couple of ways to do this, but this particular pattern is going to go in, and we're going to use the prototype keyword, and this is what I mentioned earlier, is available directly in the JavaScript language. This allows you to add functionality or extend it on objects. So Calculator has already been defined and associated with a constructor. Now what we're going to do is define the different functions that we want the Calculator object to have. Now I just have one simple one here, which I'm going to call add, and you'll notice I'm actually using an object literal here. Here's the start of it. Here's the end of it, and then here's the name, and then the value, of course, goes from here down to here. Now I only have one in this example. When I get to the demos here in just a moment, I'll show you some others. But in this case, the add function is going to take an X and a Y. We'll simply add those together, and then we're going to assign the value to the eqCtl that was passed or assigned up in the constructor area. Notice again the use of 'this'. Now this is a little bit tricky, because if you're calling it directly from the object, 'this' represents the object, but if this function calls another function, the context of 'this' can change to the caller. So in this example here, because add would be called directly from the Calculator object itself, 'this' would represent this object, which would be the Calculator object. So it's not a problem, but as we get into different patterns, I'll show you where it can be a little bit tricky, and I'll give you a couple of workarounds for working with the 'this' keyword. So that's how you would define a prototype pattern with JavaScript for a Calculator object. Now this is a very simple example. I have a much more robust one coming up that I'll get to in the demos. Now, how would you actually call it? Well, see that's the good thing with these patterns. Instead of just calling a function directly, we can actually new-up an instance of this Calculator, call the constructor, and then pass in a different value to it. From there, we can use the object instance to call into this add function that's defined within the prototype. So this is the basic pattern that you'll follow, and it would look like this. So you notice we have a new calc object, we create a new Calculator, we pass in the target. This is where the output of the add function will be written to, the DOM element. And then we simply say calc.add, and in this case, we pass 2 plus 2. And by doing this, you'll notice that, number one, it looks very kind of modularized or encapsulated, it looks like traditional programming where you create a new instance and you work with it. It's going to be a lot easier to maintain. You'll typically keep this in one file. And so in that one file, you'll have all your Calculator functionality. And then we also are now avoiding the global scope of JavaScript. The add and the variables that you see in here, they're actually within the Calculator. They're encapsulated. Therefore, they're not going to spill over to the global scope. So, now that we've taken a look at the basic structure for the prototype pattern, let's jump into some examples.
Using the Prototype Pattern
The easiest way to get started with any of the patterns that will be shown in this course is to jump right in and actually try them out. So, let's look at a demo of using the prototype pattern and how we can define our own constructor and our own prototype section. Let's start off by taking a look at a more simple example based on what you saw earlier, and then I'll show a little more robust version of that code. So, I'm going to right-click and add in a new file. So, let's go ahead and add a new HTML page. And we'll just call this PrototypeDemo. Okay, and what I'm going to do is just add a div, and we'll give this an ID of equals, and this is going to represent where we'll write our add operation to. And then we'll come up and we'll add a script block, and in that script block, let's go ahead and define a Calculator. So to start, we first have to do the constructor. Now there's a couple of ways to do this. We could do like this, but a convention you'll follow or see followed out there in the internet with JavaScript is if you have an object that needs the new keyword to be used on it, you'll upper case that keyword, and that'll kind of represent that you have to go through the constructor to get to it. Now it's certainly not a convention that you have to follow, but it is something out there that's kind of a giveaway that you need to initialize this object. So, we'll do that by creating a constructor, so we'll do an anonymous function. And inside of here, when 'this' class is instantiated and used, we want to set the control that's going to be called to whatever they have passed us in. So we're going to say eq right there. Now that's going to represent that guy, the name of it, the idea of it I should say. So we'll ultimately pass that in once we use the Calculator. Okay, now, we can't put the actual prototype piece in the same area, so we're going to have to go right below it, and now we say Calculator.prototype, and now we give it an object literal. And we'll do that. Now inside of here, because we gave it an object literal, we simply give it name value pairs, and the value will represent a function, though, so it's actually an object that literally points to in this case a function. And so we're going to do add colon, and now we define our X,Y for our add operation, and then we'll simply return X plus Y. Okay, now, if we do that, it would be up to the caller of this to update the guy right here. So, I'm going to do very similar to the slides, and we're going to just have a value, which is X plus Y. Then we'll come in and say this.eqCtl. And now that we have that, we can say the innerHTML equals the value. We'll kind of break it into two steps. So, that'd be a very simple example of defining with the prototype pattern. Okay, so to use it, we can come on up into our script, and let's do a window.onload. And when this loads, we can fire up a new Calculator. And then I'll just give it eq as the ID that I want to target, and now we can say c.add, and we can pass in, we'll do 2 plus 2. Now that'll automatically call the constructor, then call the add method, and because we're passing into the constructor our parameter here, the add method's automatically going to take care of updating this div down here. And that's about it. That's all you'd have to do. So let me go ahead and view this. And we should see four down below once this fires up, and you can see we do. So it looks like it works. Now that's a pretty simple example, and obviously for very kind of primitive code, that's great and all, but what about for more advanced code? Well, I have a much more advanced example that has a full calculator. Let me go ahead and run it. And this will do several different things that a normal calculator would do, as you would expect. It has a Clear and Plus and all the standard arithmetic operations. So, the script for this is actually located in the Scripts folder under PrototypePattern.js. And you'll see that, although this has a lot more code to it, it does follow the same exact convention that I just walked through. So we have our constructor area, and then we have our prototype area. The constructor in this case, you'll see, takes where we're going to write out the value as well as some other different items. And we also have a lot of different functions you can see in here. Now, as these functions are defined, you'll notice I'm separating each one just like you would in a normal JSON object, even though this is an object literal, with a comma. So, I put the name and then a comma, put the next name, separate it with a colon and put the comma, and so on and so forth. And so here's the standard arithmetic operations right there, but then as they click on different keys, I have several other functions that handle clearing, setting the operator, such as the multiplication, the division, the subtraction, things like that. And when they click on a number, this will be clicked. And then here's the actual calculate function that looks at what's the operator that the user's working with. You'll notice as we call into these different functions, we're doing 'this.' to call into this class's functions because when calculate is called, 'this' would represent the object. We want to then pass that along to setVal, the lastNumber, and all those types of things. And you'll see that lastNumber is defined up here. Now something very important to point out about this pattern that I mentioned earlier. Each one of these functions will only be loaded in the memory once. Now, that means there's no state that's actually tracked inside of the function. All the variables are up in the constructor, and the reason we do that is that way, every time you create a new instance, you get a fresh set of variables. But even if you created a hundred examples or a hundred instances, I should say, of the Calculator, you'd only have one add in memory, so it's very, very efficient on memory. That's kind of key point #1 of this pattern. Key point #2 is because we are using prototyping, it is possible somebody can come in and override some of this different functionality if they wanted. Now with this particular way of structuring, there's a little more code involved there, but it is possible to do that. So that's an example of a more simple type of prototype pattern, just kind of starting out, and a little more involved prototyping pattern. What's nice about it, though, is regardless of if it's involved or simple, you're still going to create an object using kind of a standard way of doing it with the new keyword, and then we can just call into the different functions you expose.
Prototype Pattern Extension Demo
Now that you've see an example of the prototype pattern in action, let's explore a few of the other options it has and one other thing I'm going to throw in, which is called namespaces. Now two big things are available with prototype pattern, two big benefits. Number one I mentioned that regardless of how many Calculator instances I create, there's only going to be one add function up in memory at any given time, and that's why we define the variables up in the constructor area, because those are going to be unique to the instance, whereas the different functions we have are down in the prototype area, and those are not unique to each instance. They're shared. The second big thing I mentioned is that a user of this particular Calculator object could override functionality if they wanted. So for example, if I don't like what the add function does, I don't actually have to come in to the source code and change it. I can override it separately, and that's pretty nice because if I got this off the internet somewhere, and I know new versions are going to come out, I don't really want to go in here and tweak it because then as I get a new version, I'd override my tweaks. Well, fortunately, we can use prototyping for that. So, if I just come up and say Calculator.prototype., and notice add shows up, I can actually override and put my own functionality without ever touching the original source code down here. So, let's just say that we want to do basically the same thing, but for some reason our add actually subtracts just to demo it. And now what's going to happen is when I call Calculator.add and pass 2 and 2, we're going to actually get 0 back and write that out down to our div. So, I've now overridden the functionality without actually touching the source code. So, if you're building libraries, this might be a pattern you might want to explore and consider because now people don't have to go into your library to actually make modifications. They can actually to it outside, even in a separate file if they want. So, if we run this, we should get back 0 now because our override will kick in, and you can see it does work. That's a really nice feature that can come into play with the prototype pattern. Now the final thing I want to talk about is not unique to the prototype pattern, but it's something you might use. This Calculator object, even if it was in a separate file called calculator.js, is going to be placed up in the global scope. Well, it's very possible you might use another script that also has something called Calculator. So what you can do is define your own little wrapper around this or what I'll call a namespace. So, I'm going to create something called my namespace (myNS). And what I'm going to do is say if my namespace (myNS) is already defined, go ahead and use it. So I'm just going to assign it to itself, and the reason you do that is maybe in another script, they already did myNS equals something, and I don't want to override that. So we're going to go ahead and say if it's already defined just to use it. Otherwise, create a new object and assign it. Now this is literally just an empty object. We're going to assign it to this. Now what I can do is I can prefix myNS on the front of Calculator. Now my Calculator is always going to be distinct from somebody else's Calculator object because of this namespace. Of course, now when I want to use it, I'm just going to comment out the override here, but when I want to use it, I'm going to have to say new myNS.Calculator. So if you've worked with namespaces in the .NET world or packages in the Java world or other languages have other features like this, we're basically adding a unique naming container, and we're putting the Calculator inside of that naming container. Now the only time I could have a name conflict now in my code is if somebody else had a myNS and a Calculator, which the odds of that are pretty bad, and if they do, unfortunately, you're going to have to fix that manually. So if we run this, we get basically the same thing. We should get 4 written out, and you can see it works. But now what we've done is we've put this out of---or taken this out of the global scope and into the myNS scope. Now myNS, yes, it is in the global scope, but we can now reuse myNS across all of our objects. So, typically, you might just use your company name, as an example, for this value. So that's an example of what you can do with namespaces and also how you can override with the prototype pattern.
Summary
In this module, you've seen how the prototype pattern can be used to structure JavaScript and provide those three benefits we were after. Number one, we wanted code reuse. We did that with encapsulation making a Calculator object that can be reused across pages or applications. Number two, maintenance should be simplified because we've now structured things in a very standard way. And number three, we learned how to take things out of the global scope so that we don't conflict with other scripts. Now the prototype pattern leverages the prototype functionality that's built into JavaScript and has that benefit of only loading functions up into memory one time, and you can also override functions using the prototype keyword. You saw that it's comprised of a constructor and then a separate section, which is the prototype section. That's really my main knock against it is everything's not encapsulated in one single thing, but, you know, you get over it pretty quick. It does provide those extension capabilities, which is a very powerful feature, especially if you don't want people to have to go into your source code to make modifications directly. So that's an example of how you can get started using the prototype pattern with your JavaScript code.
Module Pattern
Introduction
Another pattern you can use to structure your JavaScript code is called the module pattern. This is a pattern that Douglas Crockford came up with initially, and it's been very popular. It provides some very distinct differences between other patterns, such as the prototype pattern that was covered earlier in this course. So what I'll do is walk you through what is the module pattern and what are some of the pros and cons it has, and I'll specifically compare it to the prototype pattern, because there are some very distinct differences between those two. We'll talk about the module pattern structure, what's the basic code you need to have to get started, and then how do you fill in the blanks from there. And then I'll walk you through a few demonstrations of using the module pattern and explain how it works. So let's go ahead and get started by taking a closer look at what the module pattern offers.
Module Pattern Pros and Cons
So let's jump into a discussion of what the module pattern is and some of the different pros and cons that it offers us as JavaScript developers. So first off, the module pattern does satisfy the three main tenets that I mentioned at the very beginning of the course: It does promote reuse of your JavaScript object, definitely makes it easier to maintain things because everything is going to be structured in a very specific manner, and it takes variables and functions out of the global scope. So that's all good. Now it's very similar to the prototype pattern in that regard. However, it does offer a very distinct advantage over the prototype pattern, and that is the ability to actually define members, variables, and functions as either being private or public. Some people argue this point depending on which background you have. If you come from a Java or C# or VB type background, you'll probably love this feature. If you don't, then some people really don't like this feature, because they view JavaScript as being very open and kind of malleable anyway. So it really depends on your background and what you want to achieve. I personally don't mind the fact that some of my stuff is private, some is public. I only want the public stuff to be called from external callers of my script, but you may not have that opinion. It really depends. So, I'll talk through the pattern, and you can kind of choose if you like it or not. When it comes to exposing these members, it's very simple to do. In fact, when I showed the initial closure example in module one, I showed a brief glimpse of what we're going to do here. So I'll show you that when we get to the demos, but it does make it very easy to have public and private type members. Now that's all great. There are some cons, though, to the pattern. Number one, because we're not going to be using prototyping, any function that you define inside of this JavaScript file, following the module pattern, will get loaded up into memory for each new instance that's created of an object. So if you create 50 new instances and you have one function, you'll have 50 copies of that function in memory. Now, for many apps out there, I really don't think that's going to be a big deal, but if you do find yourself in a scenario where you think that you will be creating an object over and over and over, maybe in a looping type scenario or something, and you're worried about memory, then this is one you might want to watch because it will make a copy of each function up in memory, and that again is because we're not using prototyping. It's also not as easy to extend. With the prototype pattern, I showed a demonstration of it's pretty easy to actually override and extend different functions and things inside of that pattern. With this pattern, because we're not using prototyping, you don't have those extension benefits. Some also complain about debugging because the private members aren't accessible as you're debugging, and oftentimes if you want to tweak things, you have to make a change and then refresh the page. So, if you're used to something such as the Firebug Tool or Chrome Developer Tools or something like that, then you will maybe have to refresh the page as you change a variable. I personally don't think it's a huge deal, but again, it's something that some do complain about. So that's some of the different pros and cons and kind of what the pattern offers. So, if you want the public/private member visibility option, not a bad way to go. If you need extension, though, such as you're writing a library, and you want users to easily be able to extend your library without actually having to touch the source code, this may not be the pattern for you. Now for me when I'm just doing custom maps for customers, and I'm not looking to actually write libraries, not a bad way to go. But there're others that are along the lines of this pattern that we'll talk about coming up, such as the revealing module pattern, so you're going to have some others to choose from. So, now let's go ahead and move on, and we'll take a look at the structure of the module pattern.
Module Pattern Structure
Like all of the patterns that we're talking about in this course, the module pattern also relies on closures. So we have functions nested within other functions. So, here's what the basic structure looks like, and you'll notice that there's a special return statement, and I mentioned earlier that if you look back in module one at one of the closure demos I did, this looks very, very similar to it actually. So in this example, we're going to have an object called Calculator. Now this is going to have to be created itself, so we could use, for instance, the new keyword on it, and that's why it's uppercased. Again, that's a convention you'll see oftentimes that is kind of a giveaway that you have to initialize the object somehow. We're going to assign it to an anonymous function, which ends down here. And then our private members will go inside of this area, and this will be our variables and our functions, and then in the return block here, this is going to return another object literal. So an object literal, again, is going to have a name of something and then you'll associate that either with a value or a function. So in this case, we could put all of our public members inside of the return statement here, inside of the object literal. Anything outside of that, including these guys up here, will be private. Now when I say private, I of course don't mean they're private in the source code. You can always get to them in the code. But external callers won't see those, especially if you work with programs that have code help as you type. You won't see IntelliSense or code help in the little drop-down that pops down as you hit a dot or whatever you're using. So another example is shown here. Here we have a Calculator much like I showed with the prototype pattern, but this time we're using the module pattern. So you'll notice that we have an anonymous function. This is kind of like the constructor, and it takes one particular parameter. We're going to pass that parameter in, and that's going to grab the DOM element and assign it to this variable. Now this variable will be private automatically because it's not in the return statement. Now if we jump down to the return statement, though, you notice we have one single public member, and that is the add function. And the add function does what it says, basically takes two parameters, adds them, and then assigns the value to the inner HTML of the DOM object. So by doing this, if you were to create a new Calculator using this type of technique right here, when you hit calculator dot, and if you try to do calculator.eqCtl and try to get to this variable up here, you actually won't be able to. And that's because the way we're nesting things here, we've made it so that only the things defined in the return object literal will actually be made public. So it's kind of an interesting pattern you can follow that if you're used to the whole public and private methodology may appeal to you. It works out very well. Now there's another pattern we're going to be talking about called the revealing module pattern. It's based on this one, and it's going to change it up a little bit. So I won't go into it now, but it's going to simplify this part down here, make it a little easier to read, at least in my opinion. So that's a look at what the module pattern structure looks like, and the big thing to understand from here is we kind of have three mains parts. We have our constructor. We have our private member area. And then in the return object literal, we have our public members, and that's how the pattern works.
Using the Module Pattern
Now that you've seen the module pattern pros and cons, learned about some of the different features it offers, and seen the overall structure, let's jump into a couple of demos, and I'll show you the module pattern in action. So the first thing I'd like to do is, let's create a new page, and we'll start from scratch. And I'll just do an inline script to keep it really simple. We'll do something very similar to what we did earlier with the prototype pattern. So let's come down, and we'll make an HTML page. We'll just call this ModuleDemo.html. And let me add a script block here. Alright, so inside of this script block, we're going to go ahead and add a window.onload. Normally, I like to use jQuery for this, but since we're just using regular old JavaScript, this will work great. And let's add a div. ID is Output. And this will be where we'll write the result of our calculation again. So I'm going to come down, and normally I'd put this probably in a separate file, maybe call it calculator.js. But to keep it all in one spot to make it easy to see, let's go ahead and add it here, and then I'll show you a more robust example coming up. So the first thing we'll do is create a Calculator, and we'll do that by creating an anonymous function that takes in a parameter, which is going to represent the Output ID, and that'll represent our actual container. So, again, you can think of this as being very analogous--we'll put Similar to a class container. That's really what Calculator is in this example. So this is our container right here. Now anything I put inside of here is going to be private, so let me just add a comment, and we'll say private members, and we'll go ahead and create this, the same thing as we saw earlier, which is just going to do a document.getElementbyId on whatever they pass in, and then that'll be our private member. Now, anything else I put in here, let's say I wanted to come in and maybe add a new function just called foo with an anonymous area of block of code, then I could go in and simply say foo, we'll put a semicolon to end that, that would be a private function now. Now in this example, though, we're going to go in and do very similar to what you saw in the slides, and I'm going to actually add in a return block, and we're going to do an object literal. So, again, an object literal is going to be between these two brackets, and we're going to go ahead and give it the name of our function. Our add will, of course, take two items. And inside of the add, we'll simply grab the value, and we'll assign it to the eqCtl.innerHTML. Alright, and that would be an example of a very, very simple Calculator object that has an add function, and this is going to be public because it's been placed into the object literal that's actually returned out, whereas a client won't be able to get to this guy or any other functions that are outside of this object literal here. Okay, so that would be an example of creating a very simple Calculator using the module pattern. Now, we'll come up, and let's create an instance of our Calculator. And we'll pass in the Output name, or ID, and now we'll say calc.add. And like we saw before in other demos, in this case it will return 4 hopefully, if everything goes well. So you can see I can use the new keyword on this. It works great. I even got, as I do .ad, you notice I get IntelliSense for that because I'm in Visual Studio in this example. And let's go ahead and run this now. And we should get 4 up here where the output would be, and you can see it works great. Now, to show you about the public/private thing. Let's go ahead and maybe after this, let's just do an alert on calc.eqCtl, which will be the DOM element, innerHTML, and let's see what happens here. So, we'll do View in Browser. We get our 4, but notice no alert, so I'm going to do Control +Shift +I, because I'm in Chrome, to get to the Chrome Developer Tools, and you can see we have a JavaScript error. So if I go to the console by clicking this icon here, "Cannot read the property 'innerHTML' of undefined." And the keyword there is undefined. It's not able to get to the eqCtl. So if I click here, it will actually show me the source of this error, and it shows me that, hey, basically, we can't get to this guy. So to kind of further illustrate this, we close this guy and go back, and I'm going to set a breakpoint right here so that we can actually use the console to try to write out some things. Let's go ahead and run this. And we've hit our breakpoint. Come down to the console now, and let's do calc, and you can see it's an object. If we open up that object, look at what we see. Only an add. No eqCtl or anything like that. In fact, if we try calc.eqCtl, it's undefined. It's private. I can't get to it. So, if you like the whole public/private methodology again, as I mentioned earlier, then this is not a bad way to go, especially if you have people that are working with your code that maybe they're not sure what they should be calling, and you just want to make sure they only call the correct stuff, the public stuff. So that's a simple example of getting started. Now I also have a more robust example, and this example will be very similar to what I showed earlier with the prototype pattern, and this is the module pattern but with a kind of full calculator. So down here, I have a div with Calculator, and it just has all the calculator buttons. Now I normally prefer to wire up events. You'll see here externally in script using jQuery or another framework, but I wanted to keep it very simple here. So, basically what happens up top is we create a Calculator, and once that Calculator is created, we pass in two items. In this case, we actually pass in DOM objects. And then we use that Calculator object as they click different buttons to say that, hey, I clicked a number or I clicked on an operator or something else. The actual code behind this is in ModulePattern.js, so let's go ahead and take a look at that real quick. Okay, so this is a more robust example of what you saw me do just a minute ago. We have a Calculator object. It has a constructor. It takes two parameters. When those parameters come in, this is all my private area. Everything you see all the way down to the return, all this represents all my private variables. So we're simply going to take the equals parameter, assign it to this control and this one, and, of course, assign it here. And then everything else you see, including the functions, are private, so I can't say calc.add or calc.subtract in this example. I can only call what's in the object literal. So, if we look at the object literal, you'll see that we have a numberClick with an embedded function, an anonymous function. We have a setOperator. And we have a clearNumbers. Now to demonstrate the visibility of all this, let's go ahead and grab clearNumbers, and we'll move this last comma here. I'm going to move it outside with these other functions that are private, and we'll need to change the syntax just a little bit from a colon to an equals. Okay, so we need to add one more comma there, and now we're ready to go. So, this is now a private member. Obviously, we can't get to it. Or we shouldn't be able to get to it. So let's save that and now run the page. And when I run the page, you'll see, let's refresh to make sure we have it, we'll do 9 times 9. That all works, but let's hit clear now, and you'll see it doesn't work. I'm going to hit Control +Shift +I, and we have, because I clicked it several times, several JavaScript errors you can see in the corner. So, let's go to the console now, and on the console, it "has no method 'clearNumbers'". So, if we just do a calc, we can get to our object, and you can actually see the members that are exposed--numberClick, setOperator, very similar to the more simple demo I showed earlier. So, you can see that it truly has made it a kind of private variable or private function in this case. So, let's go ahead and fix that back up. So, we'll grab clearNumbers, move it back out of the private members, back down, and then it will obviously work. And that's an example of what the module pattern offers that you really can't do with patterns such as the prototype pattern. Let's go ahead and run it one more time to make sure it works. And we'll talk about one final thing here. And you can see it works. So, as I type, it can clear. Now keep in mind that if I were to create 50 or 100 or 1000 instances of a Calculator, and a Calculator would probably be a bad example of doing that, but you might have some other type of JavaScript object you need to create a lot of them, then all these different functions are going to be duplicated in memory, unlike the prototype pattern. Also, it's not easy to extend these. I can't use prototyping to simply go in and take over control of these, at least like I showed you in the prototype example where it was very simple. I actually have to go in this case into the source code and make some tweaks if I want. So, overriding and extension is not nearly as easy as it is with the prototype pattern. Now in the case of a calculator, that may not be a big deal. It is what it is, and people use it or they don't. And if they don't want to, they can tweak it. But that is a limitation that you need to be aware of with this particular pattern. So, that's an example of how you can actually work with the module pattern and use it to provide the benefits we've been talking about throughout the course--reuse, easier maintenance, and we take everything out of the global scope. Now keep in mind this Calculator object up here is going to be in the global scope, so I showed in the prototype section how we can fix that. I'm going to create my namespace (myNS), and what I could do is come in and say myNS, and that's going to be our namespace if you will, .Calculator. Now I'd have to do the same thing when I go to create the object here as well. But this will make it so that this particular object is now in this namespace. If the namespace is already defined elsewhere in another script, I'll simply take that and assign it. if it's not, that's what the 'or' does here, then I'll go ahead and create an empty holder, container for this. So you could also take it to this whole other level to make sure that you don't even have naming conflicts even amongst your Calculator object, even though all the members of it are safe. So that's an example of the module pattern and how you can use it to provide public and private type of members inside of your JavaScript code.
Summary
To wrap up, you've seen how the module pattern can be used to provide encapsulation of your JavaScript code so that we have better reuse, easier maintenance, and we take all of our variables and functions out of the global scope. But we've also seen how the module pattern can be used to actually provide public or private visibility for our members, and that makes it nice in situations where you don't want callers to be able to call specific functions or get to certain variables. Now keep in mind that each instance you create using this pattern of an object does duplicate the different functions that you define up in memory, unlike the prototype pattern, and that extending your different functions is going to be a lot more difficult. It's really not geared towards extension. If I were to build a library, this is probably not a pattern I'd go with because it doesn't provide a nice extension point, especially compared to something like the prototype pattern. However, if I just simply want to make objects that others will use, and I don't expect that they're going to need to override anything, then this provides a nice way to get started. So in the next one, we're going to talk about a different pattern that's very similar, though, to this one called the revealing module pattern. So the concepts you've learned here will be directly applicable, and that will be what we'll cover in the next module.
Revealing Module Pattern
Introduction
In this module, we're going to take a look at the revealing module pattern, one of my personal favorites, and one I've used a lot in different web applications out there. So to start off, we're going to jump into what is this pattern, how does it differ from the module pattern, and what are some of the pros and cons? And you'll find that it's actually very similar to the module pattern. In fact, it has all kind of the same pros and cons associated with it. We'll then go into the overall structure of this pattern. And then from there, I'll show you several demos again of how we can use this pattern, and I'll show you a couple of ways you can use this pattern. So, let's go ahead and get started with what the pattern is and some of the pros and cons that it offers us.
Revealing Module Pros and Cons
In this section, we're going to talk about the revealing module pattern, and I'm going to compare how it kind of matches up with the module pattern, which was covered earlier in this course, and you'll see they're very, very similar actually. In fact, really the only difference is the way that things are exposed publicly, and you'll see this pattern used a little bit differently as far as creating objects. So, I'll cover all of that as we jump forward here. So, as I mentioned, it is very similar to the module pattern. It provides modularization of your code. It satisfies the three main tenets that I kind of keep harping on in this course, and that's reuse, better maintenance, and we don't want naming conflicts. We want to take variables and functions out of the global namespace. And it also allows you to provide public versus private members, whether it's variables or functions. Now the main difference, though, between this pattern is that the way you expose public members is a little bit cleaner. With the module pattern, you actually have an object literal, and the entire function that's publicly exposed is embedded in the return statement for the object literal. With this pattern, we're actually going to define it separately, and I think it actually is a lot easier to read, a little bit easier to maintain I would think as well. Now the other main difference is a lot of times you'll see this pattern used with a singleton. In other words, there'll be one object in memory at any given time, and you can actually do that with these other patterns as well, but it's something that you'll definitely see as you go research on the internet this pattern and look at some of the sample codes. So, I'll kind of show you both ways in this particular module. I'll show you the singleton approach and the just instance approach where you can create multiple instances if you'd like. Now, like the module pattern, it does have some cons. First off, any function that you define inside of your encapsulation container will actually be duplicated if you create a new instance. Now, if you're just doing a singleton, a single object that gets created, you'll be fine there, of course, because you only have one. But it is something to keep in mind. It's not something that's scared me away from the pattern personally because I haven't had an app where I had to create maybe thousands or even hundreds of thousands of objects of a similar type and worry about duplicating those functions in memory. But it would be something to be concerned about if you are creating a huge number of the same object in memory. It's not easy to extend, so this is really not a good pattern to go with if you need users of your code to easily be able to tack on new functionality and extend existing functions and things like that. So, that's really not the goal of the pattern, though. This is truly an encapsulation pattern. And just like the module pattern, some do complain about debugging because it's not as easy to get to the private members. And as I mentioned in the previous module on the module pattern, it's really I don't think that big of a deal to deal with. Yes, you do have to refresh your page maybe a little more often versus just changing things right there when you're debugging, but it's kind of up to you to decide if it's a blocking feature or not. So now that we've talked about what this provides as far as pros and cons, let's go ahead and move on, and we'll take a look at the structure.
Revealing Module Structure
The overall structure of the revealing module pattern is very similar to what you've already seen with the module pattern. And there's a good reason for that. When the module pattern first came out, people liked the fact that you could kind of divide up your private and your public members, but some people weren't super fond of how you defined your public members, because you define those in the object literal. But with the revealing module pattern, it makes it a little bit cleaner. I personally like it better, and it makes it easier to read, definitely easier for maintenance I think. So, here's an example of kind of the standard format and structure for the revealing module pattern, and you'll notice it's almost identical to what we saw with the module pattern. There're a couple of key differences, though, and I'll point out even more of these in the next couple of slides here. First off, you'll notice the name is lowercase. Now, you don't have to do it this way with the revealing module pattern, but the reason it's lowercase is you don't have to use the new keyword on it. Again, it's kind of a giveaway, something I've mentioned a couple of times throughout this course. You'll see this is a self-calling function. We're actually calling directly into the function, and we're not passing anything in this particular example. But because it's self-calling, and the user wouldn't have to use the new keyword to instantiate it, we're going to use the lowercase. Now, that is certainly just a convention some people follow. You don't have to go with that, but it is something you might come across out there on the internet as you research this and other patterns. Now, really the main big difference, though, between this pattern and the module pattern, is shown here. With the module pattern, we actually go in and we add the function and all the code for the function, the brackets and the body and everything, right into the object literal that you see there. Now in this case, the external caller is going to call calculator.add, and internally what it's going to do is forward that to doAdd, which you'll see is up here. So with this pattern, you can actually define all your private members all together, and that includes all your variables, all your functions, everything like that. Then the public ones, you simply give them a name, give them an alias. Now I normally name them the same. In this particular example, I wanted to show that you don't have to. But this could be doAdd forwards to doAdd if we wanted. It could be foo forwards to doAdd. And that'll forward up to here. Now what's nice about that is now your return section, your object literal, that gets returned to the caller of this particular script code only sees the public members that you expose in the return. Now that's identical to the module pattern, but I think it's a lot cleaner now because now you just simply match up the names. You can see here also it's self-invoking. So, right as this function's parsed, it'll then be invoked immediately. And we're going to pass in eq control up into the parameter, which is then used for this variable here. So, that's really the main difference. Now, because it is self-invoking, you would simply say calculator.add, and then you would pass in your two parameters that you want to pass in here. Now, if we compare that really quickly again to the module pattern, here's an example of that one, and you can see that we still have an add, but the function is actually embedded directly in the object literal, which starts here and ends here, and then we return that. So, it gets a little messier. I personally think it's a lot harder to read this way. But it is something you can certainly do. I personally think this is a lot cleaner, though. Definitely easier from a maintenance standpoint. From the standpoint of encapsulation, keeping things out of the global scope, the global namespace if you will, both patterns are equal. From the standpoint of reuse, both patterns are equal. But when it comes to maintenance, I just think this one's more clean, but that's kind of up to you to decide. So that's what the revealing module pattern structure looks like, and that's kind of how it's compared to what you would do for the module pattern that we looked at earlier in this course. Now you can also use this type of syntax with the revealing module pattern. Simply remove the parentheses. And I'll demonstrate that coming up in the demos that follow. Let's go ahead and move on. We'll take a look at some sample code.
Using the Revealing Module Pattern
Now that you've seen what the revealing module pattern offers and the overall structure of the code, let's take a look at a few demonstrations of how it can be used in different scenarios. Let's get started by creating a new HTML page, and I'm just going to call this RevealingModuleDemo.html, and we'll come in and add a script block. Now I'm going to have an Output area as you've seen in some of the other demos. We'll write some Output data too. And what I'd like to do is because I'm going to do the self-invoking revealing module pattern demo, I need to make sure that the DOM, at least this DOM element called Output, is loaded before my script actually runs. You'll see what I mean. So, what I could do is I could come in and put my script right up here inside of the onload, but if it was a separate script, that's not going to work out. So, what I'm going to do instead is I'm just going to put a script block right under this, and although I could load a separate script, we're just going to do it inline. We'll kind of pretend that it might actually call calculator.js or something like that. This is where I'm going to demonstrate the code that you've already seen up to this point for the revealing module pattern. So, we'll go ahead and make a calculator, and I'm going to pass in one parameter. And there is our wrapper. So, if you come from a class background, again, this would be very analogous to a class in this particular case. Now I'm going to come in and make a variable, and it's going to reference the DOM element above, so we'll pass in eq. And then I'm going to make my object literal, and so this will represent my private members, and this will represent my public members. Okay, now instead of actually putting all the function code inside of the return block here, the object literal, we're going to go ahead and make it a little cleaner by following the revealing module pattern, which basically says let's come in and let's make our functions up top. So what I'm going to do is go ahead and put a comma there, move that over, and we'll have---let's do two of them. We'll do an add and a subtract. And then for the add, we'll just simply grab this and update the innerHTML to X plus Y. And I'd do the same thing here normally, but I don't want them---they'll run so fast you wouldn't see the difference between the two, so let's just do an alert because I'm going to call both in succession, and we'll do X minus Y so we can see it just works. Okay, now if I were to come in and run this as is, I would have to new-up the instance because we're not self-invoking. So, what I'm going to do is change that to be more of a singleton where we'll have one instance of the calculator in memory at any given time. And we'll do that by simply passing in the ID we want, which is this one, and we'll self-invoke the function. So when the script parses or gets parsed down to here, it'll then self-invoke the function, pass this up in, and then it'll be used in the script. Now if we were to come into here in the window load and now say calculator., and call add, we wouldn't be able to call it. So I can go ahead and add this code, but it's not going to do anything at this point because we haven't returned anything in the object literal. So we'd get a script error if we tried to run this. So, what I'm going to do is simply say, "What do we want the alias of the internal function to be?" So, let's say it was doAdd, but I want it to call add, and we might have doSubtract, which calls subtract. Now I'm providing an alias that the external caller of my script would use, but internally it's going to forward it to these guys. Now I normally don't do that. I normally name them as is. So we'll call them like that especially since I already have it set up that way. Okay, so basically what'll happen is once this guy gets parsed, our script then gets parsed, it self-invokes the function. That sets up all these internal members. We expose both of these functions publicly, and now we're ready to go, and we can just call this object directly without having to new it up. It's a singleton. So let's go ahead and View in Browser, and we should get an alert, and then we'll get the 4. Now it looks like we didn't get an alert, so let's take a look at our script error, has no method 'subtract,' which probably means I have a typo down here, and I do--'substract.' Let's go ahead and change that. We'll run it one more time. And there we go. We get that, and we get that, so we get our add and our subtract called. So you can see that it really does matter obviously what you name these. Again, if I were to call this doAdd and doSubtract, then down here we would need to call them this way as well. Otherwise, the client would never see it. But now it kind of lets you name things like you want the public API to be called, and it allows you to name things whatever you want internally, which can be useful in some scenarios. So that's an example of getting started with the revealing module pattern. Now let's look at some more involved demos of using the pattern. So I also have an example of the calculator. Now we've seen this same calculator for the prototype pattern and the module pattern. Now we're going to see it again, but now it's using the revealing module pattern. So the script is here, and you'll notice this actually follows the same type of thing we've been working with. You'll notice it's lowercase. If I come down to the bottom, you'll see it's self-invoking. That's why we're going to go ahead and go with lowercase there, so it's kind of obvious to the user that you don't have to use the new keyword. Other than that, it's identical. There's just more code. All of our private variables. We have a lot of different functions, you can see here, that perform the calculator functionality are defined. You'll see all those in here. And then as I scroll to the very bottom, you can see that we're only exposing four different members from above as public members for this calculator functionality. So, that's what I really, really like about this pattern is that it's very, very simple to only expose what you want if you're into the whole public and private member type of thing. And this makes it very easy to work with that. In fact, it's kind of nice because there've been times in real apps where I've actually forgot to list something here, and then instantly I'll kind of say, oh yeah, I didn't expose that publicly. So, by default, everything is kind of private, much as it would be in traditional object-oriented languages. So, if we run this, it'll just run the same calculator you've seen a couple of times but now using the revealing module pattern. And you can see it works as you would expect. So, now we've satisfied those three main tenets I keep talking about in this course, which is we now have reuse because we can reuse this calculator object, we have excellent encapsulation of our data for maintenance, these functions are only unique and only used for this calculator object, and we've taken everything out of the global scope except for this guy. So the final one I want to show that uses this pattern is script that's related to the HTML5 canvas. So I have a Chart.html, and you'll notice I'm using jQuery in this example to detect when the DOM is actually loaded. And we're going to actually create a new instance of something called CanvasChart. Now CanvasChart is right here. You'll notice it's uppercase. And let's go look at the very bottom of it. And that's because this is not self-invoking. Now you can see it is the revealing module pattern. We don't have any functions in here as with the module pattern. We're not using the prototype keyword, so it's definitely not the prototype pattern. And all my functions are now referencing others. Now this one has quite a bit of code in it and quite a few other functions. Now, I won't be able to go through the canvas code, but if you are interested, there're other HTML5 courses on Pluralsight.com if you want to get more into what I'll show you here with the canvas API. So, you can see all of our private members. We have quite a few variables up top, several different functions that handle the rendering of our canvas, and then we only expose two of those, though, to external clients-- renderType and a render. So back here in Chart.html, once this DOM is loaded, I'm going to go ahead and create a new instance. Now this is not a singleton because I might want multiple charts on one page. Not a problem. We just take off the self-invoking parentheses at the end of the revealing module code, and that lets us new it up. So what this does is you can pass in some information about the chart, such as what's the title?, the X and Y labels, font information, what do I want to render?, do I want lines?, do I want points? And in this case, I'm doing both. And then this is the actual data that the chart is going to plot, so this represents U.S. population data at different years and then shows in millions how many people lived then. Now what we're going to do from there is we're going to pass the name of our canvas, which you'll see is right here, the ID I should say of the canvas, into the render function, along with all of this data definition code, which is just a JSON object you can see here going down to here. Now what this will do is render a nice little chart without any plugins right here in the page. And there's an example of using the canvas API. Although this is a little more fancy as far as the code, especially compared to the calculator, I'm still able to leverage the same revealing module pattern structure that we've talked about in several of the different demos up to this point. So that's an example of different ways in which the revealing module pattern can be used, and I hope that gets you started thinking about how you can use it in your applications.
Summary
So in sum, the revealing module pattern provides a great way to encapsulate variables and functions into a reusable object, and it allows you to along the way expose different members as either being public or private. So in that regard, it's very, very similar to the module pattern. However, it does provide, at least in my opinion, a cleaner way to expose your public members as compared to the module pattern we talked about. And one of the downsides of this pattern is, again, if you want to work with, say, libraries and you do expect people to be able to extend existing functionality, you don't want them to have to tweak your source code, then this is not as flexible as the prototype pattern that we talked about earlier in the course. So it's important to keep that in mind. However, in scenarios where you're simply writing functionality that's very custom for a given application, I think it can definitely be a pattern that you can jump into and use effectively to promote reuse, to simplify your maintenance, and to make sure that you keep all your functions and variables out of the global scope. And that's a wrap on using the revealing module pattern.
Revealing Prototype Pattern
Introduction
In this module, we're going to talk about the revealing prototype pattern, another one of my favorites because it combines two of the other patterns we've already talked about in this course and merges together the best parts, so you get a lot of extensibility features and some other benefits that we'll talk about. So, in this module, we're going to start off, as we have in the others, talking about what is the pattern, why would I want to use it, and what are the pros and cons of this pattern? From there, we'll go into what's the structure of the pattern look like, and I'll show you a simple example of getting started writing JavaScript code that uses this pattern. And then from there, we'll jump into some demos of showing the pattern in use. And I'll show a couple of different ways that can be used and even how it can be extended. So, let's get started by talking about some of the different pros and cons and what this particular pattern offers us as JavaScript developers. The revealing prototype pattern really
Revealing Prototype Pros and Cons
The revealing prototype pattern really brings a lot to the table, and as I mentioned offers really the best of two of the other patterns that we've already talked about and kind of merges those together. So, it really does have a lot of pros going for it. There's really not a lot of downside. There are a few things that I'll mention but, overall, this can be a good pattern to go with whether you're building libraries that others will use or you're just building code that's very custom for one particular application. So, the revealing prototype pattern combines the revealing module pattern with the prototype pattern, so we get the strengths of both of those. First off, we get the encapsulation. We can modularize our JavaScript code instead of just having function spaghetti code all over the place. By doing that, of course, we take the variables and the functions out of the global scope, and we put those inside of the constraint of our encapsulated container. And then what's really nice is because it takes features from the revealing module pattern, we can also expose only public members, if we'd like to go that route, and then hide the private members. That way callers only see what they're supposed to see, and everything else we kind of hide from them. Now as I've mentioned in some of the other modules in this course, that's a subject that it really depends on your background and the way you like to approach JavaScript. Some people really don't believe in the hiding of different functions or variables from the users of your code while others kind of like the more object-oriented approach where you do have some visibility and some things are private and some things are public. I personally come in from more of the object-oriented background. I kind of like that idea, simply because it makes it easy in tools where you get IntelliSense or code help that the user of your code would only see what they're supposed to see and everything else they wouldn't. So it doesn't get cluttered with different functions or variables that they really shouldn't be getting to anyway. But, again, that's a very subjective view, and it really depends on what you want and what you like. Now because we are going to use features of the prototype pattern as well in the revealing prototype pattern, the functions that we're going to define are only going to be loaded up into memory one time. So even if you create 50 objects, if you add one function defined in your pattern, it's only going to be loaded up into memory one time and shared across all of these. It makes it very, very flexible as far as memory goes and very efficient of course. Now also because it uses prototyping, it is very extensible. So users can tack on new functionality or even extend or modify existing functionality by using prototyping, and that's a really, really nice feature that makes it so the user doesn't actually have to go into your source code of your particular JavaScript to make any changes. And as I mentioned in other modules in the course, the reason that's a big deal is if you do write a library and, let's say you're on version 1, the user goes in and makes a few tweaks in the source code, but now you roll out version 1.1, well now they have to kind of track how to merge their changes into the new version, and they have to make sure there're no new conflicts that occur as a result of that merge, so it can be a little bit tricky. But because of prototyping, we can actually extend and even add new functionality without actually touching the original source code, and I'll show a demonstration of that coming up. Now it's not all perfect. The pattern does use the 'this' keyword, and it can be a little bit tricky, but I'm going to show you a few tips to work around that that are kind of nice that we'll talk through. And the constructor definition is separate from where all your functions are defined, your prototype definition, and some people view that as a knock on the pattern because it's not all in one massive container, kind of like you do with the module or the revealing module pattern. I don't think it's a big deal. It's going to be in one file anyway, but it is something that is a little bit different than the module or the revealing module pattern, as far as that goes. So, now that we've talked about what the pattern offers, let's go ahead and look at the structure of the code.
Revealing Prototype Structure
The revealing prototype pattern pulls from the revealing module pattern and the prototype pattern, as mentioned earlier, so several aspects of those patterns are going to be used in the code and the structure of the code. So, a simple example of getting started with the pattern is shown here. And this very first example looks very much like what we saw with the prototype pattern, but there's one key distinct difference, and I'll kind of tie that in at the end of this section. So, first off, we have a constructor area up at the top. We have a Calculator. And you can see it has a constructor that takes one particular value. All of our variables would then be defined in here. Now when you define those variables, you will need to use the 'this' keyword to do that, so I'll show an example of that actually coming up. Now once you've defined your constructor, then you can define the actual functions. Now those are going to be moved into the prototype section, though, so you'll notice it is separate from our constructor area. But this is very different than the definition we saw earlier with the prototype pattern because instead of assigning an object literal to the prototype, we're actually assigning an anonymous function, and then we're self-invoking the function. So, really, this is following very much along the lines of the revealing module pattern, and so this is how we're going to get the public/private capability where we can mark some things as private and mark some things as public as needed but still be able to prototype because we want to build a prototype. Prototyping is good for extensibility and adding new features onto existing code. So, in this example, we assign the prototype to a function. That function is immediately invoked. Now this does not create a singleton in this example because our constructor is separate, so it is different from the revealing module pattern in that regard. You're still going to have to new-up the object to use this calculator. What this will do, though, is all these functions that'll be defined here will be made available instantly through the prototype. Then once we create a new instance, we'll be able to get to those functions. So I'll show a demonstration at the end of this particular module. Now, where does the revealing module part tie in? Well, you can see it right here. What we're going to do is inside our object literal, any functions that are defined up here, we're simply going to reference here. So, we're going to do it in exactly the same way as we saw in the revealing module part of this course, and I'll show you another example of that again coming up as well. So, we really have the best of both patterns. The prototype pattern's being used here, although we're using kind of the revealing module pattern to assign the functions to the prototype, and then the revealing module pattern is obviously used not only for the assignment here but also in the way that we're exposing our public members. So it's a really nice thing to work with, very easy. Now we get the benefits of extensibility and the public/private hiding or showing to the external client our functions if we want. Now here's a more filled in example of the revealing prototype structure, and you'll notice that we have our constructor area. We're passing in a parameter, and then we're assigning that to this variable eq.Ctl. So, we're going to grab the DOM object and assign it. Now the reason we put the variables in here is we don't want to put them in the prototype section because then they'd be shared across everything. So, if we had 50 objects, they'd all share everything, and that would definitely be bad. So, instead, what we're going to do is define all our variables in the constructor area. That way, when we new it up, each new copy of the object gets a fresh of variables. But we'll still be able to share the functions across all objects. They won't maintain any state. All the state will be stored in the variables. So, in this case, you'll notice we have a very simple add function. So, we have add equals an anonymous function, takes our X and Y, does its thing. This is private by default because of the way we've defined the function and assigned it to the prototype. To make it public, we're going to follow the revealing module pattern. And so we're going to say return. In this case, we're going to name it the same. This'll be the alias that the external caller will call, and it's simply going to forward that call to the add function that you see here. It makes it very easy to hide or show the different members, just like the revealing module pattern. Now if you were to compare this again with the actual prototype pattern, especially as you're learning these patterns, it can be a little tricky to remember which is which, the big thing to remember here is the revealing prototype structure really falls along the lines from the prototype equals down the revealing module pattern. Whereas the prototype pattern uses an object literal to assign the functions to a prototype. Here's an example of that. And I'll come back to that. So, here's the prototype structure, and kind of reviewing this, everything up top's the same, but notice down here it's very different. We just have an object literal that starts and ends, and then we define our functions. Whereas, with the revealing prototype pattern, we use very much along the lines of the revealing module pattern. That way, we get the benefits of the public/private if you want that. Now if you don't want that, you probably should just go with the regular old prototype pattern if you'd like. But if you do like that, this is a great way to go. Now you can see an example of actually using this. We simply create a new Calculator object. We pass in our initial constructor parameter, and then we can call the add function because the add function is defined publicly. So that's an example of how to use it and comparing it with the prototype pattern. So, now that we've taken a look at that, let's jump into some examples of how we can use the revealing prototype pattern.
Using the Revealing Prototype Pattern
I'll show a few examples of using the revealing prototype pattern in this section. We'll start off by showing what I just demoed in the previous section and kind of show a very simple example to get started. Then I'll show a more robust calculator example, very similar to what you've seen throughout this course. And then, finally, I'm going to tie in a piece of code that I showed at the very beginning module of this course and show how we can convert that to use the revealing prototype pattern. So let's go ahead and jump in. The first thing I'd like to demonstrate with the revealing prototype pattern is a very simple example that follows what we just saw earlier in the module, a very simple calculator. So, I'm going to go ahead and add an HTML file, and let's call this RevealingPrototypeDemo.html. We'll go ahead and add in the standard script block, and we'll add a little area to capture some Output. Then I'm going to add a window.onload. Okay, so now that we have that in there, we're ready to go. Now, again, I normally like to put this in a separate file, but for these very simple demos I'm showing in all the modules of the course, I'm just going to put everything in one file so you can see it all at once. But we'll pretend it was in calculator.js. So we're going to start off by creating a Calculator, and we're going to create the constructor area, so I'm going to create a function that takes some type of parameter, because I need it in this example, and then we'll end it. So this would be very similar to our constructor. It's the initial thing that's going to be called when we new-up the Calculator. Now the second piece to the revealing prototype pattern is we then take the Calculator, add on the prototype, and now we're going to add our functions. Now the nice thing about using this prototype again, these functions will not be duplicated across instances of the Calculator. They'll be shared, and that's why all state will be stored up in the instance area, the constructor area, whereas all functions will go down in here. So, we're going to follow the revealing module pattern for this one. We're going to self-invoke the function as soon as it's basically parsed, we're going to self-invoke it. And then our private members and our public members can go in here now. And we'll do our public members, to find those, by using an object literal just like that. So the next thing we're going to do is up in the constructor area, this is where all my state should go. You never want to put it down in here because then it would be shared. A prototype is shared, of course, across all the instances, so I want everything to be unique to the constructor area. So, we're going to make a variable similar to what you've seen in other demonstrations in the course. And we'll pass in the eq. And the reason we're doing this is we want the variable to be associated with this instance of the Calculator. And you'll see where this can get a little bit tricky as we move into some more advanced demos here in this section. But for now, just understand that we do need to put 'this.' so that we associate it with this instance of the Calculator. And, again, the reason is down here everything we put in here is going to be shared across all the instances. We don't want this guy to be shared. We want it to be unique to this instance of the Calculator. Okay, so now we're going to come down, and let's add a function called add, and this will do what it says, and then we'll also add one, which we're going to call subtract--and I'm just going to bump this guy over a little bit--and this will be a function that does the same thing but subtracts. Okay. Now what I'm going to put inside of here is just a call to this.eqCtl. Now this is where it's very important. We don't want to just put eqCtl equals or eqCtl innerHTML, is what I'm going to do such as this, X plus Y. And the reason for that--let me go ahead and just bump those over--the reason for that is this is unique to the instance of the object. So, therefore, we need to say 'this.'. The caller of the add function is going to be this object. Okay? And that's what this will represent, and this gets a little bit tricky with JavaScript. It's not like C# or Java where it's very consistent. It actually changes context depending on the caller. So for now, just understand that we need it, and I'll show you another example of where it can get tricky in just a moment here. So, in this example, I'm just going to do an alert mainly because I'm going to call add followed by subtract very quickly, and if we update the div, then you wouldn't see both of them at the same time. So, we'll just do an alert there. So that would represent our two private members at this point. And the only way for somebody to call these is inside of this particular prototype area. Outside, an external caller can't get to them. So, let's expose them publicly. We'll say that they're going to call a function called add, which will forward the call to add, and we can name this whatever we want. If I wanted them to call it foo, then they would call calculator.foo, and that would actually call the add function. But I normally name them the same. We'll do a subtract, and then we're done. So, now we have our constructor with our state, our variables, only one in this example. We have our prototype section, which is very different, though, from the prototype pattern because we're not using an object literal in this example. We're actually coming in and using very much along the lines of the revealing module pattern. So we define an anonymous function, we define our members, and then anything that we want to be public, we go ahead and put inside of this object literal right there. Now let's use it. So, we'll come on up. We'll create a new Calculator, and I'm going to pass in the div ID, which is Output, and then we'll see calc.add and calc.subtract. And we're ready to go. So, very nice pattern to work with because as you'll see in a later demo we'll do in this section, I can also extend this without ever touching the actual source code here. That makes it very, very easy to work with and very flexible as far as extending or changing any of the add or the subtraction stuff that you see in here. So, let's go ahead and try it out. And we should get a message box and then a value. So there's our subtract, and there's our add. And so you can see it did work. So that would be a very simple example of getting started with the revealing prototype pattern. Now let's take a look at a little more advanced example, and you'll see where 'this' gets a little bit tricky. Alright, so I'm going to open up revealing prototype pattern, and let me just run it first. This shows the calculator that, if you've watched the other modules, you've seen. And you can go in and do whatever you'd like, and it calculates and works. The script is here, and you're going to see it follows the exact same pattern we just went through with the simple example, it's just more robust. So, we have a Calculator constructor. In this case, it takes two parameters, and we assign those to these variables. Now this is all our state again that each instance of the Calculator will have. Notice that they all are prefixed with 'this'. Alright, that's going to be very important coming up here. Now moving on down to the prototype section, we follow the anonymous function pattern I just talked about in the previous example. Here're all our private members. So we have an add, a subtract, a multiply, and they simply do the respective functionality. And there're several things in here. We can clear numbers. We can set the operator to a multiplication, division, equals, stuff like that. And then we have the calculate actually takes care of the calculation and does all the work there. Now at the very bottom, you'll notice we self-invoke the function that's assigned to the prototype, and any public members we expose through the object literal using the return. So, you can see in this example, there're only three that are public. And that's all I'll see in the IntelliSense in Visual Studio or other programs that provide that type of help as you type. Alright, now, where this gets a little bit tricky, though, is number one, you do have to put 'this' on all the different variables, and that's not a big deal. It's just something to get used to, and you do it. But, when we call into one of these three functions, such as let's go into setOperator. Let's go find that. Here it is. We pass in newOperator, which is what they clicked, and if it's an equal, if they clicked on the equals, we set the equalsPressed variable, and notice we're doing 'this' because we want this instance. Now why this is so important is, remember that setOperator is shared across all of our different object instances. So even if I create 50 calculators, there's only one setOperator in memory, and that's a good thing. You know, we don't want to have a lot of memory pressure from our JavaScript. But, we need to be able to get to the object instance to get to the variable. Well, that's why we had to use 'this' up in the variables to represent that this variable is associated with the object instance. Now we're getting to that object instance. Okay? And that's why it is very important. Now, here's where it gets tricky, though. When setOperator is called, it'll be called from the Calculator object. In fact, I can show you that down in here. Here's calc.setOperator. 'This' now represents the Calculator object, because the Calculator object was created right here and stored up in this variable so we can reference it. And so it represents the actual Calculator, so no problem there. When we say this.equalsPressed, we know we're on the Calculator object. We know that we have an equalsPressed associated with the Calculator object, so no problems because 'this' represents the actual object. Now where it gets tricky, though, is now we're going to call a function called calculate. Calculate is down here at the bottom, and when we make that call, 'this' now changes context. It doesn't represent this Calculator object any longer. It actually represents the context, which is setOperator, that we're in. So we kind of lose where we're at. Notice that I'm passing in 'this'. Now 'this' at this stage, just like it did here, represents the Calculator instance. That's what we want because we need to be able to get to all the Calculator variables in the calculate function. So, we're going to pass that in, and notice that we take a parameter called thisObj. Now, anytime I want to get to any of those parameters or the variables, I should say, defined in the constructor area, I say thisObj.operator. I can't use 'this'. If I just do this.operator, we'll have a problem because 'this' no longer represents the actual object, it represents the context of who called, which is the, what was that function?, the setOperator right here. So, we've now lost our context. Now there is a way around this. I'm going to show a different demonstration once we wrap up this one, and show a nice little trick you can do in JavaScript that's very important to know. But, this is something that with this particular pattern is very important to kind of comprehend that when a function calls another function, the 'this' keyword changes context. It's no longer the actual object that first called into the original function. It changes. And that's little bit tricky, especially if you're coming from a C# or Java or VB or some other language where 'this' always represents this class. In JavaScript, it can change depending on the caller. That's why I'm passing this in. Now thisObj represents the Calculator object instance, and I can get to the different variables. So a little bit tricky there. Now notice that I do this in quite a few places. Here's a setVal, and on the setVal, you'll notice that not only do I pass the value to set right here, but I also pass the 'this' keyword, and if we go up to setVal here, notice that I accept thisObj, and I'm updating a variable, currNumberCtl, and updating the innerHTML. Well, if I just put 'this', it's not going to work right, because the Calculator object didn't call it, another function did, so it changed context. That's why we're passing the 'this' keyword into here, and then we're going to use it. So, this is a little bit tricky. Something that you definitely might want to play with if you're new to this, especially if you're used to 'this' just having one meaning, one connotation. It does change in JavaScript, it makes it a little bit tricky. And that's one of the kind of cons of the pattern, but it's not that bad to work around once you know how it works. It's just something you have to keep in mind. So that's an example of using the revealing prototype pattern in two different scenarios, one with our very simple one where we just had add and subtract, and one with a little more robust example where we have functions in the prototype calling other functions, which then changes the context of 'this'. So, I hope that helps get you started with using the pattern. Now in the upcoming demos, I'm going to show a couple of other tricks you can do with this pattern, and we'll go from there.
Using the Revealing Prototype Pattern with 'this'
In a previous demo, I walked through the revealing prototype pattern and showed how it can be used but also showed a little bit of the difficulty you can run into with the JavaScript 'this' keyword. 'This' changes context depending on how it was used and where it was called. So, in the previous example, I showed code similar to this. It had a setOperator. And setOperator was actually invoked directly from the Calculator object, so 'this' represents the Calculator object. That's who called it. But then we want to call the calculate function, and we want to preserve 'this' as the Calculator object. So, what I did in that example was passed 'this' keyword, but then I had to make a separate parameter here representing 'this', because if I did this.operator, 'this' now represents the function that called, not the actual Calculator object. The context changed. So to get around that, one way you can do it is simply pass 'this' around, but then it kind of pollutes your parameters. And so a couple of other examples here. Notice in setVal and setEquation, not only do I pass the value that we actually want to set, but I also have to pass 'this' so that I can get to the currNumberCtl variable that's defined up here in the constructor. Alright, so that kind of pollutes your parameters and makes things a little bit messier than maybe you'd want them, but it does get the job done. At least it preserves the original caller so that 'this' truly represents the Calculator object, not some other function that actually called this function. Okay, now, there's another way we could do this, though. I'm going to go ahead and take this out so that we just call this like we would normally do, and I'm going to put the 'this' keyword back. And let's come down to where we call setVal. Here's an example here. There would be several. But, I'm going to do setVal.call, and what you do is call allows you to pass the context first, 'this'. 'This' will now represent whatever called this. We'll assume clearNumbers was called by the Calculator object in this case. By saying call, it'll pass the context of what setVal should be called from, called as. So if the Calculator object called this one, 'this' represents the Calculator object. And we're going to say, hey, I want to call setVal, but I want to call it using the Calculator object, 'this', and then I'll pass parameters. Now why this way is better, at least in my opinion, is that look at our parameters. I could just use 'this' everywhere I want. I don't have to put an extra parameter like you saw me do earlier. I don't pollute my parameter collection there. It keeps it a lot cleaner. Now, I have an example where I've done this for everything, so let me go ahead and save this one back as it was. I have another script called revealing prototype pattern with call. Alright, so if we come down in here, you'll notice that setVal and setEquation just have one parameter, and then they then use the 'this' keyword. No special type of coding going on here to account for changes in 'this'. If we come down to clearNumbers, notice that we call setVal, but we do it by using the call function built into JavaScript, and we say setVal.call, call it as 'this', which would be the Calculator object. That now preserves the context. So, instead of calling it as clearNumbers, and 'this' would represent kind of this context, by doing setVal.call(this), the Calculator object itself now basically invokes setVal or setEquation, depending on which one you call here. So this allows you to define the context of the caller that actually calls this function. It's a very nice trick you can use with this pattern, and there are others out there. There are some bind techniques you might see out in the internet that even make this even more simple. But this is a great way to get started dealing with 'this', and I think it's a lot better than what I showed you in the previous demo, because it keeps your parameters clean, and you just worry about the 'this' keyword, and that's it. So, it's something you definitely want to keep in mind that if the Calculator object were to call setVal directly, then this will work fine, because 'this' represents the caller, the Calculator object. However, that's not the case here. The Calculator object calls clearNumbers, and then we call setVal. That changes this, so 'this' wouldn't work normally. But by doing the setVal.call and setting the context, now 'this' truly represents the original caller of clearNumbers. So, definitely something that's a little bit tricky, as I've mentioned several times, something that threw me off over the years as I first got into this, but it's one of those things that once you know about it and know how to deal with it, and now you know two techniques, that it's not too bad to work with.
Extending the Revealing Prototype Pattern
One of the best features of the revealing prototype pattern is the ability for external users of your script or library to override or even extend functionality that you've defined without touching your source code. Now, I showed a simple demonstration of this with the prototype pattern, but I'm going to show that it also works with the revealing prototype pattern. So, I'm going to open up the simple demo we did initially in this section. And what I'd like to do is, let's change the add functionality instead of maybe adding, we're going to come in and maybe we want to, let's say we want to multiply, something like that. So, we're going to say Calculator.prototype., and now we can get to the add, and we'll give it a different function, so we're going to override it now. And now it's up to us what we want to do. So, let's just go ahead and we'll grab 'this' and the variable, and let's just multiply them. And so, we'll have 2 times 2, which is 4, which isn't going to be very impressive, so let's go ahead and change this a little bit. Let's do 3 and 3 there. So, normally, we should obviously get 6, but now we should get 9 if the override works appropriately, and that's all you have to do. So what's beautiful about this is, if our script is in a totally separate file, I don't have to go in and actually touch that script at all. I can extend functionality. I can even add new functionality if I want to the Calculator object just through the prototyping. Let's go ahead and try this out. We should see 3 times 3. We should get 9 instead of 6. And there we go. You can see that it worked. Now of course if I comment this out, we should be back to the normal, and we should get 6, because it's going to do the regular addition function. And you can see that worked as well. So that's an example of how easy it is to actually extend this type of pattern. That's one of the big strengths of this pattern is that you can allow users to do this type of activity without having to modify your source code.
Converting Code to the Revealing Prototype Pattern
A great way to learn about a pattern, such as the revealing prototype pattern, is to take existing code and convert it to follow the pattern. So, we're going to do that here. In the very first module of the course, I ran a demonstration that showed using HTML5 LocalStorage, or you'll hear WebStorage sometimes, and it's basically a much better type of cookie if you haven't used it before. So we can put in a name, store it, and if I go the Chrome Developer Tools, come down to Localhost, you can see that our Local Storage has a name and a value, so a key and a value stored. And I can clear them as well. And you'll see they're cleared out. That's kind of what it does. Now the script for this, though, is---there're only three really functions here, but it's kind of the function spaghetti code. They're in the global scope. There's no organization of them. And so what we're going to do is convert these particular functions to follow the revealing prototype pattern. So to do that, let's go ahead and create an object called LocalStorage, and we'll create our constructor that we do with the revealing prototype pattern. And I'm not going to store any variables in this one. So, we still need it though. Then we'll go ahead and prototype it. And we'll create a function, which we then self-invoke right there. Now we can put in our private members. And our public members, of course, will be defined using an object literal. Okay, so it's pretty easy to convert this. I'm just going to grab these functions. We'll cut them out. I'm going to paste them right into the private area, and now I just need to fix them up a little bit. All we do is take off the name, put a variable and assign it, put a comma, and we do the same thing for these other two. Very simple to actually convert it. And then once we're done, we'll hit a semicolon, and let's make sure we don't miss that comma right there. Okay, so now we have in our private area our private members of the LocalStorage, a loadSettings, storeSettings, and hasLocalStorage, but none of these are public at the current time. So to do that, we, of course, need to take these names and put them into our object literal. And I'm going to go ahead and name the alias for what the external user would call the same as the internal function. So, we'll do storeSettings, and then finally we'll do hasLocalStorage. And that's it. That's how easy it is to actually convert just some kind of messed up functions that really have no rhyme or reason to follow one of these patterns, in this case the revealing prototype pattern. So now, we can go ahead and use it. So we'll come up to, this is using jQuery to detect when the DOM is loaded, and we'll go ahead and create a new LocalStorage object, and now what I need to do is just prefix ls dot (ls.) on front of the appropriate methods. So we'll come into this, and we have a loadSettings right here, and that should do it. Now I would, of course, normally maybe even put this in a separate file on its own, but in this case, we're just going to leave it as is so we know once the DOM's loaded, we'll call it. So, let's come in. We'll View in Browser. And we should, hopefully, get the same exact behavior. We'll store. Looks like they stored. Let's go check, though. So, we'll come down into our localhost, and we have Dan Wahlin, and we have Utah. So it looks like it did work. Let's clear. Refresh this, and it did clear. And there's no JavaScript error, so it looks like we're good. So that would be an example of converting from just kind of your standard function-based JavaScript code to follow one of the patterns. Now the same exact process would apply to the module pattern or the, just the regular prototype, or the revealing module pattern. Just we would change up, obviously, our JavaScript code a bit. But now I've taken these out of the global scope, so at this point, the only thing in the global scope is LocalStorage, and as I've shown a couple of times, let's go ahead and fix that. We'll just put a namespace called my namespace (myNS), if it's already defined, we'll use it. Otherwise, we'll create kind of an empty object here. And now we'll simply prefix the LocalStorage with that namespace. Now we've taken that out of the global scope. This is the only thing that's in there now. And as long as another script we're using doesn't use my namespace or your company name or whatever you decide to use for that namespace, then you'll be good to go. Then we can come up to here, put it up there, and now we're ready. We now have a namespaced revealing prototype pattern object, and let's go ahead and run it one more time. Okay. Let's do California this time. Store Settings. Let's go look. And it looks like it worked. We'll clear. And everything's gone. So, now we've kind of done everything we would need to do to make sure we don't have naming conflicts. We've now satisfied the reuse story, because we now have a reusable object here, and from a maintenance standpoint, all of our functions are now grouped into a container that kind of relates them to each other, so it's very easy to know where to go to maintain things, or easier I should say. So that's an example of converting existing code to use the revealing prototype pattern.
Summary
In this module, you've seen the revealing prototype pattern and seen how it also provides another way to encapsulate variables and functions much like the other patterns we've talked about throughout this course. It does provide the best of two of the other patterns we talked about, including the prototype pattern and the revealing module pattern into one pattern. So you get the extension capabilities of the prototype pattern and the ability to mark members as public or private from the revealing module pattern or the module pattern in general. That makes it very nice if you want to hide certain members from users that are calling into the code. One of the really nice features, though, especially if you're going to be building libraries that others might need to modify or extend, but you don't want them changing the source code, is the prototyping capability. And I showed a demonstration of how you can extend existing functions. And you can even add new functions if you wanted using prototyping. So, that's a wrap on this module, and I hope that helps you better understand the revealing prototype pattern and how it can be used in your JavaScript code.
Course author
Dan Wahlin
Dan Wahlin founded Wahlin Consulting, which provides consulting and training services on JavaScript, Angular, Node.js, C#, ASP.NET MVC, Web API, and Docker. He is a Google GDE, Microsoft MVP and...
Course info
LevelIntermediate
Rating
(1679)
My rating
Duration2h 10m
Released12 Dec 2011
Share course