A Developer's Guide to Key Programming Concepts
Imperative vs. Declarative Programming
Imperative programming is about how a program is executed. The exact steps or procedure of the program is listed, and therefore abstraction is minimized. Declarative programming is all about the result; it doesn't matter what procedures or steps the program executed to achieve those results, so long as the result is achieved. Abstraction here is maximized.
The best example to explain these concepts is how we use CSS in web development.
The Declarative Approach in CSS
Here, we select all p
tag elements that are direct children of an li
tag that also has the class name selected
attached to it, and we set that background color to red.
li.selected > p {
background-color: red;
}
In this declarative example, we don't care about the internals or about how the browser managed to achieve this. We only care that the background color is now indeed red.
The Imperative Approach in JavaScript
The imperative way requires us to list the exact procedures the browser should take.
// Get all <li> elements
const listItems = document.getElementsByTagName('li');
// Loop through all of those elements
for (let i = 0; i < listItems.length; i++) {
// Check to see if the class name is 'selected'
if (listItems[i].className === 'selected') {
// Find the children
const children = listItems[i].children;
// Loop through the children
for (let j = 0; j < children.length; j++) {
// Find all children with the <p> tag
if (children[j].tagName === 'P') {
// Set the background color to red
children[j].style.backgroundColor = 'red';
}
}
}
}
JavaScript's Inheritance Chain
Each object in JavaScript has an internal link to another object called its prototype. When trying to access a property of an object, the property will not only be sought on the object but also on the prototype of that object, and so on, until a match is found or the prototype chain has come to an end.
Let's look at an example. Here we have a child
object and a parent
object.
const parent = {
c: 'parent_c',
value: 3,
method: function() {
return this.value + 1;
}
};
const child = {
a: 'child_a',
b: 'child_b',
value: 10
};
// Set the prototype of child to be parent
Object.setPrototypeOf(child, parent);
This creates the following prototype chain: child
-> parent
-> Object.prototype
-> null
.
When you try to access a property a
of the child
(child.a
), it will look in the child
object, and because it exists there, it will return it immediately.
However, if we look for the child.c
property, it will first check in the child
, will not find it there, so it will then check its prototype (parent
), and because it exists there, it will return the value from the parent
.
But what if we add functions to this? The parent
object has a method
in it. If we call parent.method()
directly, this
refers to the parent
object, so it would return this.value
(which is 3) + 1, resulting in 4.
However, if we call child.method()
, this
refers to the child
. Although the method exists on the parent
prototype, the value
that will be used is the one in the child
(10), resulting in 11. If the value
property did not exist on the child
, it would then follow the prototype chain to use the value
found in the parent
.
This is how, for example, array objects get their map
function. The array you create is the child object, and somewhere along its prototype chain is an Array
object that has the function defined on it.
SQL vs. NoSQL
SQL is a database model that relies on tables, rows, and columns to store data. One of the criticisms of SQL is "impedance mismatch," which describes the disconnect between object-oriented programming and models using tables, rows, and columns. The benefit of this model is that it supports data models with many connections, allowing you to join different tables using primary keys.
NoSQL is a database model which stores its data in documents, much like JSON, and therefore provides better locality. By locality, we mean that all the information about something is in one place; we do not need to join different tables. This leads to performance benefits and a better match between objects in programming and documents in databases. The disadvantage, however, is that models with many connections are less well-supported because joins do not exist. This often moves the logic of joining documents from the database side to the application side.
IP Addresses and Domain Name Servers (DNS)
A domain name is simply a human-readable text that masks an IP address. When you search for random.com
, the browser asks the DNS to find the IP address, which might be 181.12.34.56
.
- A Record: This IP address is stored under the
A
record, which stands for "address." So,random.com
is connected to that IP address by anA
record. - CNAME Record: A
CNAME
record either points to anotherCNAME
record or finally to anA
record. The DNS can respond toCNAME
records by following the chain until eventually returning anA
record and returning whatever resource is found at that IP address.
Server vs. Client Components
A server is a computer in a giant data center that stores your application code and receives requests to send responses. The client usually refers to the browser, which makes a request to the server for the application code and then turns it into a user interface (UI).
React lets you render and cache UI components on the server with Server Components, which has several key benefits:
- Performance: Moves non-interactive code to the server, which reduces the amount of client-side JavaScript that the browser has to download, parse, and execute. This leads to faster page load speeds.
- Security: Exposes less information to the client and user.
- User Experience: UI components are streamed to the client so that parts of the website are visible earlier, instead of waiting for the entire website to be rendered.
Server Components only live within the server environment; the browser never knows about them.
Client Components, in contrast, are pre-rendered on the server and then sent to the client. This allows client-side JavaScript to run in the browser and make these components interactive.
The benefits of Client Components include:
- They are interactive.
- They allow you to use React hooks such as useState
, useEffect
, and event listeners.
- They can also use browser APIs, having access to features like localStorage
.
Join the 10xdev Community
Subscribe and get 8+ free PDFs that contain detailed roadmaps with recommended learning periods for each programming language or field, along with links to free resources such as books, YouTube tutorials, and courses with certificates.