The \'Wat\' talk for CodeMash 2012 basically points out a few bizarre quirks with Ruby and JavaScript.
I have made a JSFiddle of the results at http://jsfid
We may refer to the specification and that's great and most accurate, but most of the cases can also be explained in a more comprehensible way with the following statements:
+
and -
operators work only with primitive values. More specifically +
(addition) works with either strings or numbers, and +
(unary) and -
(subtraction and unary) works only with numbers.valueOf
or toString
, which are available on any object. That's the reason why such functions or operators don't throw errors when invoked on objects.So we may say that:
[] + []
is same as String([]) + String([])
which is same as '' + ''
. I mentioned above that +
(addition) is also valid for numbers, but there is no valid number representation of an array in JavaScript, so addition of strings is used instead.[] + {}
is same as String([]) + String({})
which is same as '' + '[object Object]'
{} + []
. This one deserves more explanation (see Ventero answer). In that case, curly braces are treated not as an object but as an empty block, so it turns out to be same as +[]
. Unary +
works only with numbers, so the implementation tries to get a number out of []
. First it tries valueOf
which in the case of arrays returns the same object, so then it tries the last resort: conversion of a toString
result to a number. We may write it as +Number(String([]))
which is same as +Number('')
which is same as +0
.Array(16).join("wat" - 1)
subtraction -
works only with numbers, so it's the same as: Array(16).join(Number("wat") - 1)
, as "wat"
can't be converted to a valid number. We receive NaN
, and any arithmetic operation on NaN
results with NaN
, so we have: Array(16).join(NaN)
.