DEV Community

Cover image for JavaScript - Things
Facundo Botta
Facundo Botta

Posted on

JavaScript - Things

Introduction

In this post, I want to share some JavaScript behaviors that often seem nonsensical at first, but actually reveal something about the language’s nature. Understanding them can help us avoid mistakes — and even take advantage of them.

The following examples are inspired by the book Eloquent JavaScript and by the quiz on JS is Weird web's site.
Another interesting resource, not taken into account for these examples, is jsdata.wtf that shows unexpected, or not so much, behaviors of the Date object.

So:

true + false === 1

Boolean values are converted into their numeric counterparts:

Number(true); // -> 1
Number(false); // -> 0
1 + 0; // -> 1
Enter fullscreen mode Exit fullscreen mode

!!"" === false

The double exclamation mark (double NOT) converts any value to its corresponding boolean, based on its truthiness or falsiness, just like the Boolean() function :

!!""; // -> false ("" is falsy)
Boolean(""); // -> false
!!0; // -> false
!!"hello"; // -> true
!!666; // -> true
Enter fullscreen mode Exit fullscreen mode

+true === 1

This is an example of type coercion, its minds JS tries to convert a value to a number. Internally JS use the Number() function:

Number(true); // -> 1
Enter fullscreen mode Exit fullscreen mode

true == "true" // false

Here the loose equality operator (==) tries to convert the values to number:

Number(true); // -> 1
Number("true"); // -> NaN
1 == NaN; // -> false
Enter fullscreen mode Exit fullscreen mode

null + 0 === 0

When performing arithmetic, null is coerced to 0:

Number(null); // -> 0
0 + 0; // -> 0
Enter fullscreen mode Exit fullscreen mode

if ([] == false) → true but if ([]) → true

This one shows how truthiness and type coercion are two different mechanisms:

  • if([]) When you use a value inside an if statement, JavaScript simply checks its truthiness — no type conversion, no comparison.
if ([]) console.log("truthy"); // → truthy
Enter fullscreen mode Exit fullscreen mode

Arrays (and any non-null objects) are truthy, even if they’re empty:

!![]; // -> true
Boolean([]); // → true
Enter fullscreen mode Exit fullscreen mode
  • if ([] == false)

Now we’re using the loose equality operator ==, which triggers type coercion and the rules changes.
When comparing an object [] and a boolean false, JavaScript first converts the boolean to a number:

Number(false); // -> 0
// So we get
[] == 0;
Enter fullscreen mode Exit fullscreen mode

Then it tries to convert the array to a primitive value (a number or string).
For an empty array:

[].toString(); // → ""
Number("");    // → 0
Enter fullscreen mode Exit fullscreen mode

Finally we have:

0 == 0; // -> true
Enter fullscreen mode Exit fullscreen mode

JS uses truthiness for if(x) and type coercion for x == y, that’s why something can be truthy and loosely equal to false at the same time.
We have the === operator to avoid these surprises...


0.1 + 0.2 !== 0.3

This behavior comes from how floating point numbers are represented based on the IEEE-754 standard used by JS and every major language.
The result is actually 0.30000000000000004, if you want to know more check the https://0.30000000000000004.com/ web site.


NaN !== NaN

A Not a Number value is, by definition, not equal to anything... not even to itself


'5' - 3 === 2 but '5' + 2 === '53'

The - operator always expects numbers, so '5' becomes 5.

But the + operator can mean addition or string concatenation, so if one operand is a string, the string concatenation wins.


'' == 0 -> true

The empty string is falsy and JS convert it to 0:

Number(''); // → 0
0 == 0;     // → true
Enter fullscreen mode Exit fullscreen mode

0/0 -> NaN

In divisions by 0, JavaScript does not always behave the same way:

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

This behavior is caused too by the IEEE-754 standard that JS uses for its numbers.


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

Ones again the + operator treats values like strings if they are not numbers, so it performs a string concatenation with the two arrays.

If you want to save the , you have to put it before the 4:

[1,2,3] + [,4,5,6] // -> "1,2,3,4,5,6"
Enter fullscreen mode Exit fullscreen mode

But not after the 3 because of the trailing coma will be ignored.


Conclution

This list could go on with more and more examples, but as you start to understand the why, the examples start to sound repetitive.

Most of these behaviors, which seem “weird” at first, are actually the result of how the language uses different strategies to handle the values it receives.
We can recognize in these examples some of JavasCript's main strategies, like type coercion and truthiness.

It’s thanks to those decisions JavaScript makes for us that we get certain freedoms — to be care, and to be creative too, like:

('b' + 'a' + + 'a' + 'a').toLowerCase(); // -> "banana"
Enter fullscreen mode Exit fullscreen mode

😁 Thanks for reading!

Top comments (0)