Javascript Thought of the Day

Now, Javascript surely doesn't have the best reputation around for being a well-designed language, but I often feel like being an apologist for it, much in the same way that I truly enjoy the ethos and aesthetics of Bash as a programming language in its own right. They might have warts, but they're not arbitrary. Although Gary Bernhardt's now-classic WAT highlights some ridiculous consequences of Javascript's type conversion system, they are nonetheless explainable in a consistent way. In the JSC interpreter:

> [] + []

> [] + {}
[object Object]
> {} + []
0
> {} + {}
NaN

So while this is certainly WAT, it also can be explained relatively easily. The + operator can either add numbers, concatenate strings, or be used to specify a positive number. So, [] + [] is really empty string, and [] + {} is really empty string plus the string representation of {}, which is '[object Object]'. In fact, the Node interpreter makes this clear:

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

Then, the final two are interpreted by JSC as empty code blocks followed by something that must be coerced into a numeric value via its string representation. Roughly:

> + Number([].toString())
0
> + Number({}.toString())
NaN

So these at least have some straightforward logical explanations, based on understanding Javascript's parsing and type coercion. But how on earth could we allow this to happen?

> Boolean([0])
true
> [0] == true
false

That the path to a boolean using Boolean is separate from the path to a boolean using == might seem downright nuts, except when one realizes that the == operator is used for far more than truth comparisons. The two use entirely different algorithms for determining the final evaluation.