This course contains good reference material, but does not reflect our current quality standards.

Check out a free preview of the full Organizing JavaScript Functionality course:
The "Task #3 - Questions" Lesson is part of the full, Organizing JavaScript Functionality course featured in this preview video. Here's what you'd learn in this lesson:

Kyle spends some time answering a number of audience questions around why modules are important and more examples of public and private variables.

Get Unlimited Access Now

Transcript from the "Task #3 - Questions" Lesson

[00:00:00]
>> [MUSIC]

[00:00:04]
>> Kyle Simpson: The question was why are we organizing things into modules?
>> Speaker 2: To hide the internal stuff.
>> Kyle Simpson: So the major reason for organizing things into modules is if you zoom out and you don't pay any attention to those internal details, or if you code fold and you ignore the internal details, the major thing here is that we are able to declare private internal details that's a function.

[00:00:34] That's a function, we've got a bunch of private internal variables. We don't want to expose that stuff to the outside world. If that stuff was global variables or global functions, there's an extremely high chance that some other file also declaring global variables or global functions could accidentally override or collide with one of ours.

[00:00:56] So we don't want global variables because of the high chance of collusion, the high chance of accidentally overriding variables that we weren't intending to. Those are all negatives in code and that's what most people refer to as kind of the wild, wild west spaghetti coding of JavaScript. That's where everybody starts.

[00:01:14] As we're learning, we start putting stuff in the global scope, but the next step of maturity is to say I don't wanna put that stuff in the global scope, I wanna wrap it up inside of a module. So I put this stuff inside of a module and then only the stuff that's public needs to be public.

[00:01:33] So here, that carousel.init is the only thing that needed to be public. All the rest of these details, these functions and variables, all that stuff is private and there's no reason to expose it to give us the potential for collision. The primary principle here is that modules give us encapsulation which is a fancy $25 word for saying private stuff,

[00:02:05]
>> Kyle Simpson: Leslie asks, in most cases, will our return be init init. Well, I've set up this example that we're going through, this exercise today artificially to look like that. Most of my modules have several methods on the API. But our simple example that we're going through here is just focusing on keeping as much stuff private as possible.

[00:02:27] So we aren't seeing any examples yet, although we will, we're not seeing any example yet of any need for other public API stuff. This question says this closure pattern looks to me like declaring a class. What's the main difference? Does the class handle the DOM and jQuery? So there's a bunch of different stuff in that question that we don't wanna mix up.

[00:02:50] This code organization decision about whether we use a module or whether we try to implement something that looks like classes, has absolutely nothing to do with what we're dealing with in the DOM or CSS or any of that stuff. It doesn't deal with jQuery or whatever. It's really just a question of how do we organize our functions and variables.

[00:03:11] It's at the JavaScript level that we're asking this question. It doesn't matter what we put on top of it. So at the JavaScript level, the question is, is the module my better hammer, or is the class thing that people try to do in JavaScript my better hammer? And I could make a dozen different observations about differences, but the major one that I'll make an observation about here is that the thing that people call classes in JavaScript does not offer any notion of privacy.

[00:03:41] Everything in a quote unquote class in JavaScript is public. By default, everything in a module as we're seeing here is private, and you get to decide what to make public. So that's the first, probably biggest, observation that I could make about the differences, although there are dozens of other differences that we could go into.

[00:04:02] There are some comments being made about it's not really classical inheritance. Yeah, I'm not a class fan at all. I don't like classes. I definitely don't like them for JavaScript because JavaScript doesn't really actually have classes. And I do in my advanced course as well as in my object prototypes book, I do go through what I call classless objects.

[00:04:23] It's a way of defining objects and using prototype delegation without the notion of classes at all. I think that's a much better way of going about it. The little catch phrase that I have for it, instead OO which is what people mean when they say object oriented programming, instead of OO, I coined the phrase OLOO which stands for objects linked to other objects.

[00:04:47] So there is a pattern for dealing with objects that doesn't bring any of the complexity of classes into it.
>> Kyle Simpson: The question was asked what scenarios makes sense to ever pass in a parameter to an IIFE? That's a great question, it's outside of our exercise but it's a good enough question.

[00:05:06] Let me take a quick little side note. So set our exercise aside for just a moment. Let's pretend you're not even going to deal with the module design, you just have a bunch of stuff in a file a bunch of random functions and variables in a file and you wanna organize that file so that stuff isn't global.

[00:05:23] Well the easiest way to do that is to have an IIFE wrapping around the entire contents of your file. So you start the IIFE at the top, you end the IIFE at the bottom and all your spaghetti goes here.
>> Kyle Simpson: Okay? And in the early days of me learning JavaScript, this was the most important thing I did was just go through and find all of my files that I had a bunch of global stuff, and wrap an IIFE around the entire contents of the file, so that stuff's private inside of a function instead of public.

[00:05:54] Now, some stuff needs to be public, otherwise there would be no point to any of the contents of that file. If none of it's being accessed anywhere, then that whole file is pointless and you should just delete it. So let's imagine that I have 100 different variables and functions and I wrap a big IIFE around all the contents in that file, and then I try to run my program and I notice that two of them are breaking.

[00:06:18] The other 98 of them aren't ever accessed anywhere else. But what I've concluded then is that I got 98 things which ought to be private and 2 things which ought to be public. This isn't even asking the question about modules, it's just asking a question about access of variables.

[00:06:36] So let's imagine I had 98 private things here and I'd just leave those 98 private things completely alone. All right, the two things that did need to be made public, I could easily make them public by just simply adding them as references on the window object. So I could say something, if there was a thing called foo in here and I needed to make that public, I could say window.foo equals foo.

[00:07:00] And if there was another one called bar, I could say window.bar equals bar. That makes references on the global object to these internal private things and that makes them accessible to the outside world, just like they were before. So 98 different things stay private, these things get public.

[00:07:26]
>> Kyle Simpson: And now the question back at hand was, what scenarios would I ever pass something into an IIFE? Well, here's where I would do it. Because an IIFE is just a regular function call, I can pass stuff in. So I could pass the window object in, but stylistically, I don't like using the window object name.

[00:07:45] It doesn't really speak to me from a JavaScript perspective. It's a DOM thing, but it's not a JavaScript thing. From a JavaScript perspective, I'd like to give it the name global. So if I have a parameter name of global and I pass window in as an argument to it, essentially, global becomes an alias for the window object.

[00:08:04] And now inside of my code anywhere that I need to do global stuff, I use the word global instead of the word window. This is purely a stylistic thing but there what that does for me is it now let's me visually see the stuff that's global, publicly available versus the stuff that stays private.

[00:08:23] If I see the word global anywhere, I know that, it jumps out at me as a big neon sign, that stuff is public.
>> Kyle Simpson: Finally, I would mention that especially in the jQuery world, when people deal with multiple frameworks being on a page, it's very common for somebody to say well, I got some stuff from jQuery that I want, some stuff from prototypes, some stuff from dojo, whatever, and they pull in a bunch of different frameworks.

[00:08:47] And the problem is that most of those libraries and frameworks try to use the same dollar sign symbol for their main function, which is pretty annoying. And it means that dollar sign essentially becomes unusable because you don't know who was the last one to point to it. And so a way to solve that is to pass in the jQuery object for example, by name.

[00:09:09] Of course, I never wanna type jQuery. That's like the worst variable name ever invented. I don't wanna type that cuz I'm gonna mess up the capitalization a thousand times in my code, but if I pass it once by name and I give the parameter alias dollar sign, now inside of this IIFE, from lines two through nine, all of these hundreds of functions can use dollar sign reliably because we know for sure that inside of this IIFE, the dollar sign always points to jQuery.

[00:09:41] Those are the two major reasons why I pass stuff into IIFEs. So hopefully, that answers that question. Next question.
>> Kyle Simpson: To what extent is Document Ready necessary just to get practice? That is a really good question. So you'll notice that I am using Document Ready all over the place.

[00:10:01] There's an awful lot of information out there on the web which says if you put your script tags at the bottom of your body, which I have done here, there is a lot of people out there on the web that claim you don't need a document ready event, because by the time your script runs, your document's already done parsing.

[00:10:19] That's the claim. That claim is false even though most of the time, it accidentally turns out to be true. Technically, the DOM is not necessarily guaranteed to be complete even though many times, it often is complete. So basically what I suggest is, don't assume anything. The reason the document ready event exists, it's sole reason for existence is to allow you to wait until you're sure that the document is ready, that's why it's called that.

[00:10:52] So don't assume that it's ready until that event has fired. As a side note on that, there's an awful lot of stuff that we do in our apps that doesn't care about the DOM and people still wrap that stuff up in a Document Ready which is kind of an anti-pattern actually.

[00:11:08] You're waiting unnecessarily. For example, let's say you need to make an Ajax call. Ajax doesn't deal with the DOM at all. There's no reason to put an Ajax call inside of a document ready handler although that's where most people do it. So document ready specifically is for any piece of logic that actually deals with the DOM because if the DOM's not ready, you're playing wild wild west games risking whether or not you can use it or not.

[00:11:35] Hopefully that answered that. Next question. The code we covered today is compatible with all browsers? Yep, absolutely. Everything I'm talking about is straight up simple JavaScript, we're not talking about any complex patterns like ES6 or anything like that. Okay, can we use objects as a parameter and then pass parameters a property of the objects.

[00:12:01] Yeah absolutely. So the question is, can I do something like, if I have a function called foo and he takes a parameter and I call foo with an object.
>> Kyle Simpson: Can I pass in an object like that and reference it? Yeah absolutely you can. I can say o.name and that will print out a column.

[00:12:37]
>> Kyle Simpson: Kevin saying that document ready is the same thing as DOM content loaded? Absolutely. Document ready, right now what it does, is it waits to see if that event is fired. So they are synonymous for our purposes. Okay, great questions by the way. Thanks for asking all those.

[00:12:59] Yeah you can listen for DOM content loaded by doing window.addEventListener. Absolutely. Okay.
>> Kyle Simpson: Back to mental context, switch back to our exercise. We're not complete with task three yet, but we have made significant progress on task three. Are there any questions so far on task three?
>> Speaker 3: In this case right, like when we initially wrote, like we wrote all the functions within like function.ready directly, right, all are function scoped in this case.

[00:13:41] So there is no like global variables getting exposed, right?
>> Kyle Simpson: The only global variable is this variable.
>> Speaker 3: No, no, not.
>> Kyle Simpson: We're essentially treating these variables like namespaces.
>> Speaker 3: No, the way we wrote initially.
>> Kyle Simpson: When everything was inside of the document ready? At that time, if everything is inside of the document ready, and it all also private, except for the fact that most of the stuff should not have been in the document ready.

[00:14:07] That was the point that I made, that was sort of the orthogonal point that I made which is, you don't want to put all that stuff in a document ready. So if we had just said, I'm not even to use modules, but I just want to refactor that original code to only put stuff there that's necessary, then we would have been taking a bunch of variables and functions and putting them out of the global scale.

[00:14:26] That's would have been the only place to put it.
>> Speaker 3: But like we wrapped everything inside a function right, like when we declared inside a function, it just will be part of that function scope, right?
>> Kyle Simpson: Well, what I'm suggesting to you is this. Let me open us the solutions folder back for task one.

[00:14:49]
>> Kyle Simpson: In this code, not all of the stuff inside of here should be, like we have one thing that's outside this version of the file in another document ready, right? So.
>> Kyle Simpson: If this had had the document ready like it should have, it should have said this.
>> Speaker 3: Now when we write like this, everything these function scoped within that function.

[00:15:16]
>> Kyle Simpson: That is true, but the point I'm trying to make is that most of this stuff, well not most of it, but some of this stuff doesn't need to be inside of the document ready. This whole function thing here doesn't need to be inside of a document ready because it's not gonna be called until long after the document's already ready.

[00:15:35] So if I'd approached this file not from first make it into a module rule where we just don't put stuff in DOM ready that you shouldn't, the first step that I would have done is to take that function and move it out of the document ready because that's the more proper place for it, right?

[00:15:54] Now it's a function outside that I reference by name and now, we're faced with this same problem that I got us to. So I just combined both steps into one rather than doing them separately. We come to the same conclusion, which is I don't want all that stuff in the global scope.

[00:16:08] It's a good question. I just want to make sure you understand I just did both steps at once. That make sense?