A friend of mine discovered some interesting behaviour in some Javascript code, which I decided to investigate further.
The comparison
(function (x) {return x*x;}) > [1,2,3]
returns true in most major browsers (Firefox, Chrome, Opera and Safari) and false in IE9. To me, there is no logical result of this comparison other than undefined as there is no way to say that a function is greater than an array.
Reading up on this in the ECMA-script standard, it says that the actual arguments of > when it is used on objects are the result of calling the ToNumber internal operation on the arguments. Some experiments and further reading tells me that this is not the same as applying a type conversion such as (Number) arg. Reading the specification, I have a hard time figuring out what’s going on here.
Can anyone fill me in on what’s really happening here?
The operands to
>are not necessarily converted to numbers. The abstract relational comparison algorithm callsToPrimitivewith the hintNumber, butToPrimitivemay still return a string (and in the case of both functions and arrays, it does).So you end up comparing two strings. The result of calling
toStringon function objects is not defined by the spec, although most major engines return the source code of the function (or some form of it, and the formatting varies). The result of callingtoStringon arrays is the same asjoin.So the odds are that you’ll end up basically doing this:
Since the exact form of the string for the function may vary from browser-to-browser (and note Esailija’s investigations — looks like IE9 keeps the outer
(), Chrome doesn’t), it’s not too surprising that the result may vary.