为什么这里需要功能名称?

时间:2013-11-07 19:39:57

标签: javascript firefox

我一直在FireFox的浏览器控制台中对此进行测试,不确定其他javascript环境是否有这个:

◄ {x:function(){console.log("test");}}["x"]();
► SyntaxError: function statement requires a name

为什么呢?这虽然有效:

◄ ({x:function(){console.log("test");}})["x"]();
► undefined
► "test"

(如果有人想知道:我真的很讨厌switch,case,break语法。我宁愿使用这种结构。)

4 个答案:

答案 0 :(得分:5)

第一个括号中的括号产生block statement

当注入分号时,第一个看起来像这样

{
    x : function() { 
        console.log("test");
    }
};
["x"]();

答案 1 :(得分:3)

JavaScript的语法可能不明确。第一个示例被解析为块的开放({),后跟标签(x:,您将跳到breakcontinue),然后是函数声明的。声明函数时,必须提供名称。

第二个示例被解析为表达式,因为它括在括号中((),因此{被解释为具有x属性的匿名对象,其值为函数表达式。函数语句可以是匿名的。

答案 2 :(得分:2)

这是因为您正在创建一个块。正如MDN describes

  

块语句用于对零个或多个语句进行分组。该块由一对花括号分隔。

这是一个块:

{}

这是一个声明。它没有返回任何东西。它只是将零个或多个其他语句组合在一起。当Javascript在行的开头看到{时,它会认为“啊哈,我们这里有一个块”。

然而,这不是一个块:

({})

这是一个表达。它有一个返回值。这里,在表达式上下文中,{}分隔对象文字,而不是块。

所以,使用你的代码,让我们分解一下:

{ // start a block
    x: // create a label called x
    function(){console.log("test");} // create a function expression
} // end the block
["x"](); // create an array with one element and attempt to execute it as a function

现在,最后一行显然会失败,但我们永远不会到达那里。当Javascript在行的开头看到function时,它需要一个函数语句。你给它一个匿名函数表达式。这在此上下文中无效并导致错误。


相比之下,你的另一个陈述:

( // start an expression
    { // create an object
        x: function(){console.log("test");} // create a property called x with an anonymous function as its value
    } // end the object
) // end the expression and return the object
["x"] // get the `x` property from the returned object
(); // execute it

答案 3 :(得分:0)

在Opera 12.16中,它除了告诉你

之外基本上都是一样的
["x"] is not a function

它真的不是: 在您的第一个陈述中,您定义

{x:function(){console.log("test");}}

如果您自己输入,则评估为

function(){console.log("test");}

但是如果你没有括号,它会做到这一点,评估一个匿名对象,并开始你的其余声明。 如果你点这样的一个点:

{x:function(){console.log("test");}}.x

会出现语法错误。如果你这样做

({x:function(){console.log("test");}}).x

它会起作用。