A High-Level Overview of JavaScript
Before diving deep into how JavaScript works behind the scenes, I would like us to start with a high-level overview of the JavaScript language so that you get a first overview of most of the things that we need to learn to be good at JavaScript eventually.
Let's start by recalling the first definition that we had of JavaScript:
JavaScript is a High Level, Dynamically Typed, Object-Oriented, and Multi-Paradigm Programming Language.
The above definition is 100% correct, but that's just the tip of the iceberg. Let's have a look at another definition of JavaScript.
JavaScript is a High-Level, Prototype Based, Object-Oriented, Multi-Paradigm, Interpreted or Just-In-Time Compiled, Dynamic, Single-Threaded, Garbage-Collected Programming Language with First-Class Functions and a Non-Blocking Event Loop Concurrency Model.
Ok ok I get it! You are surely asking yourself, what's all this? 😅
Well, that's just a definition made for fun where we packed as much information as possible about JavaScript into one unreadable sentence.
But now, what we are going to do is unpack all of them to get a first peek into all the stuff that we're going to learn about JavaScript throughout the course.
I hope you aren't frustrated after reading that definition. The idea wasn't to intimidate or frighten you but to make you have a big picture before we get started.
With that being said, let's unpack that definition
As you might already know, every program that runs on your computer needs some hardware resources, such as memory and the CPU, to do its work.There exist low level languages, such as C, where you have to manage these resources manually—for example, asking the computer for memory to create a new variable.
On the other side, we have high-level languages such as JavaScript and Python, where we do not have to manage resources at all because these languages have so-called abstractions that take all of that work away from us.
This makes the language easier to learn and use, but the downside is that programs built with such languages will never be as fast or as optimized as C programs.
Now, one of the powerful tools that take memory management away from us developers is garbage collection.
Garbage collection is an algorithm inside the JavaScript engine that automatically removes old, unused objects from the computer memory to not clog it up with unnecessary stuff.
It's a bit like JavaScript has a cleaning guy who cleans our memory from time to time so that we don't have to do it manually in our code.
Next up, JavaScript is an interpreted or just-in-time compiled language. We will learn more about this in a later lecture, but what you need to know for now is that the computer's processor only understands zeros and ones. Ultimately, every single program needs to be written in zeros and ones, also called machine code. And since that's not practical to write, we write human-readable JavaScript code, which is an abstraction over machine code, but this code eventually needs to be translated to machine code.
That step can be either compiling or interpreting. This step is necessary for every single programming language because no one writes machine code manually. In the case of JavaScript, this happens inside the JavaScript engine.
One of the things that makes JavaScript so popular is that it's a multi-paradigm language. In programming, a paradigm is an approach and an overall mindset of structuring our code, which will ultimately direct the coding style and technique in a project that uses a certain paradigm.
To be honest, this definition still sounds abstract, but don't worry, it will become more clear as we move on. The three most popular paradigms are:
Procedural programming is what we've been doing so far, basically just organizing the code in a very linear way and then with some functions in between.
We will talk about object-oriented and functional programming in a second 😉.
We can classify paradigms as imperative or as declarative, but again, more on that later.
Many languages are only procedural, object-oriented, or functional, but JavaScript does all of it. It's really flexible and versatile, and we can do whatever we want with it. It's up to you to use whatever paradigm you want. In this course, we will use all of them.
About the object-oriented nature of JavaScript, it is a prototype-based, object-oriented approach.
To understand what this means, we first have to know that almost everything in JavaScript is an object except for primitive values such as numbers, strings, etc. But an array, for example, is an object, and we already saw that in practice.
Have you ever wondered why we can create an array and then use the push
method on it, for example? Well, it's because of prototypal inheritance.
Basically, we create arrays from an array blueprint, which is like a template, and this is called the prototype. This prototype contains all the array methods and the arrays that we create in our code, then inherits the methods from the blueprint so that we can use them on the arrays.
The above explanation is a huge oversimplification, which might still sound confusing. That's why there will be whole section on object-oriented programming with JavaScript later in the course.
But since this is just a high-level overview lecture, I wanted to introduce this topic right here.
JavaScript being a language with first-class functions means that functions are treated just as regular variables. We can pass functions into other functions and even return functions from functions.
We have already used the power of first-class functions without knowing that they are called first-class functions.
Do you remember the below piece of code that we wrote for closing the modal window that we built before?
From the above code we can see that, we pass the closeModal
function into the addEventListener
function as if it was just a regular variable.
Not all languages have first-class functions, but JavaScript has, and it is amazing and really helpful.
Next, JavaScript is a dynamic language, and dynamic actually means dynamically typed.
As we've already seen, we don't assign data types to variables in JavaScript. Instead, they only become known when the JavaScript engine executes our code.
Also, the type of variables can easily be changed as we reassign variables, and this is basically what dynamically-typed means.
There are many controversies about whether this is good or bad, but this is just how it works. The same is not true for most other programming languages, where we have to assign types to variables manually, which usually prevents bugs from happening—the reason why many people say that JavaScript should be a strongly-typed language.
If you want to use JavaScript with types, you can always look into TypeScript.
This, in my opinion, is a really complex topic and probably the most complex one of the whole course, which is why we are going to add lectures on these topics at the end.
First, what actually is a concurrency model? The concurrency model is just a fancy term that means how the JavaScript engine handles multiple tasks simultaneously.
Now you might ask why do we need that? Because JavaScript itself runs in one single thread, it can only do one thing at a time, and therefore we need a way of handling multiple things simultaneously.
In computing, a thread is like a set of instructions executed in the computer's CPU. Basically, the thread is where our code is actually executed in a machine's processor.
Now just imagine we have a long-running task, like fetching data from a remote server? Well, it sounds like that would block the single thread where the code is running.
But of course, we don't want that. What we want is the so-called non-blocking behavior, and how do we achieve that?
Well, by using a so-called event loop. The event loop takes long-running tasks, executes them in the background, and then puts them back in the main thread once they are finished.
This is, in a nutshell, JavaScript's non-blocking event loop concurrency model with a single thread.
It sounds like a mouthful for sure, but in the end, it really just compresses to this. Just keep in mind that, again, this is a huge oversimplification that we will come back to.