我一直在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语法。我宁愿使用这种结构。)
答案 0 :(得分:5)
答案 1 :(得分:3)
JavaScript的语法可能不明确。第一个示例被解析为块的开放({
),后跟标签(x:
,您将跳到break
或continue
),然后是函数声明的。声明函数时,必须提供名称。
第二个示例被解析为表达式,因为它括在括号中((
),因此{
被解释为具有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
它会起作用。