简体   繁体   English

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

[英]Why is a function name required here?

I've been testing this in the browser console of FireFox, not sure if other javascript environments have this: 我一直在FireFox的浏览器控制台中测试它,不确定其他javascript环境是否有这个:

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

Why? 为什么? This works though: 这有效:

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

(In case anyone is wondering: I really hate the switch,case,break syntax. I'd rather use this construction.) (如果有人想知道:我真的很讨厌switch,case,break语法。我宁愿使用这种结构。)

The brackets in the first one is resulting in a block statement . 第一个中的括号产生一个块语句

The first one looks like this when the semicolons are injected 注入分号时,第一个看起来像这样

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

Syntax of JavaScript can be ambiguous. JavaScript的语法可能不明确。 First example is parsed as opening of block ( { ) followed by label ( x: , the one you would jump to by break or continue ), then function declaration . 第一个示例被解析为块( { )的开头,后跟标签( x: :,您将通过breakcontinue跳转到的那个),然后是函数声明 When declaring functions, you have to provide name. 声明函数时,必须提供名称。

Second example is parsed as an expression, as it is enclosed in parentheses ( ( ), so { is interpreted as anonymous object with x property, which value is function expression . Function statements can be anonymous. 第二个示例被解析为表达式,因为它包含在括号( ( )中,因此{被解释为具有x属性的匿名对象,该值是函数表达式 。函数语句可以是匿名的。

This is because you are creating a block. 这是因为您正在创建一个块。 As MDN describes : 正如MDN所描述

A block statement is used to group zero or more statements. 块语句用于对零个或多个语句进行分组。 The block is delimited by a pair of curly brackets. 该块由一对花括号分隔。

This is a block: 这是一个块:

{}

It is a statement. 这是一份声明。 It does not return anything. 它没有返回任何东西。 All it does is group zero or more other statements together. 它只是将零个或多个其他语句组合在一起。 When Javascript sees { at the beginning of a line, it thinks "aha, we have a block here". 当Javascript看到{在行的开头时,它认为“啊哈,我们在这里有一个块”。

This, however, is not a block: 但是,这不是一个块:

({})

That is an expression. 这是一个表达。 It has a return value. 它有一个返回值。 Here, in an expression context, {} delimits an object literal, not a block. 这里,在表达式上下文中, {}分隔对象文字,而不是块。

So, with your code, let's break it up a bit: 所以,使用你的代码,让我们分解一下:

{ // 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

Now, the last line would obviously fail, but we never get there. 现在,最后一行显然会失败,但我们永远不会到达那里。 When Javascript sees function at the beginning of a line, it expects a function statement. 当Javascript在行的开头看到function时,它需要一个函数语句。 You are giving it an anonymous function expression. 你给它一个匿名函数表达式。 This is invalid in this context and causes an error. 这在此上下文中无效并导致错误。


By contrast, your other statement: 相比之下,你的另一个声明:

( // 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

In Opera 12.16, it does basically the same thing, except telling you 在Opera 12.16中,它除了告诉你之外基本上都是一样的

["x"] is not a function

Which it really isn't: In your first statement, you define 它实际上并非如此:在您的第一个声明中,您定义

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

If you enter this on your own, it will evaluate to 如果您自己输入,它将评估为

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

But if you put no parentheses around it, it will do just that, evaluate to an anonymous object and begone for the rest of your statement. 但是如果你没有括号,它会做到这一点,评估一个匿名对象并开始你的其余声明。 If you put a dot like this: 如果你点这样的点:

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

There will be a syntax error. 会出现语法错误。 if you do 如果你这样做

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

it will work. 它会工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM