自调用匿名函数解析问题

时间:2011-09-08 02:18:31

标签: javascript

我很难理解这两条线是如何互换的。

( function() { return console.log("anon inner 1"); } ) ();
//                                                     ^^ invoke

( function() { return console.log("anon inner 2"); } () );
//                                                   ^^ invoke

在第一行中,我们有一个匿名的内部函数,它包含在括号中,然后立即被调用。第二行,我们有一个匿名的内部函数,它被调用然后用括号括起来。

我想我的问题是,括号中的包装是做什么的?它是否客观化,即将事物变成对象?

2 个答案:

答案 0 :(得分:3)

JavaScript有一个函数 statement ,这是声明函数的“标准”方式,语法如下:

function name([param1, 2...]) {
   statements
}

还有一个函数 operator ,它看起来与函数语句相同,只是名称是可选的,它不是单独用作语句而是用于<期望em>表达式,如以下两个例子所示:

// declare variable name that references a function created by expression
var name = function([param1, 2...]) { statements };
// call someOtherFunction that expects a function as a parameter
someOtherFunction(function() { });

(还有很多其他方法可以使用函数表达式。)

如果您尝试在一行上单独使用匿名函数而不将其包含在括号中,则它将被视为函数语句,因此是语法错误,因为没有名称。将它括在括号中意味着它将被视为parens中的表达式而不是语句,因此name是可选的。如果将函数表达式的结果赋给变量或以其他方式使用它(如上面的示例中所示),则不需要括号。

因此得到(最后)问题中提到的语法:一旦你有了parens并且你的函数被视为表达式,你可以使用你发布的两种语法中的任何一种来调用它。第一个,调用“外部”的parens意味着第一组parens将评估为具有内部表达式的值,这恰好是您可以调用的函数。第二个,调用“inside”意味着将调用函数表达式,然后周围的parens将评估函数返回的任何内容。

无论哪种方式,函数的返回值都会被丢弃,因为你没有将它赋值给任何东西。

(最后注意:函数表达式可以有一个名称,以便函数可以递归调用自身。)

答案 1 :(得分:1)

当你有一个常规的annon函数时:

function() { alert('testing'); }

这是一个函数表达式。任何其他vairiation称为函数声明,如下所示:

function a() { alert('testing'); }
!function() { alert('testing'); }
var a = function { alert('testing'); }
(function() { alert('testing'); })

现在无法调用函数表达式,因为它没有返回值,但声明可以。因此,您需要做的就是以某种方式将其切换为声明以立即调用,这是parens所做的,无论它们是否包装调用的parens。这是因为一旦js解析器看到一个开放的parens,它就会变成声明

免责声明:我可能混淆了声明表达

的术语