怪异的JS语法:函数声明中的数学运算符

Weird JS syntax: math operator in function declaration

本文关键字:声明 运算符 JS 语法 函数      更新时间:2023-09-26

我刚玩过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中运行了这个,但我相信,如果推特对此做出回应,它在任何地方都有效。那么,为什么它会起作用,它到底是如何起作用的呢?我相信这在某种程度上与函数返回值及其隐含的类型强制有关,但我仍然不明白

您的URL在API调用中没有转义,因此twitter读取错误并创建无意义的语法。如果您将URL参数设置为转义值(通过encodeURIComponent),它将生成c({some:"Object"}),这是一个JSONP响应-JSONP本质上是一个函数调用,通过注入脚本标记来工作。

所以,twitter并不是故意产生这种响应,你给它传递了有问题的参数,它并没有优雅地失败。

至于为什么在对象中划分函数是NaN——在JS中,数学运算符通常不会抛出。JavaScript告诉你——你试图执行一个没有意义的数学运算,结果不是一个数字——NaN。

对于古怪的结果:

c/()

只是无效的语法,简单地说,如果你什么都不做,5/()也会失败。

c/({})

用一个物体来划分函数是没有意义的,所以它给你的是"不是一个数字"。我可以添加一个规范引用,但我认为除了"没有办法以不同的方式来解释这一点"之外,没有更多的内容可以添加。

c+({})

除了数字加法之外,+运算符还执行字符串串联-因此这里发生的情况是,函数和对象都调用了toString,您可以看到串联的结果。

c({})

这只是函数调用的返回值