Advanced JavaScript - Episode 4
- Duong Hoang
- Jul 15, 2024
- 6 min read
There's a saying: "In this world, there are only two kinds of things: those that many people curse and those that no one bothers to use."
JavaScript is a prime example of this. It has some interesting aspects but can also give us headaches. The theory is easy to understand, but when it comes to practice, it's a whole different story. So, I'll dive deep into specific examples with you and analyze them to better understand JavaScript.
This series might be quite long; I don't know how many episodes there will be. However, for those who haven't read my previous posts about JS, I'll explain everything again in this series. I might also explain the theories multiple times (depending on my mood) so you can understand them better. Okay, let's get started... LET'S GO 🚀
If you have any questions, don't hesitate to comment below. Or just leave a comment to say hi; that alone will give me more motivation to complete this series. Thank you very much. 🤗

1. Increment in JavaScript
You've probably seen and used the ++ operator in JavaScript (or other programming languages). It's an interesting and common operator but can sometimes be a bit confusing for beginners. Let's explore the issue with the following example:
let number = 0;
console.log(number++);
console.log(++number);
console.log(number);
The output of the above code will be:
A: 1 1 2
B: 1 2 2
C: 0 2 2
D: 0 1 2
The correct answer is ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ The answer: C
To make it easier to remember, I'll compare this operation to buying bread. Imagine when you go to a store; before buying, you want to know the price. After knowing the price, you decide whether to buy or not. Or the opposite, you buy it right away without knowing the price and ask about the price afterward. That's the difference between having the ++ operator before or after the variable.
1.1 Postfix Increment (number++) When you see number++, imagine you are asking the price of bread first:
Return the original value of number (in this case, 0).
Increase the value of number by 1. Thus, the console.log(number++) statement will output 0, but afterward, the value of number has increased to 1.
1.2 Prefix Increment (++number) When you see ++number, it's like buying bread without knowing the price first:
Increase the value of number first (from 1 to 2).
Return the new value of number (which becomes 2). So, the console.log(++number) statement will display 2.
1.3 Final Result At the end of the code, number has been incremented twice and has a final value of 2. So, the console.log(number) statement will display 2.
Therefore, the correct result of the code is:
0
2
2
Just like the answer C that you provided. Very simple and easy to understand, right? I hope with this bread-buying example, you will remember and apply this increment operation more easily.
2. Tagged Template Literals
We have the following JavaScript code:
function getPersonInfo(one, two, three) {
console.log(one);
console.log(two);
console.log(three);
}
const person = "Lydia";
const age = 21;
getPersonInfo`${person} is ${age} years old`;
When running the above code, what is the output?
A: "Lydia" 21 ["", " is ", " years old"]
B: ["", " is ", " years old"] "Lydia" 21
C: "Lydia" ["", " is ", " years old"] 21
The correct answer is ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ The answer: B
2.2 Basics of Template Literals
Before explaining the above issue, you need to understand template literals in JavaScript. Template literals (started and ended with backticks `) allow you to easily embed variables or expressions into strings:
let name = "Tony";
console.log(`Hello ${name}!`); // Hello Tony!
2.2. Tagged Template Literals: What are they? Tagged template literals are an advanced way to use template literals. They allow you to use a function to process a template literal.
So, getPersonInfo in our code is a "tag" for the template literal.
2.3 How do Tagged Template Literals work? When you use a tag for a template literal, the strings and expressions in that template literal are "decomposed" and passed into the function as parameters.
The order of the parameters is important to note:
First argument: An array of strings
Subsequent arguments: Values of the expressions in the template literal
2.4 Applying it to our issue Consider our code:
getPersonInfo`${person} is ${age} years old`;
one (the first argument) will receive an array of strings: ["", " is ", " years old"]
two (the second argument) will receive the value from the first expression: "Lydia"
three (the third argument) will receive the value from the second expression: 21
Thus, the output will be: ["", " is ", " years old"] "Lydia" 21
2.5 Another Example To understand better, let's try another example:
function testTag(one, two, three, four) {
console.log(one);
console.log(two);
console.log(three);
console.log(four);
}
let fruit = "apple";
let price = 10000;
testTag`One kg of ${fruit} costs ${price} yen.`;
The output will be:
["One kg of ", " costs ", " yen."]
"apple"
10000
undefined
=> Tagged Template Literals are a powerful tool, allowing you to customize how template literals work.
3. Comparison in JavaScript
function checkAge(data) {
if (data === { age: 18 }) {
console.log("You are an adult!");
} else if (data == { age: 18 }) {
console.log("You are still an adult.");
} else {
console.log(`Hmm.. You don't have an age I guess`);
}
}
checkAge({ age: 18 });
When running the above code, what is the output?
A: You are an adult! B: You are still an adult. C: Hmm.. You don't have an age I guess
The correct answer is ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓ The answer: C
This question requires determining the output after running checkAge({ age: 18 });. This relates to how JavaScript compares values and references, especially in the case of objects.
3.1 Inside the code First, let's consider the function checkAge(data):
This function checks if data is equal to { age: 18 } (using the strict equality operator ===), it will print "You are an adult!".
If data is equal to { age: 18 } (using the loose equality operator ==), it will print "You are still an adult.".
Otherwise, it will print "Hmm.. You don't have an age I guess."
3.2 Comparison in JavaScript In JavaScript, we have two types of comparison:
3.2.1 Strict Equality (===) Both the value and type must be equal.
console.log(3 === 3); // true
console.log('3' === 3); // false because the data types are different
3.2.2 Loose Equality (==) Only checks the value, not the data type.
console.log('3' == 3); // true
console.log(true == 1); // true
3.3 Object Comparison Now we'll get to the most interesting part, comparing objects.
3.3.1 Reference Comparison We know that when comparing objects in JS, we are not comparing the content inside them, but rather comparing their reference addresses.
Consider the following example:
const person1 = { name: "Man" };
const person2 = { name: "Man" };
console.log(person1 === person2); // false
In this case, person1 and person2 have the same content but point to different reference addresses in memory. Thus, person1 === person2 is false.
3.3.2 Same Reference Comparison Now let's change the reference:
const person3 = person1;
console.log(person1 === person3); // true
Now, person1 and person3 point to the same address in memory, so person1 === person3 is true.
3.4 Applying to our case Let's re-examine our code:
checkAge({ age: 18 });
In the first check, data === { age: 18 }:
This is a strict comparison.
data is a newly created object { age: 18 }.
The object { age: 18 } in the check is a completely different object.
Thus, data and { age: 18 } point to different addresses in memory, and data === { age: 18 } will be false.
In the second check, data == { age: 18 }:
This is a loose comparison.
JavaScript doesn't convert object types, even in a loose comparison. Thus, this will still compare the reference.
Therefore, data == { age: 18 } will also be false.
Consequently, the else block will be executed, and "Hmm.. You don't have an age I guess" will be printed.
So, the answer is C: "Hmm.. You don't have an age I guess".
4. Clean Code
From this section onwards, we will learn more advanced aspects of JS. The previous content is relatively basic, and I believe many of you already know it.
We often see code like this:
var isNumber = function (value) {
return typeof value === 'number';
};
console.log(isNumber(2)); // true
console.log(isNumber('Hello')); // false
The code is not bad at all, but I think we can write it better, shorter, and clearer by writing it as an arrow function:
const isNumber = value => typeof value === 'number';
console.log(isNumber(2)); // true
console.log(isNumber('Hello')); // false
By reducing unnecessary syntax, the code becomes more readable and maintainable.
4.2 Implicit Return
When the arrow function has only one expression, you can omit the curly braces {} and the return keyword:
const add = (a, b) => a + b;
Instead of:
const add = function(a, b) {
return a + b;
};
5. bind in JavaScript
Let's consider an example where bind is often used:
const person = {
firstName: "Tony",
lastName: "Stark",
fullName: function() {
return `${this.firstName} ${this.lastName}`;
}
};
const fullName = person.fullName.bind(person);
console.log(fullName()); // Tony Stark
In the code above, the fullName function inside the person object is assigned to a variable. Without the bind method, this inside the fullName function would refer to the global object or be undefined in strict mode.
Using the bind method ensures this inside the fullName function always refers to the person object.
Comments