DEV Community

Yaser Adel Mehraban
Yaser Adel Mehraban

Posted on • Originally published at yashints.dev

JavaScript can do that?

You might be wondering why I am writing less these days. I assure you, it's not because I am getting lazy (I am ATM 🤩), it's just that I am on a long overdue holiday. But to keep my juices going, I thought now that I am having fun, let's write a fun post 😊.

In this post I will go through some of the funniest yet unbelievable JavaScript snippets ever. Are you ready?

[] is equal ![]

Array is equal to not array 😂:

;[] == ![] // -> true
Enter fullscreen mode Exit fullscreen mode

💡 What's happening?

The abstract equality operator converts both sides to numbers before comparing them, and both sides will be converted to 0 for different reasons. Arrays are truthy, so the right hand side becomes false which then is coerced to 0. On the left however, the empty array is coerced to a number without becoming a boolean first, and empty arrays are coerced to 0, despite being truthy 🤯.

true is false

True is false:

!!'false' == !!'true' // -> true
!!'false' === !!'true' // -> true
Enter fullscreen mode Exit fullscreen mode

💡 What's happening?

true is truthy and is represented by value 1 (number), true in string form, is NaN. So:

true == 'true' // -> false
false == 'false' // -> false
Enter fullscreen mode Exit fullscreen mode

false is not the empty string, so it's a truthy value, so:

!!'false' // -> true
!!'true' // -> true
Enter fullscreen mode Exit fullscreen mode

Cool, ha? 😎

baNaNa 🍌

Let's create a banana:

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

💡 What's happening?

This one is an old trick, remixed. The expression is converted to "ba" + (+"a") + "a", and since "a" is converted to a number, it becomes NaN.

Let's fail

You wouldn't believe this in your wildest dreams, but:

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

💡 What's happening?

If we break this lot into smaller pieces, we notice that the following pattern occurs often:

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

We try adding [] to false, but because of a number of function calls internally, we'll end up converting the right operand into 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 taking the element on index ['10'].

Array equality is evil 👾

Array equality is evil in JavaScript, see below:

[] == ''   // -> true
[] == 0    // -> true
[''] == '' // -> true
[0] == 0   // -> true
[0] == ''  // -> false
[''] == 0  // -> true

[null] == ''      // true
[null] == 0       // true
[undefined] == '' // true
[undefined] == 0  // true

[[]] == 0  // true
[[]] == '' // true

[[[[[[]]]]]] == '' // true
[[[[[[]]]]]] == 0  // true

[[[[[[ null ]]]]]] == 0  // true
[[[[[[ null ]]]]]] == '' // true

[[[[[[ undefined ]]]]]] == 0  // true
[[[[[[ undefined ]]]]]] == '' // true
Enter fullscreen mode Exit fullscreen mode

💡 What's happening?

The explanation behind this is rather long. So I introduce you to section 7.2.13 Abstract Equality Comparison of the specification.

parseInt is just bad

parseInt is famous by its quirks, I just mention one of the most famous ones:

parseInt('f**k') // -> NaN
parseInt('f**k', 16) // -> 15
Enter fullscreen mode Exit fullscreen mode

💡 What's happening?

This happens because parseInt will continue parsing character by character until it hits one it doesn't know. The f in f**k is the hexadecimal digit 15.

NaN is not a number

Type of NaN is a number:

typeof NaN // -> 'number'
Enter fullscreen mode Exit fullscreen mode

💡 What's happening?

Explanations of how typeof and instanceof operators work:

Comparison of three numbers

This one is gold:

1 < 2 < 3 // -> true
3 > 2 > 1 // -> false
Enter fullscreen mode Exit fullscreen mode

💡 What's happening?

Why does this work that way? Well, the problem is in the first part of an expression. Here's how it works:

1 < 2 < 3 // 1 < 2 -> true
true < 3 // true -> 1
1 < 3 // -> true

3 > 2 > 1 // 3 > 2 -> true
true > 1 // true -> 1
1 > 1 // -> false
Enter fullscreen mode Exit fullscreen mode

You can fix this with greater than or equal operator (>=):

3 > 2 >= 1 // true
Enter fullscreen mode Exit fullscreen mode

Read more about Relational operators in the specification:

And that's just some of the fun we can have with JavaScript. No wonder some people do not like it, since they don't understand how it works 😂.

Top comments (20)

Collapse
 
cubiclebuddha profile image
Cubicle Buddha

This is one of the many great reasons to use TypeScript. It's not that TypeScript won't let you do these strange things... it's just that it's like "did you know that you're about to automatically coerce your number to a string?"

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

I'm not sure typescript will save you from JavaScript itself maybe 50% of the above insanity.

Collapse
 
tarascz profile image
Jiří Tarašovič

The rest of 50% you can avoid by using '===' instead of '==' as it's recommended everywhere.

Thread Thread
 
adam_cyclones profile image
Adam Crockett 🌀

I always assumed everyone knew that 😆. It's been a while since I started.

Collapse
 
nssimeonov profile image
Templar++

No amount of TypeScript can save you from JS quirks, but at least Saint A. Hejlsberg did a good job helping as much as he could...

Collapse
 
stephangalea profile image
Stephan Galea

These are all fun and games. Until someone asks them in a test during an interview or a programming test and you are one that never met such things because you have enough logic to never end up with such code :p

Collapse
 
yashints profile image
Yaser Adel Mehraban

If I ever got asked one of these in an interview, I'd question the company's approach to attract candidates. And it probably isn't a good place to work either 🧐

Collapse
 
nssimeonov profile image
Templar++

And if someone asks you anything like this during an interview, the only valid reply is that you're sane enough not to use it. Then stand up and walk out of... correction - run away as fast as possible.

Collapse
 
stereobooster profile image
stereobooster • Edited

I'm not sure if the article meant to be sarcasm or not. When I read "HTML can do that?" - 😲🤩, when I read "JS can do that?" - 🤨😞.

Collapse
 
sandeepbalachandran profile image
Sandeep Balachandran

Does not matter. Its another version of " __ can do that?". What matter the most is "can you do that?"

Collapse
 
stereobooster profile image
stereobooster

I have no idea what you meant

Thread Thread
 
yashints profile image
Yaser Adel Mehraban

I don't think comparison between posts is a valid thing to do, everyone has different perspectives, and if this has upset you, then it means you probably need to spend a bit more time reading about JS.
In another perspective, some of these might be the cause of a bug in your code base and knowing why it's happening will definitely help you

Thread Thread
 
stereobooster profile image
stereobooster

So it's not sarcasm just coincidence in titles. The only thing I wanted to ask 👌

Collapse
 
nssimeonov profile image
Templar++

The only valid reply to "... can do that?" is this meme:

memegenerator.net/img/instances/57...

Collapse
 
raisaugat profile image
Saugat Rai

Mind === blown.
Great article

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

I didn't know some of these and now I have more ambition to tease my colleagues

Collapse
 
yashints profile image
Yaser Adel Mehraban

😂

Collapse
 
stefanbalan profile image
Stefan Balan

This is NOT a 3 minute read! :)
It's a 3 minute read plus 5 minutes of "let me open up the console real quick".

Collapse
 
elanandkumar profile image
Anand Kumar

Great article.

Collapse
 
yashints profile image
Yaser Adel Mehraban

Thanks