【问题标题】:Why is an anonymous function on its own a syntax error in javascript?为什么匿名函数本身就是javascript中的语法错误?
【发布时间】:2012-09-08 09:53:55
【问题描述】:

如果我尝试执行一个脚本,其唯一的源代码行是一个对象:

{prop:'value'}

它解析得很好(在 V8 和 UglifyJS 中)。同样,我可以将一个字符串或数字单独作为源代码,并且不会报告语法错误。

然而,V8 和 UglifyJS 都在抱怨这个问题:

function(){}

我收到Uncaught SyntaxError: Unexpected token (

当第一个示例中的对象正常时,为什么会中断?函数不只是javascript中的对象吗?

我意识到声明一个匿名函数而不执行它不会做任何事情;那不是问题。我想知道为什么会导致解析错误。

【问题讨论】:

  • 因为声明函数遵循function [name] () { [code] } 规则,所以缺少函数名,所以实际的问题可能是:为什么在特殊情况下可以创建匿名函数?
  • “匿名函数”更准确地说是没有可选名称的函数表达式(请参阅FunctionExpression)。
  • 有趣的是只需添加一些操作符就可以了 :) !function(){};+function(){};

标签: javascript parsing syntax grammar anonymous-function


【解决方案1】:

来自 ECMAScript 规范,第 12.4 节关于表达式语句:

请注意,ExpressionStatement 不能以左大括号开头,因为这可能会使它与 Block 混淆。此外,ExpressionStatement 不能以 function 关键字开头,因为这可能会使它与 FunctionDeclaration 产生歧义。

虽然函数只是对象,但请记住,您可以自己声明函数,而无需在表达式中真正使用它们的对象。这就是歧义所在。当然,您永远不能单独声明匿名函数(因为无论如何您都无法引用它),但是由于我在规范中找不到任何区分匿名函数和命名函数声明的内容,我怀疑这一点两者都适用。

为了解决歧义,您需要将其括在括号中,因此它将始终被视为表达式:

(function(){})

【讨论】:

  • 你是对的,用括号括起来是可行的。我看不出function(){} 是如何模棱两可的。还有什么意思?
  • @Andrew——这会很模棱两可,因为它可能是一个函数表达式。请注意,在执行任何代码之前处理函数声明,然后在执行代码时处理函数表达式。
  • @RobG 你的意思是它可能是一个函数声明?怎么可能——它没有名字。
  • 编译器需要明确的规则来处理通常工作的代码(即,在所有情况下的任何地方)。如果命名函数表达式和函数声明可以出现在任何地方,编译器怎么会知道它们之间的区别?如果你这样做,你要么摆脱声明或表达式。你不想要哪个? :-)
  • @RobG 我明白你的意思。如果function(){} 是合法的,那么function f(){} 可以是FunctionExpression 或FunctionDeclaration。我想我从来没有见过使用 named 函数表达式。
【解决方案2】:

{prop:'value'} 不被解析为对象,只是被解析为一个带有标签prop 的块。

您需要 () 将其括起来以解析为表达式。

({prop: 'value'}) 将被解析为对象表达式。

(function(){}) 将被解析为函数表达式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 2020-03-18
    • 1970-01-01
    相关资源
    最近更新 更多