A function is larger than an array? A function is larger than an array? arrays arrays

A function is larger than an array?


In IE<9, .toStringing (function (x) {return x*x;}) gives

"(function (x) {return x*x;})" 

While in chrome it gives:

"function (x) {return x*x;}"

If you compare:

"function (x) {return x*x;}" > "1,2,3" // true"(function (x) {return x*x;})"  > "1,2,3"  // false

Which is effectively the same as comparing:

"f" > "1""(" > "1"

Which is the same as comparing:

102 > 4940 > 49

So that's how we get from a function and array comparison to a simple number comparison :)


The operands to > are not necessarily converted to numbers. The abstract relational comparison algorithm calls ToPrimitive with the hint Number, but ToPrimitive may 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 toString on 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 calling toString on arrays is the same as join.

So the odds are that you'll end up basically doing this:

"function (x) {return x*x;}" > "1,2,3"

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.


Let's dive into the ECMA Specification. I've included the section numbers so you can reference.

11.8.2 The Greater-than Operator ( > )

The production RelationalExpression : RelationalExpression > ShiftExpression is evaluated as follows:

  1. Let lref be the result of evaluating RelationalExpression.
  2. Let lval be GetValue(lref).
  3. Let rref be the result of evaluating ShiftExpression.
  4. Let rval be GetValue(rref) .
  5. Let r be the result of performing abstract relational comparison rval < lval with LeftFirst equal to false. (see 11.8.5).

The important part of that is the Abstract Relational Comparison. Which is defined:

11.8.5 The Abstract Relational Comparison Algorithm

The toPrimitive function will first be called on the Objects. Although this is biased to return Numbers if it can, Strings can also be derived. Once this has occurred, the following will be examined:

a. If py is a prefix of px, return false. (A String value p is a prefix of String value q if q can be the result of concatenating p and some other String r. Note that any String is a prefix of itself, because r may be the empty String.)

b. If px is a prefix of py, return true.

c. Let k be the smallest nonnegative integer such that the character at position k within px is different from the character at position k within py. (There must be such a k, for neither String is a prefix of the other.)

d. Let m be the integer that is the code unit value for the character at position k within px. e. Let n be the integer that is the code unit value for the character at position k within py. f. If m < n, return true. Otherwise, return false.

This means that the first character in the String that is different than the other will be examined. As it has been pointed out by Esailija, IE's toString() function returns a slightly different String to that of the other browsers, resulting in a different comparison taking place.

This difference between the browsers appears to be valid as is stated here:

15.2.4.4 Object.prototype.valueOf ( )

When the valueOf method is called, the following steps are taken:

  1. Let O be the result of calling ToObject passing the this value as the argument.
  2. If O is the result of calling the Object constructor with a host object (15.2.2.1), then a. Return either O or another value such as the host object originally passed to the constructor. The specific result that is returned is implementation-defined.
  3. Return O.