JavaScript Design Patterns for Web Apps

ECMAScript Modules & globalThis

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
JavaScript Design Patterns for Web Apps

Check out a free preview of the full JavaScript Design Patterns for Web Apps course

The "ECMAScript Modules & globalThis" Lesson is part of the full, JavaScript Design Patterns for Web Apps course featured in this preview video. Here's what you'd learn in this lesson:

Max uses the type attribute in the HTML script tag to treat app.js as an ECMAScript module. The gobalThis property is introduced and, in the context of a browser, will give each module access to the window object. DOM elements are selected, and some initial event handlers are created.

Preview
Close

Transcript from the "ECMAScript Modules & globalThis" Lesson

[00:00:00]
>> Maximiliano Firtman: Let's think about the questions that I gave you before. So based on this ToDo application if I wanna create the undo operation, how can I do that? So I wanna be here I have deleted the, apply design patterns. How can I get it back with control C?

[00:00:22]
I mean, think about developing the solution. How to do that? It's actually complicated. And what if I wanna type something and press control P, and add it as well. So use my keyword shortcuts to apply actions. Well, the problem is that everything is too tied to my DOM event handlers here.

[00:00:54]
So yeah, then you need to add another event listener and copy these or put this in a function, so we can see that while simple and working, the solution is not scalable. I mean, it works, but when I try to add more functionality, it's difficult. I can, but they will end up with a spaghetti code, difficult to follow, difficult to maintain.

[00:01:27]
Okay, or if I wanna save the data, so because the problem that I have here is if I reload, it's empty. So every time I reload my web app, I'm losing all the list. So if I wanna save that, restore that. So if, if I wanna save it, what should I do?

[00:01:47]
Because now, where is my data here? Where do I have the data? The list.
>> Speaker 2: Right now, It's just attached to the DOM, right? It's just on each HTML element.
>> Maximiliano Firtman: Yeah exactly, the problem is that my data is in the DOM, and that's a problem. So yeah, I should read the DOM and check the UL, grab the data from the text content or in HTML from the ULIs.

[00:02:14]
But yeah, everything sounds dirty. I mean, it will work, we can get into a solution. But, I think it's time to rewrite the whole application, okay? So, this is a vanilla JavaScript application, but without any design pattern. We are going to use now a couple of design patterns to make it work, okay, makes sense?

[00:02:36]
The first step will be to select all the code that we have, In app.js and delete everything. So I'm going to delete everything. I'm not going to touch the HTML, maybe there is one little exception, and I'm not going to touch CSS. With the same, I'm just going to rewrite this app to use a couple of design patterns.

[00:03:00]
Just to give you a hint of the design patterns that we will use, I will use Singleton, I will use Memento, Mixin, Command, and maybe some others in the middle, okay, to create the same code. By the way, you will see that the code that we will end up, it will be more complex, yeah.

[00:03:20]
From amount of lines and everything, it will feel more complex but it will be far more scalable and you will see that in action when we want to add more features how simple it is to add more features if you started using some design pattern. Okay, so delete everything, and I will start writing code here.

[00:03:44]
But I said that I will make one very little change in my HTML, only one. The only thing that I'm going to change is, if you take the script tag, I'm going to add to the script tag this type module, because I going to use ECMAScript modules to modularize my code.

[00:04:08]
That, by the way, is another design pattern modularization. So when you use modules so you separate your code in different modules, that's a pattern by itself, okay? In ECMAScript, in the browser to use ECMAScript modules, you need to type equals module. That means that now within that file, App.js, I can import content or objects from other modules.

[00:04:37]
That before that, it wasn't possible. Okay, okay, so now, because now we are in a module, we are not in a global context anymore. Sorry, I'm not sure if you remember that we do have document.addEventListener(DomContentLoades. I will keep it here, this event listener, content, I have a typo, by the way, DOM content loaded.

[00:05:08]
And DOM actually is O, M, DOM content loaded. In Manila JavaScript, this event is being fired with the DOM when the DOM Is already parsed in memory and ready to be used. So the first thing that I want is to, I'm not sure if you remember, our original code had three variables for the three elements that we need.

[00:05:36]
The list, the button, the input. Let's typically a good pattern. Instead of using get element by ID or query selector, instead of using the Do API, every time we need to access one element. It's a good idea, at least for those elements that we will use a lot to create references so we can use later.

[00:05:54]
Okay, for the button, for the input, remember we are talking about a reference, so this input type a reference to this button because we want a click handler within the input to actually get the content and we need the UL because we wanna render data in that UL, okay.

[00:06:10]
So it's a good idea always to create variables and I'm going to refactor this code, okay. So I'm going to write some code in case you're following along and I'm going to change it later. So I can create variables, bar, let, it doesn't matter in this case because it's a global scope.

[00:06:31]
So I need a to-do list, I need the button, add BTN, and the To-Do input. But we are working with modules, now, what happens with modules? Are these global variables, what do you think? No, because it's a module, I mean, if I don't have type module, there will be global variables, okay.

[00:07:00]
But if it's a module, so, the scope is the module, so I cannot access these variables from other modules. But I think it might be useful later to access those variables, because I want my whole application to access those DOM elements. So something that I can do, it's one way, I'm not saying is the only way, It's one way.

[00:07:24]
I can do this, I can create a variable, an object, I can call it Dom in global disk. Does anyone know what global disk is in modern JavaScript?
>> Speaker 2: It's the window, the self if a worker or a this?
>> Maximiliano Firtman: Okay, that's the best answer that we can get, so it depends on the context that we are running this script.

[00:07:52]
It's always the global object that in the browser is the window object. If it's node.js, it's a global object, if it's a worker, it's a self object. So in this case, it's the same as same window, but it's more cross platform. So using global Ds, D, it's an object that is pointing always to the global object.

[00:08:16]
So I'm actually attaching a DOM object there. So then these three variables, may become,
>> Maximiliano Firtman: Just properties of that DOM variable. And by the way, every time I wanna use that variable, I should use global this.global this. So, maybe what I can do is create just a local pointer to that for this particular module.

[00:08:54]
>> Maximiliano Firtman: And actually now what I need is to get those elements by ID from the real DOM.
>> Maximiliano Firtman: Okay, so I'm going to, this is following the same name so and this is kebab case. Cuz we are using hyphens and from JavaScript point of view, we are using CamelCase, okay?

[00:09:27]
So now with this, in every module, it doesn't matter which module, we have access to those elements. And we are sure that we are doing this on DOM content loaded, so they are safe to use. And then I will need, for the add button, an event listener for the click event handler.

[00:09:52]
We can use arrow functions or normal functions, wherever you prefer.
>> Maximiliano Firtman: And also click on the list.
>> Maximiliano Firtman: To simplify the delete operation, what I'm doing here is instead of reading each delete button manually, I'm checking for the click of the whole list, and then I'm verifying if the event target, event.target has the list, if it contains the class delete button, so if it's a delete button, okay, and we will fill the gaps later.

[00:10:51]
Yes?
>> Speaker 2: So if this module was loaded into a different module would global this still point to the window?
>> Maximiliano Firtman: Yeah globalThis points to window anywhere in your code, it doesn't matter on which module it is, if it's loaded in the browser, okay. Also in the browser, you can create a worker, a thread.

[00:11:14]
If you create a worker and a worker is importing this module, in that case, global this would actually be The worker, the thread, okay? But despite that difference, because the thread cannot access the UI can access the DOM the main thread. So that's why it's a security problem.

[00:11:33]
But, if you're not working with threads in the browser, global Ds will always point to window. This is one of the latest ECMAScript new additions to the language. So, but so it's a good idea to start getting used to using globalThis instead of window, okay, makes sense? So your ECMAScript code will be more platform agnostic.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now