DEV Community

Cover image for Some JS Weirdness
BaasMurdo
BaasMurdo

Posted on

Some JS Weirdness

In reality, the seemingly strange behavior from Javascript could be an entire series of posts.
Before we get ahead of ourselves, let us start small and point out a couple of interesting Javascript behaviors.

baNaNa

"b" + "a" + +"a" + "a"; // -> 'baNaNa'
Enter fullscreen mode Exit fullscreen mode

This is an old-school joke in JavaScript, but remastered. Here's the original one:

"foo" + +"bar"; // -> 'fooNaN'
Enter fullscreen mode Exit fullscreen mode

💡 Explanation:

The expression is evaluated as 'foo' + (+'bar'), which converts 'bar' to not a number.

---------------------------------------------

NaN is not a NaN

NaN === NaN; // -> false
Enter fullscreen mode Exit fullscreen mode

💡 Explanation:

The specification strictly defines the logic behind this behavior:

  1. If Type(x) is different from Type(y), return false.
  2. If Type(x) is Number, then
    1. If x is NaN, return false.
    2. If y is NaN, return false.
    3. … … …

7.2.14 Strict Equality Comparison

Following the definition of NaN from the IEEE:

Four mutually exclusive relations are possible: less than, equal, greater than, and unordered. The last case arises when at least one operand is NaN. Every NaN shall compare unordered with everything, including itself.

“What is the rationale for all comparisons returning false for IEEE754 NaN values?” at StackOverflow

---------------------------------------------

It's a fail

You would not believe it, but …

(![] + [])[+[]] +
  (![] + [])[+!+[]] +
  ([![]] + [][[]])[+!+[] + [+[]]] +
  (![] + [])[!+[] + !+[]];
// -> 'fail'
Enter fullscreen mode Exit fullscreen mode

💡 Explanation:

By breaking that mass of symbols into pieces, we notice that the following pattern occurs often:

![] + []; // -> 'false'
![]; // -> false
Enter fullscreen mode Exit fullscreen mode

So we try adding [] to false. But due to a number of internal function calls (binary + Operator -> ToPrimitive -> [[DefaultValue]]) we end up converting the right operand to a string:

![] + [].toString(); // 'false'
Enter fullscreen mode Exit fullscreen mode

Thinking of a string as an array we can access its first character via [0]:

"false"[0]; // -> 'f'
Enter fullscreen mode Exit fullscreen mode

The rest is obvious, but the i is tricky. The i in fail is grabbed by generating the string 'falseundefined' and grabbing the element on index ['10'].

More examples:

+![]          // -> 0
+!![]         // -> 1
!![]          // -> true
![]           // -> false
[][[]]        // -> undefined
+!![] / +![]  // -> Infinity
[] + {}       // -> "[object Object]"
+{}           // -> NaN
Enter fullscreen mode Exit fullscreen mode

---------------------------------------------

Minimal value is greater than zero

Number.MIN_VALUE is the smallest number, which is greater than zero:

Number.MIN_VALUE > 0; // -> true
Enter fullscreen mode Exit fullscreen mode

💡 Explanation:

Number.MIN_VALUE is 5e-324, i.e. the smallest positive number that can be represented within float precision, i.e. that's as close as you can get to zero. It defines the best resolution that floats can give you.

Now the overall smallest value is Number.NEGATIVE_INFINITY although it's not really numeric in a strict sense.

“Why is 0 less than Number.MIN_VALUE in JavaScript?” at StackOverflow

Top comments (0)