Javascript is a programming language that was initially made in ten days. The first working prototype was made in May, 1995.

But what about today's version ? Well, I found two really good presentations thanks to Blue about Javascript.


I wanted to talk about some weird things I've seen in those two talks and explain how Javascript works and why sometimes it is doing "insane" things.

Weird things explained

Let's start with a few examples that show that Javascript lacks of logic when it comes to variable types.

Here is an example:

> [] + []
''  

In any other language you would have either a type error or an empty array. That would seems logical. In Javascript however, you get an empty string.

Why ? Javascript converts left and right operands to primitives first. Converting an object to a primitive returns the default value. For an object it will be the myObject.toString() method and for an array it will be the same as array.join(). With an empty array this will result in an empty string and the concatenation of two empty strings gives obviously an empty string.

Now let's have a look at this following code:

> [] + {}
'[object Object]'  

This is nearly the same thing. The empty array gives an empty string via the array.join() method. And myObject.toString() gives [object Object].

> {} + []
0  

Here something new happens.
{} is not parsed as an empty object but as an empty block ({/*empty block */};). So nothing happens. The statement looks more like that {/*empty block */}; +[]. So the + operator is the unary + operator. Javascript converts [] into a primitive which gives an empty string and then do toNumber('') which gives 0.

Cheat type sheet

Here is a quick summary of string and numeric values associated to a primitive.

Primitive Value String value Numeric value
[] "" 0
{} [object Object] NaN
null "null" 0
undefined "undefined" NaN
123 "123" 123
true "true" 1
false "false" 0


When it gets even weirder

Javascript is really sensitive and... you shouldn't ask too much!

> x = ['10', '10', '10']
[ '10', '10', '10' ]
> x.map(parseInt)
[ 10, NaN, 2 ]

It looks like a really strange result. In fact in most other languages the result would have been
[10, 10, 10]. However, the prototype of parseInt is parseInt(string, radix); with

  • string the value to parse
  • radix a number between 2 and 36 that represents the base in mathematical numeric number

So, what we get is in fact the result of three function calls :

> parseInt('10', 0)
10  
> parseInt('10', 1); // base 1 does not exists
NaN  
> parseInt('10', 2);
2  

Here 0, 1 and 2 are in fact the index of the previous array.

Now let's have a look at this

> y = {}; // Define an empty object
> y[[]] = 1; // Set a key to an empty object
> Object.keys(y); // Display all keys
['']

So here we can see that all keys are converted to a string which is most of the time not what you want. So you have to be really careful when using Object keys and know that typically they can only be strings. Javascript does not have a real hash-map.

Conclusion

One way to make sure that Javascript is somehow type safe is to use a JS compiler like Babel and enforce strong type by using Flow (a Facebook project).

If you have any suggestions on the article or you would like to tell the way you use Javascript, let me know in the comments below.