JavaScript things that make you hate learning it — Part 1

Mohammad Asif
5 min readJan 23, 2018

--

I have just started to learn JavaScript at a deeper level and have come across many concepts which make the JavaScript an ugly language. This is a going to be a series of collection of JavaScript things (concepts/syntax/bugs) which make any person hate learning it.

The null value is of type object!

The weirder it sounds the truer it is!
But it’s just a bug and is been there for such a long time that now if it’s fixed it might unsettle many applications and code written upon it.

You either die a hero, or you live long enough to see yourself become the villain.

Although any person in normal sense wouldn’t want to rely upon the typeof() of a potentially null object to be the "object" so as to confirm it’s null. But still, Who knows! There are people who try such stuff. Know more!

Overridden keys and String Coercion of Keys

Any person will expect “String Zero” and “Number Zero” consecutively but it logs “Number Zero” both the times. Because

  1. All the keys are internally coerced to strings hence both “0” and 0 should mean the same.
  2. In JavaScript objects the latest key overrides all the previous keys with the same string value.

Array coercion to strings

The reason for this behavior is very straight forward

  1. Both a and b are equal to c because when you compare an array and a string, the array is coerced into string as comma separated values.
  2. Although both a and b have the exact same arrays, internally there values are just references to the memory containing those arrays. Unless both of them have the same reference value they will never be equal.

NaN’s stubborn behavior

When you compare a number and a string, the string is coerced into it’s equivalent number and if it isn’t possible to make it a number it will make it NaN. And NaN has a unique quality that it can’t be less than, greater than or equal to anything, even itself.

The internal procedure can be interpreted as

a == b
42 == "foo"
42 == Number("foo")
42 == NaN // NaN - Because "foo" can't become any number

If you want to dig deep into NaN see this

No hoisting for let

It is normal to expect let to act same as var and the variables to get hoisted. But every let statement is treated as a normal assignment statement thus it is executed when the line is encountered. What’s hoisting?

Function expressions are not hoisted

Function expressions are not hoisted but we don’t get a ReferenceError rather a TypeError and the reason is that the variable foo is hoisted as usual but the value remains undefined till the execution reaches the function assignment line. As we presume the variable to be a function and call, it throws a TypeError as foo is not a function. Know More!

But

Now it throws a ReferenceError because as we didn’t use a var or let when declaring foo, it is added to the global object and thus becomes a global variable( actually it becomes a property of the global object) and this happens when the javascript engine encounters that very line where the variable is declared. So when foo is called before that as there so such variable existent, it throws a ReferenceError. See — The Horror of Implicit Globals

Closures

Consider this

The function alpha() returns the reference to its inner function beta()which has access to its inner variable a. Now as we call alpha() and assign its output to gamma() , it refers to beta()

Normally we would expect that the entirety of the inner scope of alpha() would go away, because we know that the JavaScript engine employs a garbage collector that comes along and frees up memory once it’s no longer in use. Since it would appear that the contents of alpha() are no longer in use, it would seem natural that they should be considered gone.

But NO!.

By virtue of where it was declared, beta() has a lexical scope closure over that inner scope of alpha(), which keeps that scope alive for beta() to reference at any later time.

beta() still has a reference to that scope, and that reference is called closure.

Later when the variable gamma is invoked (invoking the inner function we initially labeled beta), it duly has access to author-time lexical scope, so it can access the variable a just as we’d expect. Know Deeper!

To be continued…

P.S: I actually don’t hate learning JavaScript. It has some downs and we need to move on from them. After all it’s core was written in 10 days!

--

--