DEV Community

Cover image for ๐Ÿ‘จโ€๐Ÿ”ฌ Why The DOM Causes Negative Enthalpy! - Learning Frontend Deeply - Part 2
MirAli Mobasheri
MirAli Mobasheri

Posted on

๐Ÿ‘จโ€๐Ÿ”ฌ Why The DOM Causes Negative Enthalpy! - Learning Frontend Deeply - Part 2

Why Should You Care About The DOM And The Negative Enthalpy?

In the first part of this series, we learned that HTML is a Markup Language destined to create documents. We now know that this document is much like a paper one. We can use different elements and layout systems in HTML to shape our ideal document layout.
But still, there's a question. If it's only about documents, then humans have been able to create them thousands of years ago. Documents can be carved on stone, painted on papyruses, and written on paper.
So while HTTP facilitates the document's sharing around the world, there's one important thing that a webpage needs to be capable of to ultimately become superior to a simple document.

And it is the ability to update data in real-time, in response to user interactions and different events. This feature makes documents interactive and pushes the limit of the traditional documents which could never be edited or updated. And especially this is one of the main skills every frontend developer should acquire.

Throughout this article, we are going to learn about the Document Object Model abbreviated as the DOM. In the last part, we learned about the Document, now we'll try to figure out what an Object is and how the DOM implements the Model.

But we're not going down a straightforward path. We're going to learn about some basic theories of computer programming. This includes variables, objects, collections, compilers and etc. This is because I want to show you how in the end all of these theories shape the internal functionalities of a web frontend application.
This is somewhat like how we're introduced to Christopher Nolan's Tenet. It's going to show you some theories and in the end, you are going to face it all in real action. Then let's dive deeper!

First questions first...

๐Ÿ๏ธ What Is An Object?

While a motorcycle has two wheels, a car holds four. Both are objects. Each with its traits. These traits could vary in numerous ways.

The comparison we made identifies the difference in the count of common property in two distinct objects.
A contrasting case is the observation of a hen and a motorcycle. Both can move. And while the hen utilizes its legs for this purpose, the other uses its wheels. The movement action is possible for both of them, but they do so using quite different tools.

โ— In terms of programming, we can express the actions as Methods and the tools as Properties.

Thus, the main element in Object Definition is that a set of traits shape the object.

By knowing what an object definition is, let's move on to how a document is defined by it.

๐ŸŒด What is an object model?

C is a programming language. So is C++. Both are known as semi-low-level languages. This means you'll need to write thousands of lines of code to make a simple program work. But in exchange, their programs run at higher speeds. Because by writing code in a low-level language the system needs less translation of your code to understand what you're trying to assemble.

But there is a major difference between the two languages we talked about earlier. C++ is an object-oriented version of C. What does this mean?
This means that we can define objects in C++ programs which possess their own traits and actions.

Let's define object orientation in smaller chunks. That'll make it easier for you to grasp the idea if you don't already know about it.

First, let's begin with a simple thing; Value. That's what every program is about!

2๏ธโƒฃ Hey PC, Take This 2!

In a program, every value is stored in a part of the memory. This value is identified by a reference. A reference is a specific number that addresses a location in the memory that holds a specific value.

This referencing can be suitable for performing actions like computing. For example, if you want to calculate the sum of 2 and 3, you have to store these values in the system and then give the system the program by which it should add these two numbers.
A reference to the value 2 could be a number like 2452123 and a reference to the value 3 could be another number like 7892392.

The system can manage these references easily. But it would be hard for a human to work with them. We'll easily forget which reference points to which value.

๐Ÿค™ Call My 2, Ey!

A variable is simply a name we give the reference to a value. In the last paragraph, we said that in an exemplary system a reference to number 2 is 2452123.
Now, what if we told the system that we want this reference to be called a; so that every time we had to point to this number we simply give its name and the system retrieves the value for us?

How variables resemble humans' memory. (Click to learn more.)

This behavior is close to how we humans store different data in our minds. For example, when we want to refer to a long fruit with a yellow cover, we say banana. The value was retrieved!

๐ŸŽ™๏ธ Hey PC, Repeat After Me: Ey equals 2!

Fortunately, most of the programming languages manage this for us.
Here's how we define a variable in JavaScript:

var a = 2;
var b = 3;
Enter fullscreen mode Exit fullscreen mode

In the above code block, we've declared two values, stored them in memory, and given them a custom name for their references. Thus if we wanted to add these numbers we simply tell the system: add a and b.
In JavaScript it's written like this:

var c = a + b;
Enter fullscreen mode Exit fullscreen mode

What happened in this code block?(click to learn more)

Here, in a single line, we've performed three actions. First, we've retrieved the two values 2 and 3 from the memory, by calling their names. Then, we've added these two numbers which result in a new value, 5. Next, the new value is stored in the memory and its reference is given a name; c.

Well, we gave the references a name. But what does it have to do with Object-Orientation?

โ›๏ธ The Thing, or The Object?

So far, we've only defined simple variables. These may be the basics of programming, but they are insufficient for a more advanced program.

Metal is one of the most useful materials in construction but by giving a fair look at the world around you, it's easy to conclude that buildings aren't just made of metals. They're assembled of glasses, metals, concrete, etc.

The same observance applies to a program. It's never made of single values. But rather a collection of them.

๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ [Person 1, Person 2, Person 3]

You know people by their names, phone numbers, looks, jobs, and much more. Perhaps you know a lot of people. Hundreds of names could be familiar to you.

Indeed you have got a collection of information in your memory. A collection of names, or a collection of different brands. All in all, collections are the main way of information storage.

What makes collections suitable for this purpose is their flexibility and simplicity in integration. You can easily search, sort, filter, or manipulate a collection.

๐Ÿ“Š Data Structures

Probably, algorithms are familiar to you. If not, you can think of the following text as an algorithm:

Go to the kitchen. Search the cabinets for the red pepper can. If found, swallow the whole can's content. If not, go to the freezer. Take out all the ices in it and swallow them one by one.

As you can see, an algorithm is a set of step-to-step commands. Computer programs are instructed using these algorithms.

Let's think about the sum program which we previously wrote using the variables. Its algorithm is straightforward. Take the first number and add it to the second one. Store the result in a new memory location.

But is there a collection too?

๐Ÿ”ข Arrays

Sometimes you need to store different values as a group. Like a list of different versions of a sentence. You can store each value in a separate variable but that's not the ideal way. Because for instance, if you are required to iterate over the list and find a specific version, you'll have to check each value manually to find out whether it's the wanted value or not.

Arrays come to help.
An array is indeed a list of memory addresses. Of course, these memory addresses refer to values. But its difference with a normal reference is that it can be indexed.

What is indexing? And how does an array work? (click to learn more)
  • Simply it's like when you are looking at a list of different versions of a sentence and you ask your colleague about which version he likes the most and he responds: 'The third one!'

  • So, the keyword here is third.
    Now if we wanted to represent the version history list in a JavaScript array, it would look like this:

var versions = [
  'A sentence.', 
  'Beautifully written sentence.', 
  'Da Funny Sendenze!'
]
Enter fullscreen mode Exit fullscreen mode
  • To access the second sentence and store it in a new variable the following line of JavaScript suffices:
var theDesiredSentence = versions[1]
Enter fullscreen mode Exit fullscreen mode
  • In JavaScript arrays are indexed from 0 which means that the first element's index is 0 and the nth element's index is n-1.

The array is a very simple collection. But remember when we talked about the calculation program. It didn't consist of any arrays. Perhaps we could use an array of numbers and write a program to calculate the sum of all of the numbers in the array. But that's not what we're trying to do right now.

The question was whether, in that simple program, a collection existed or not. Now, none of the values were collections, but in reality, the whole program is a collection.

Why is that?๐Ÿง

๐Ÿ” Program Compilation

Every program written in a language has to be compiled into machine language to act as fast as possible. The machine language is the most direct one, but having the lowest level among the programming languages, it's not possible for programmers to easily interact with it.
The nerds' solution to this problem has been the development of higher-level programming languages. Yes, even C++ has a higher level in comparison to that of Assembly.

Still, there's a matter to reflect upon. If communication with machines is difficult then how comes the compilers do it and turn huge chunks of code into machine-readable ones?

To understand the mechanism you can think of yourself trying to speak a foreign language, how will you manage it?
First, you will create mental models.

What is the mental model? It's the concept or the meaning of what you are trying to translate.

How is a mental model designed? Suppose you want to tell a foreigner that his face is burning. What is the concept behind this sentence? A face that belongs to that person is melting due to contact with heat?
But what is the context? Perhaps you and the other person are trapped inside a burning house and you are screaming at him to warn him that his face is burning. Or maybe you are pushing his face into boiling water and joyously shouting: "Ha! Ha! Ha! Your face is burning!"

Do you see? Different contexts. Different tones. Different sentence structures.

Now how are these related to a compiler's task? Well first of all it gathers every value in your program. These values are like the meanings of every single word. Next, it tries to shape a model of your values. This model is shaped from the different scopes inside a program code.
Scopes are different blocks of code inside a program. These blocks contain standalone logics, which can perform independently of other parts of the code. Sure most of the time the blocks will use variables defined in other scopes or passed as arguments.

The compiler will look for the various blocks present in a code to shape its model. These blocks will help in maintaining the levels of the model. Previously we learned about arrays which are the most common forms of collections, but the ones we spoke about were only one-dimensional. However, in cases in which we need to specify a collection of groups of values, we can simply nest arrays inside each other.

In JavaScript a nested array might look like this:

var nestedArray = [
  [1, 2, 3],
  [4, 5, 6]
]
Enter fullscreen mode Exit fullscreen mode

In the above code example, the nestedArray variable could be a model of various values organized in different blocks. Like block 0 and block 1 and so on. This way the compiler will know what block each value belongs to. So if somewhere in your code you try to call a value that isn't available in the corresponding block, the compiler will throw an error.

A nested array might be a good example to illustrate a collection model, but not perfect for such a case as a compiler's model. Because arrays are just a group of values in a specific order.

Thus, the programmers have designed various types of data structures that can be used to implement collections in a useful way. Examples of these data structures include linked lists, queues, stacks, graphs, and hash tables.

What Data Structure Does A Compiler Use?

Compilers mainly use Symbol Tables as their primary data structure.
A Symbol Table is a symbolized collection of data. Don't panic if this doesn't make sense to you, we're going to learn it in more detail.

โš›๏ธ What does symbolized mean?

Remember when we talked about variables?
We stored a value in the memory and then gave it a name. So each variable in a program is made of a group of information that includes: memory reference, name, type, and attribute.
Using these properties, the compiler can store what information it requires about a particular variable in a single symbol and then implement these symbols into a bigger model which represents the code blocks and scopes, using a data structure.

A representation of Symbol Tables could look like this:

<symbol name, type, attribute>
Enter fullscreen mode Exit fullscreen mode

What are the type and the attribute? (click to learn more)
  • JavaScript is a dynamically typed language, which means that you don't have to strictly define a variable's type. But under the hood, each value owns a type. There are several built-in types like objects, strings, numbers, etc.
  • These types declare the intrinsic behavior of the variables. So in a Symbol Table, each value holds a type declaration. The attribute is another unpopular term in JS. In languages like Java, keywords such as public and private exist that can be used in a variable declaration to indicate in what context the variable can be used.
  • The let and const are the two attributes that can be used in JS. For instance, using the const attribute clarifies for the compiler that the variable can't be assigned a new value after its initial declaration.

What data structure a compiler uses for shaping the code blocks, can vary between Linear Lists, Binary Search Tree, and Hash Tables based on the compiler's architect.

๐Ÿ’ผ Is a data structure enough for a compiler to get its job done?

The short answer is no.
The long answer is that a data structure is only a model that makes data available to you. It exposes no methods to work with the data. It's barely a skeleton of data.
A skeleton doesn't move by itself. It can take no action. A body needs muscles to be able to handle its skeleton for good use.
Hence the compiler uses its own built-in methods to work with the data that is exposed to it through the symbols.

How is this data structure is similar to a database? (click to learn more)
  • Each symbol is an entry and each code block is called a block. You could think of a symbol table as a database. Indeed I can relate to this personally since I'm currently working on the development of a web-based database management application for the place I work at.
  • Each cell in a database table is like an entry. A cell can be a text, a number, a date, and many more fields. Each of these fields has its own type and attributes. Each table can also be divided into different phases with each phase having its own rows of entries.
  • But a database management application isn't made up of just entries and phases. It's also about the ordering of data, its aggregation, editing, inserting, removing, validating and etc.
  • Each of these functionalities can also be generalized to how a compiler commonly behaves with a symbol table.

โ‰๏ธ What now?

This was a long read, but not a useless one. We have learned about the program's compilation progress, and we've come to acknowledge what a data structure is and how an object is defined.
Now, it's time to get back on track and learn how a Document's Object Model is implemented.

But first, let's take a few seconds and think about the answer to a fundamental question of the frontend area.

๐Ÿคทโ€โ™‚๏ธ Is HTML a Data Structure or is it an Object?

It's tempting to say that HTML is an object since it possesses traits like a body or a head or a title. These may sound like traits being defined for an object.
But they're not and HTML is definitely not an Object. It's a Data Structure. All that HTML does is expose data.

Indeed you the developer who writes the HTML are exposing this data to the browser. Using the document structure which we talked about in the last part, you were doing the compiler's job.
Oh, yes! Perhaps you have written several HTML documents, or maybe you're an experienced one, and using the HTML markup has been a daily job for you. But you have never thought that you were indeed writing a pre-compile file. That you were doing the programming process with a negative enthalpy!

Sounds crazy and sounds like what Christopher Nolan introduced in his 2020 movie; Tenet.

You have come a long way to reach this point, and perhaps you are tired or you think this article will be useless. Yeah, I know! This idea is turning around your head that I've been mocking you all the time. That compilers and data structures and the Object Orientation have got nothing to do with a simple HTML.
But be patient my dear reader. From now things only get better.

A fight scene in Tenet
After all, what do you expect from a Nolanish idea?๐Ÿ˜Ž

SPOILER FREE: I'm not going to spoil anything from the movie's plot. The negative enthalpy theory is something you learn very early in the movie. So enjoy the article!

๐Ÿ”€ But how is the negative enthalpy happening?

A chemical reaction with a negative enthalpy is one that loses energy throughout the process.

This might sound too theoric but we can interpret it in our subject as such:

When we code a program and the compiler turns it into an executable file, we're keeping energy by doing less work by ourselves. The compiler is the one that handles the hassle of translating our code to machine-readable programs. Now, when we write HTML, we're losing energy. Because we're doing a part of the compiler's job which is creating a data structure. We're doing more job to model the fine Document Structure for our purpose.

But the Data Structure isn't the only thing that the compiler creates. There was actually a need for different methods to be able to work with this data.
This is where the Document Object Model comes into play. And to no surprise, this time we're going to work with objects.

๐Ÿ—œ๏ธ Where are my methods?

So, you give the browser all the data necessary in your document, organized into nested structures, according to your desired layout, and expect the magic to happen.
But that's not what every application is about. Is it? Nowadays web applications are more than just scientific documents. They're about Interactive Interfaces which respond to user interaction.

Documents get updated, changed, inspected, animated, styled, and manipulated in real-time. If you think of the HTML Document as the Symbol Table then by using the DOM Methods to work with this data structure and to change it, you are doing the compiler's job.
Because you are managing the available data structures and methods to output your desired program.

But there is one important difference. The compiler compiles once, you do it many times.

What Next?

Originally this post was intended to have full coverage of all the methods that the DOM avails us with. But tonight I decided that writing such a long article might not be a wise move and might result in the dear readers' attention loss.

So our long journey comes to a pause with the knowledge that the management of a frontend application is like a real-time compilation. In the next part, we'll learn about the DOM's methods and compare each of them with what a compiler does.

The next part is more like an action ride through how updating a document's different parts, results in different states, and perhaps Tenets!

Tenet gif. Pattinson: What the hell happened here? Washington: It hasn't happened yet.

And I expect the next part to be released faster than this one. Since most of it is already written!๐Ÿ˜

The End!

And don't forget to give me feedback. I'm trying to bring new ideas into this series and like everyone else my ideas have their own flaws too. So I would be glad to hear what you think!๐Ÿ˜…

Top comments (0)