Tommi
Tommi

Reputation: 3247

Weird JS syntax: math operator in function declaration

I just played with Twitter API and found very weird construction. It's division operator between function name and arguments passing.

c/({"count":8098,"url":"http:\/\/example.com\/"});

I supposed that this should throw parser exception, but it works − just returning NaN instead of undefined. Also it works similar with * and - operators, while + returns c.toString() (or .valueOf, I dunno). Even more, it's really syntax error thrown if i don't pass object to function. Here's examples:

function c() {}
>> undefined

c
>> function c() {}

c/()
>> SyntaxError: Unexpected token )

c/({});
>> NaN

c+({})
>> "function c() {}[object Object]"

c({})
>> undefined

I ran this in Chrome, but I belive it works everywhere if Twitter put it in response. So. Why this even work, and how it works exactly? I believe this somehow releated to function returning value and its implicit type coercion, but I still don't get it.

Upvotes: 0

Views: 140

Answers (1)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276286

Your URL is not escaped in that API call so twitter reads it incorrectly and creates meaningless syntax. If you set the URL parameter to an escaped value (via encodeURIComponent) it will produce c({some:"Object"}) which is a JSONP response - JSONP is inherently a function call and works by injecting a script tag.

So, twitter does not produce this response deliberately, you're passing it problematic parameters and it's not failing gracefully.

As for why dividing a function in an object is NaN - in JS generally math operators don't throw very often. JavaScript is telling you - you tried to perform a math operation that doesn't make sense and the result is not a number - NaN.

For the funky results:

c/()

Is just invalid syntax, simply put you're diving something by nothing, 5/() would fail equally well.

c/({})

Diving a function by an object makes no sense, so it is giving you "Not a Number". I can add a spec quote but I don't think there is much more to add beyond "There is no way to interperet this differently".

c+({})

The + operator performs string concatenation in addition to numeric addition - so what's happening here is that toString is called for both the function and the object and you see the concatenated result.

c({})

This is just the return value of the function call

Upvotes: 2

Related Questions