JavaScript: Where Weirdness is the Norm!

Jeffer Marcelino
8 min readJun 14, 2023

--

JavaScript, a wonderful programming language to learn for beginners, is also a challenging language to learn for beginners. It allows you to build anything and find job opportunities everywhere. On the other hand, it can be weird, messy, and has an abundance of frameworks and libraries.

JavaScript was invented by Brendan Eich in 1995, in just 10 days. It was initially named “Mocha” and later changed to “LiveScript” before finally settling on “JavaScript” to leverage the popularity of Java. It’s important to note that JavaScript is not the same as Java.

Here are some of the weird things about JavaScript:

Sort method: “The Quirks of JavaScript’s Sort Method”

[1, 2, 10, 3].sort();

If you have programmed in other languages before, you probably think that the output will be [1, 2, 3, 10]. However, JavaScript is a language with many surprises. Here’s the output:

[1, 10, 2, 3]

But why does this happen? This occurs because in JavaScript, the sort() method is designed to be used with a callback function as an argument to create a custom sorting method. By default, the sort order is ascending, based on converting the elements into strings and comparing their sequences of UTF-16 code unit values.

To achieve the expected result, you need to use the following approach:

[1, 2, 10, 3].sort((a, b) => (a - b))

This will perform a numerical comparison and sort the array correctly.

Comparing null to 0: “Understanding JavaScript’s Comparison of Null and Zero”

null == 0; // -> false
null > 0; // -> false
null >= 0; // -> true

The behavior you’re observing is a result of how JavaScript handles comparisons involving null and numeric values.

In JavaScript, the == operator checks for equality, and when comparing null to a numeric value like 0, it returns false because null is not equal to 0. This is because null represents the intentional absence of any object value, while 0 is a numeric value. However, if you explicitly convert null to a number using Number(null), it will be equal to 0 and the expression Number(null) == 0 will evaluate to true.

On the other hand, when you use the >= or > operator, JavaScript behaves differently. When comparing null to 0 using the >= or > operator, JavaScript implicitly converts null to a numeric value, which is 0. Therefore, null >= 0 returns true because 0 is equal to 0, and null > 0 returns false.

This behavior can be a bit confusing, but it’s important to understand that null is a special value in JavaScript, and its behavior in comparisons may not always follow the same logic as other values.

NaN is not a NaN: “JavaScript’s NaN: An Unusual Non-Equality”

NaN === NaN; // -> false

In JavaScript, the expression NaN === NaN evaluates to false.

The reason for this behavior is that NaN (which stands for "Not-a-Number") is a special value representing an invalid or unrepresentable numeric result. Due to its unique nature as a non-numeric value, it does not equal itself according to the strict equality comparison (===) in JavaScript.

If you need to check for NaN in JavaScript, you can use the isNaN() function, which returns true for NaN values:

isNaN(NaN); // true

Additionally, there is a global property called Number.NaN, which also represents NaN and can be used for comparison:

Number.NaN === NaN; // true

It’s worth noting that when using the non-strict equality operator (==), NaN is not equal to any value, including itself. So, NaN == NaN would also evaluate to false.

Adding arrays: “Concatenating Arrays in JavaScript: Pitfalls and Solutions”

[1, 2, 3] + [4, 5, 6]; // -> '1,2,34,5,6'

In JavaScript, the + operator is primarily used for string concatenation. When you use the + perator between two arrays, JavaScript implicitly converts the arrays to strings before concatenating them.

The default string representation of an array is obtained by calling the toString() method on the array. This method converts each element to its string representation and joins them with commas.

In the expression [1, 2, 3] + [4, 5, 6], both arrays are converted to strings using their default string representation, resulting in “1,2,3” + “4,5,6”. The concatenation of these two strings gives “1,2,34,5,6”.

If you want to combine the elements of the two arrays and get the desired result of [1, 2, 3, 4, 5, 6], you can use the concat() method or the spread operator (...). Here are examples of how to achieve that:

Using concat():

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const concatenatedArray = array1.concat(array2);
console.log(concatenatedArray); // Output: [1, 2, 3, 4, 5, 6]

Using spread operator:

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const concatenatedArray = [...array1, ...array2];
console.log(concatenatedArray); // Output: [1, 2, 3, 4, 5, 6]

Both methods properly combine the elements of the two arrays into a new array without converting them to strings.

Magically increasing numbers: “Numeric Precision in JavaScript: Dealing with Large Numbers”

999999999999999;         // -> 999999999999999
9999999999999999; // -> 10000000000000000

10000000000000000; // -> 10000000000000000
10000000000000000 + 1; // -> 10000000000000000
10000000000000000 + 1.1; // -> 10000000000000002

In JavaScript, numbers are represented internally using the double-precision 64-bit binary format (IEEE 754). This format has a limited precision, which means that there is a maximum number that can be accurately represented. This maximum value is approximately 9 quadrillion (or 9 quadrillion minus 1).

When you exceed this maximum value, JavaScript starts to lose precision, resulting in unexpected behavior. In the case of 9999999999999999, which is larger than the maximum representable value, JavaScript rounds it to the nearest accurately representable number, which is 10000000000000000. This rounding behavior is due to the limitations of the underlying numeric format.

Therefore, when you perform calculations or additions involving such large numbers, the results may not always be what you expect.

In the case of 10000000000000000 + 1, JavaScript does not have the necessary precision to accurately represent the result. As a result, it returns the same value 10000000000000000, as it cannot accurately represent the addition.

Similarly, in the case of 10000000000000000 + 1.1, JavaScript performs the addition but rounds the result to the nearest accurately representable number. In this case, it returns 10000000000000002 because it can accurately represent that value.

To work with extremely large numbers and maintain precision, you can use libraries like BigInt or specialized numeric libraries available in JavaScript. These libraries provide support for arbitrary precision arithmetic, allowing you to work with numbers of any size without losing precision.

Investigating Truth in JavaScript: “JavaScript’s Boolean Behavior: Exploring Truth and Equality”

true + true + true === 3; // true
true - true === 0; // true
true == 1; // true
true !== 1; // true

In JavaScript, the boolean value true can be implicitly coerced to the numeric value 1 in certain contexts. When you perform arithmetic operations involving boolean values, they are converted to their numeric representations.

In the expression true + true + true === 3, the addition of three true values results in 1 + 1 + 1, which indeed equals 3. Here, the + operator performs numeric addition, and the boolean values are implicitly coerced to their numeric representation.

Similarly, in the expression true - true === 0, the subtraction of true from true results in 1 - 1, which equals 0. Again, the - operator performs numeric subtraction, and the boolean values are implicitly coerced to their numeric representation.

Regarding the comparison true == 1, JavaScript performs type coercion and treats the boolean true as the numeric value 1. Therefore, true == 1 evaluates to true. However, the strict equality comparison true === 1 evaluates to false because it checks for both value and type equality, and the boolean true and numeric 1 are of different types.

Precision of 0.1 + 0.2: “Understanding Floating-Point Arithmetic in JavaScript”

0.1 + 0.2 === 0.3; // -> false

In JavaScript, the result of the arithmetic operation 0.1 + 0.2 is not exactly equal to 0.3. This behavior is due to the way floating-point numbers are represented and handled by the JavaScript language.

Floating-point numbers in JavaScript (and many other programming languages) are stored using the binary representation of numbers. However, certain decimal numbers, such as 0.1 and 0.2, cannot be represented exactly in binary.

When you perform the addition 0.1 + 0.2, the result is a value that is very close to, but not exactly, 0.3. This is because the binary representation introduces a small rounding error.

The actual result of 0.1 + 0.2 is 0.30000000000000004, which is a very close approximation of 0.3. This rounding error is a common issue when working with floating-point arithmetic.

To illustrate this behavior further, you can visit the website 30000000000000004. This website explains the topic in more detail and demonstrates the issue with interactive examples.

HTML comments are valid in JavaScript: “JavaScript’s Treatment of HTML Comments: Insights and Best Practices”

// valid comment
<! - valid comment too

The reason HTML comments (<!-- ... -->) are treated as valid comments in JavaScript code is because JavaScript parsers ignore them as part of the parsing process.

When the JavaScript parser encounters an HTML comment, it treats it as a sequence of characters that should be skipped and not considered as executable code. This behavior allows developers to include HTML comments within JavaScript code without causing any issues or errors.

However, it’s important to note that using HTML comments within JavaScript code is generally not recommended or considered good practice. JavaScript provides its own comment syntax using // for single-line comments and /* ... */ for multi-line comments. It's best to use these standard JavaScript comment formats for better code clarity, maintainability, and compatibility with JavaScript tools and environments.

Using JavaScript-specific comments also helps ensure that your code remains readable and understandable by other developers who might be working on the project. It promotes consistency and avoids any potential confusion or conflicts between JavaScript and HTML comment syntax.

In summary, while JavaScript parsers allow HTML comments within JavaScript code, it’s advisable to adhere to the standard JavaScript comment syntax for better code organization and compatibility.

For those who have found the strange and weird aspects of JavaScript intriguing and want to dive deeper into this fascinating realm, I highly recommend visiting the GitHub repository wtfjs.

JavaScript indeed has its share of strange and weird aspects, but it remains a widely used language in today’s job market. If your goal is to quickly enter the job market and start building web applications, JavaScript is a solid choice. However, if you have a deeper curiosity and desire to understand the inner workings of programming languages, I would recommend exploring languages like Java or C. These languages provide a closer look at the fundamental concepts and mechanics of programming, allowing you to gain a deeper understanding of how things operate beneath the surface. Ultimately, the choice depends on your specific goals and interests.

--

--

Jeffer Marcelino

Software Engineer and passionate about Web development and Software Architecture.