Weird Side of Javascript

Peculiarities of JavaScript and deatiled explanation of some of the scenarios.

Author

Thivagar Mahendran

Dec 15, 2023

JavaScript is one of the most popular scripting languages in the world and has given birth to countless frameworks and libraries. However, among developers, it is widely acknowledged that JavaScript can sometimes behave in unexpected ways. This "weird side" of JavaScript is a well-known phenomenon within the community of JavaScript developers.

In this article let's discuss some of the scenarios which create this phenomenon in JavaScript.

Phenomenon #1

[] == ![] //output: true

Can you guess the output of the above comparison? If you had guessed false it is wrong. The == operator converts both sides of the comparison to numbers. In JavaScript, arrays are always considered true, but empty arrays are treated as 0 when coerced. Thus, the left side of the comparison results in 0. As arrays are always true, the left side evaluates to true. On the other hand, the right side is coerced to 0, which is considered false.

Phenomenon #2

{} + [] // 0 [] + {} // '[object Object]'

Generally in JavaScript + operator can behave as either arithmetic addition or string concatenation depending on the types and positions(left or right) of operands.

In the {} + [] phenomenon {} is considered an empty code block and will be ignored, the + [] converts [] into a number because empty arrays are always coerced to 0. In other words + [] is equivalent to + "" (because [] is converted to an empty string), and that's equal to 0 (the unary plus operator converts the empty string to 0).

In the [] + {} scenario both operands are considered objects and they will be converted to strings when trying to concatenate them. Empty array [] becomes an empty string "", and the empty object becomes "[object Object]". As a result "" + "[object Object]" equals to "[object Object]".

Phenomenon #3

Math.min() > Math.max() // true

Both the Math functions min() and max() returns the smallest and largest numbers, respectively, among the provided arguments. However, if there are no arguments provided, they behave unexpectedly.

  • Math.min() returns Infinity. This is because Infinity is conceptually larger than any other number, so if you're looking for a minimum with no numbers to compare, Infinity is returned.

  • Math.max() returns -Infinity. This is because -Infinity is conceptually smaller than any other number, so if you're looking for a maximum with no numbers to compare, -Infinity is returned.

Hence the above phenomenon returns true as obvious it is Infinity is greater than -Infinity.

Phenomenon #4

['1', '7', '11'].map(parseInt); // [1, NaN, 3]

The map function in JavaScript passes three arguments to the provided function: the element, the index, and the original array.

When you call ['1', '7', '11'].map(parseInt), parseInt is being called with three arguments for each element in the array. parseInt takes up to two arguments: the string to parse and the radix (the base in mathematical numeral systems).

Here's what's happening for each element:

  • '1': parseInt is called as parseInt('1', 0, array). The radix 0 (or undefined) means the radix is determined by the number's format, so '1' is parsed as a base-10 number, which is 1.
  • '7': parseInt is called as parseInt('7', 1, array). The radix 1 is not valid (valid radices are between 2 and 36), so this returns NaN.
  • '11': parseInt is called as parseInt('11', 2, array). '11' is parsed as a binary number (because of radix 2), 3 in base-10.

So, ['1', '7', '11'].map(parseInt) returns [1, NaN, 3]. This is a common gotcha in JavaScript related to how parseInt works with map()!

Phenomenon #5

typeof null // object

This behaviour has existed since the beginning of JavaScript. It was considered to be a bug from the initial implementation of JavaScript! 

In JavaScript, every value has an internal [[Class]] property that depicts its type. For null, this property should not exist at all, as null represents the absence of value. However, due to a mistake in the initial implementation, null was given the [[Class]] property of 'Object'.

This bug was never corrected to avoid breaking the existing codebase. As a result, typeof null incorrectly returns 'object' even though null is not an object.

Conclusion

The peculiar behaviours mentioned above have been present since the beginning of JavaScript. However, it's important to be aware of such behaviours in the language's ecosystem so that developers can avoid confusion while developing their projects. In this article, I have only briefly touched upon a few of the peculiarities of JavaScript. I will write another article soon to cover the other existing behaviours as well.

Till then, See you in the next article! 💙

Made with Next.js, Tailwind CSS and some ❤️ , deployed in Vercel