我刚刚和Twitter API一起玩,发现非常怪异的建筑。它是函数名和传递参数之间的除法运算符。
c/({"count":8098,"url":"http:\/\/example.com\/"});
我认为这应该抛出解析器异常,但它可以工作 - 只返回NaN
而不是undefined
。此外,它与*
和-
运算符类似,而+
返回c.toString()
(或.valueOf
,我不知道)。
更重要的是,如果我没有将对象传递给函数,那么它会引发真正的语法错误。以下是一些例子:
function c() {}
>> undefined
c
>> function c() {}
c/()
>> SyntaxError: Unexpected token )
c/({});
>> NaN
c+({})
>> "function c() {}[object Object]"
c({})
>> undefined
我在Chrome中运行了这个,但我相信它可以在任何地方使用,如果Twitter将其作为回应。 所以。为什么这甚至可以工作,以及它是如何工作的?我相信这在一定程度上取决于功能返回值及其隐含的类型强制,但我仍然没有得到它。
答案 0 :(得分:2)
您的网址未在该API调用中进行转义,因此Twitter会错误地读取该网址并创建无意义的语法。
如果您将URL参数设置为转义值(通过encodeURIComponent
),它将生成c({some:"Object"})
这是一个JSONP响应 - JSONP本质上是一个函数调用,并通过注入脚本标记来工作。
所以,twitter并没有故意产生这种反应,你传递了有问题的参数,并没有优雅地失败。
至于为什么在对象中划分一个函数是NaN
- 在JS中,数学运算符通常不会经常抛出。 JavaScript告诉你 - 你试图执行一个没有意义的数学运算,结果不是数字 - NaN。
对于时髦的结果:
c/()
只是语法无效,只是让你无所事事,5/()
同样会失败。
c/({})
通过对象潜水是没有意义的,所以它给你“不是数字”。我可以添加一个规范引用,但我认为除了“没有办法以不同的方式介入”之外还有更多的内容。
c+({})
除了数字加法之外,+
运算符还执行字符串连接 - 所以这里发生的是为函数和对象调用toString
,你会看到连接的结果。
c({})
这只是函数调用的返回值