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
π‘ 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
π‘ 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
false
is not the empty string, so it's a truthy value, so:
!!'false' // -> true
!!'true' // -> true
Cool, ha? π
baNaNa π
Let's create a banana:
'b' + 'a' + +'a' + 'a' // -> baNaNa
π‘ 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'
π‘ What's happening?
If we break this lot into smaller pieces, we notice that the following pattern occurs often:
![] + [] // -> 'false'
![] // -> false
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'
Thinking of a string as an array we can access its first character via [0]
:
'false'[0] // -> 'f'
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
π‘ 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
π‘ 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'
π‘ 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
π‘ 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
You can fix this with greater than or equal operator (>=
):
3 > 2 >= 1 // true
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)
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?"
I'm not sure typescript will save you from JavaScript itself maybe 50% of the above insanity.
The rest of 50% you can avoid by using '===' instead of '==' as it's recommended everywhere.
I always assumed everyone knew that π. It's been a while since I started.
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...
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
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 π§
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.
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?" - π€¨π.
Does not matter. Its another version of " __ can do that?". What matter the most is "can you do that?"
I have no idea what you meant
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
So it's not sarcasm just coincidence in titles. The only thing I wanted to ask π
The only valid reply to "... can do that?" is this meme:
memegenerator.net/img/instances/57...
Mind === blown.
Great article
I didn't know some of these and now I have more ambition to tease my colleagues
π
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".
Great article.
Thanks