Unexpected Moments of JavaScript That Will Challenge Your Understanding of the Language

Code of Relevancy - Mar 18 '23 - - Dev Community

As one of the most popular programming languages in the world, JavaScript is widely used for building dynamic and interactive websites, web applications and even desktop and mobile applications. JavaScript is a gateway to other web technologies, because of its widespread use and compatibility with various platforms. It has become a foundational language in modern web development. It is also a complex language with many unexpected moments that can leave even the most experienced developers scratching their heads.

In this article, we'll see various unexpected JavaScript moments that can confuse, test your limits and frustrate you. It will also help you to change the way you code.

Are you ready to make your brain explode🤯? If so, let's enter the jungle..


1️⃣

2 == [2] // true
Enter fullscreen mode Exit fullscreen mode

== operator in JS performs type coercion which means it tries to convert the values being compared to a common data type before making the comparison.

In this instance, the number 2 is converted to a string and the array [2] is converted to a string as well. Resulting in both values being 2. That's why, the comparison evaluates to true.

It's generally recommended to use the strict equality operator === instead of == to avoid unexpected results due to type coercion..

Explore more:

'123' == 123        // true 
'foo' == NaN        // false
undefined == null   // true 
NaN === NaN         // false
NaN == NaN          // false
0 == null           // false
Enter fullscreen mode Exit fullscreen mode

2️⃣

[] == ![] // true
Enter fullscreen mode Exit fullscreen mode

Comparing an empty array [] with a boolean value created by negating (using the ! operator) a non empty array []. The result of this comparison is true, which might seem unexpected at first glance..

In JS, every value can be either true or false in a boolean context. An empty array is a truthy value, which means it's considered true in a boolean context. When we apply the ! operator to it, it's converted to false.

On the other side, the boolean value created by negating a non empty array is false. When we compare an empty array (truthy) with a false value (falsy) using the == operator, JS performs type constraint which means it tries to convert the values to a common type before comparing them. So, the empty array is converted to false which results in both sides being false. At the end, the comparison returns true.

Explore more:

['a', 'b'] !== ['a', 'b']   // true
['a', 'b'] == ['a', 'b']    // false
[1, 2] + [3, 4]             // "1,23,4" 
Enter fullscreen mode Exit fullscreen mode

3️⃣

null == undefined // true
Enter fullscreen mode Exit fullscreen mode

The double equals == operator is used to compare two values for equality, while ignoring their data type. When comparing the values null and undefined using the double equals operator they are considered equal and the result of the comparison will be true. This is because both null and undefined represent a lack of a value and are so equivalent to each other in this context.

With strict equality operator:

null === undefined // false
Enter fullscreen mode Exit fullscreen mode

4️⃣

typeof NaN   // number
typeof null  // object
Enter fullscreen mode Exit fullscreen mode

In JS, typeof is an operator used to determine the type of a value or variable.

NaN stands for Not a Number and is a special value in JS that represents an undefined or unrepresentable numerical value.

When you use typeof with NaN, it will return number. This might seem strange but it's because NaN is technically a numeric data type in JS even though it represents something that isn't actually a number.

When typeof is applied to null, it returns the string object. This is because null is considered to be a special value that represents an empty object reference. null is not an object itself but rather a primitive value. This is considered to be a quirk or oddity in the language design of JS.

Explore more:

typeof function(){}     // "function"
null instanceof Object  // false
Enter fullscreen mode Exit fullscreen mode

5️⃣

true == "1"  // true
false == "0" // true
Enter fullscreen mode Exit fullscreen mode

JS converts the string 1 to the boolean value true and string 0 to false because any non empty string is considered truthy and on other side falsy. So, the comparison becomes true == true which is true and false == false which is true.

Explore more:

1 + true      // 2
1 - true      // 0
'' == false   // true
0 == false    // true
true + false  // 1
Enter fullscreen mode Exit fullscreen mode

6️⃣

"1" + 1    // "11"
2 + "2"    // "22"
"5" - 3    // 2
Enter fullscreen mode Exit fullscreen mode

When you use the + operator with a string and a number, the number is converted to a string and concatenated to the string.

If the string can be parsed as a number, it will subtract the number from the string.

So,
"1" + 1 becomes the string "11"
2 + "2" becomes the string "22"
"5" - 3 becomes the number 2

Explore more:

+"1"                  // 1
-"1"                  // -1

+true                 // 1
-true                 // -1

+false                // 0
-false                // -0

+null                 // 0
+undefined            // NaN

1 / "2"               // 0.5
"2" / 1               // 2

1 / 0                 // Infinity
-1 / 0                // -Infinity

3 * "abc"             // NaN

true > false          // true  

undefined + 1         // NaN
undefined - 1         // NaN
undefined - undefined // NaN
undefined + undefined // NaN

null + 1              // 1
null - 1              // -1
null - null           // 0
null + null           // 0

Infinity + 1          // Infinity
Infinity - 1          // Infinity
Infinity - Infinity   // NaN
Infinity + Infinity   // Infinity
Infinity / Infinity   // NaN
Enter fullscreen mode Exit fullscreen mode

7️⃣

"b" + "a" + + "a" + "a" // "baNaNa"
Enter fullscreen mode Exit fullscreen mode

It concatenates the string b, the string a, the string resulting from the expression +"a" and the string a.

+"a" force the string a into a number which evaluates to NaN (Not a Number) because a is not a valid number.

When we concatenate b, a, NaN (represented as an empty string) and a, we get the string baNaNa.


8️⃣

!{}       // false
{} == !{} // false
{} == {}  // false
Enter fullscreen mode Exit fullscreen mode

When, we are comparing an empty object {} to a negated empty object !{}. The exclamation mark ! is a logical operator that negates the value of the object so !{} returns false since an object is considered truthy in JS. We are actually comparing {} to false which results in a false value since they are not equal in value or data type.

In the last expression, we are comparing two empty objects {}. Despite the fact that they may appear to be identical, they are two separate objects with distinct references in memory so they are not equal in value or data type. In the end the comparison also results in a false value.

When you use the plus operator + between two objects wrapped in curly braces {}, it tries to concatenate the objects as strings.

Explore more:

{} + [] === ""  // false
!!{}            // true 
!![]            // true 
[] + []         // ""
[] + {}         // "[object Object]"
{} + []         // "[object Object]"
{} + {}         // "[object Object][object Object]"
[] == false     // true
!!''            // false
!!0             // false
!!null          // false
!!undefined     // false 
Enter fullscreen mode Exit fullscreen mode

9️⃣

7 > 6 > 5 // false
Enter fullscreen mode Exit fullscreen mode

First, 7 > 6 evaluates to true because 7 is greater than 6.
Next, true > 5 is evaluated. In JS, true is force into the number 1 and false is force into 0. So 1 > 5 is false, since 1 is not greater than 5.

So at the end, 7 > 6 > 5 is equivalent to true > 5 which is false.

Explore more:

5 < 6 < 7  // true
0 > null   // false
Enter fullscreen mode Exit fullscreen mode

1️⃣0️⃣

Math.max() // -Infinity
Math.min() // Infinity
Enter fullscreen mode Exit fullscreen mode

Math.max() & Math.min() are functions that can be used to find the largest and smallest values in a set of numbers respectively.

When called without any arguments, Math.max() returns -Infinity which represents the smallest possible number in JS, on other side, Math.min() returns Infinity which represents the largest possible number in JS.

This behavior makes sense because if there are no numbers provided, there is no largest number to return for Math.max() and following same way, there is no smallest number to return for Math.min()


1️⃣1️⃣

parseInt('08')       // 8
parseInt('08', 10)   // 8 
parseInt('0x10')     // 16 
Enter fullscreen mode Exit fullscreen mode

parseInt('08') converts the string 08 into the integer number 8. If you were to write parseInt('08', 10), the function will still return 8.

The reason behind this is because the second parameter of parseInt function is the radix which specifies the numbering system to be used. Let's say: binary, octal, decimal, hexadecimal etc.. If the radix is not specified parseInt will try to detect the radix based on the string format. In above case, 08 is considered an octal number because it starts with 0 so it gets converted into 8 as a decimal number.

parseInt('0x10') converts the hexadecimal string 0x10 into the integer number 16. The radix is not specified either, but the prefix 0x indicates that the number should be treated as a hexadecimal number so it gets converted into 16 as a decimal number.

Explore more:

parseFloat('3.14.15')  // 3.14 
parseFloat('0.0')      // 0 
Enter fullscreen mode Exit fullscreen mode

1️⃣2️⃣

(function(x) { delete x; return x; })(1);   // 1
Enter fullscreen mode Exit fullscreen mode

An anonymous function that takes an argument x. Inside the function it tries to delete the x variable which is not possible because x is a function argument and cannot be deleted. The function then returns the value of x.

When this function is called with the argument 1, the value of x inside the function is set to 1. In this case, the delete operation has no effect, the function simply returns the value of x which is 1


1️⃣3️⃣
@tohodo from the DEV Community had a great point to add to this article. Let's see..

for (var i = 0; i < 3; ++i) {
  setTimeout(() => console.log(i), 1000); // returns 3 three times
}

for (let i = 0; i < 3; ++i) {
  setTimeout(() => console.log(i), 1000); // returns 0 1 2
}
Enter fullscreen mode Exit fullscreen mode

This is because var creates a single binding at the function scope, so after a one-second timeout the loop has already run its course, hence you get 3 three times. By using let you bind the variable at the block scope (loop), so it returns the values you expected since i refers to the value at that loop iteration.

Thanks to @tohodo for sharing this insight.


Great job exploring and understanding these JavaScript concepts!!! This knowledge will definitely help you in interviews and enable you to assess the skills of potential candidates as an interviewer. Keep up the good work and continue learning something Ctrl+N


❤ Motivation:

Motivation


🍀Support

Please consider following and supporting us by subscribing to our channel. Your support is greatly appreciated and will help us continue creating content for you to enjoy. Thank you in advance for your support!

YouTube
Discord
GitHub

Dour Darcel #8740

. . . . . . . . . . . . . . . . . . . . . . . . . . . . .