为什么需要在同一行上调用匿名函数?

2022-08-29 23:31:36

我正在阅读一些关于关闭的帖子,到处都看到了这一点,但没有明确的解释它是如何工作的 - 每次我都被告知要使用它......:

// Create a new anonymous function, to use as a wrapper
(function(){
    // The variable that would, normally, be global
    var msg = "Thanks for visiting!";

    // Binding a new function to a global object
    window.onunload = function(){
        // Which uses the 'hidden' variable
        alert( msg );
    };
// Close off the anonymous function and execute it
})();

好的,我看到我们将创建新的匿名函数,然后执行它。因此,在此之后,这个简单的代码应该可以工作(它确实可以工作):

(function (msg){alert(msg)})('SO');

我的问题是,这里发生了什么样的魔术?我以为当我写:

(function (msg){alert(msg)})

然后将创建一个新的未命名函数,如函数“”(msg)...

但是为什么这不起作用呢?

(function (msg){alert(msg)});
('SO');

为什么它需要在同一行中?

你能给我一些帖子或给我一个解释吗?


答案 1

删除函数定义后面的分号。

(function (msg){alert(msg)})
('SO');

以上应该有效。

演示页面:https://jsfiddle.net/e7ooeq6m/

我在这篇文章中讨论了这种模式:

jQuery 和 $ 问题

编辑:

如果您查看 ECMA 脚本规范,有 3 种方法可以定义函数。(第98页,第13节 功能定义)

1. 使用函数构造函数

var sum = new Function('a','b', 'return a + b;');
alert(sum(10, 20)); //alerts 30

2. 使用函数声明。

function sum(a, b)
{
    return a + b;
}

alert(sum(10, 10)); //Alerts 20;

3. 函数表达式

var sum = function(a, b) { return a + b; }

alert(sum(5, 5)); // alerts 10

所以你可能会问,声明和表达有什么区别?

来自 ECMA 脚本规范:

FunctionDelaration : Function Identifier ( FormalParameterListopt ){ FunctionBody }

FunctionExpression : function Identifieropt ( FormalParameterListopt ){ FunctionBody }

如果您注意到,“标识符”对于函数表达式是可选的。当您不提供标识符时,您将创建一个匿名函数。这并不意味着您不能指定标识符。

这意味着以下内容是有效的。

var sum = function mySum(a, b) { return a + b; }

需要注意的要点是,您只能在 mySum 函数体内部使用“mySum”,而不能在外部使用。请参阅以下示例:

var test1 = function test2() { alert(typeof test2); }

alert(typeof(test2)); //alerts 'undefined', surprise! 

test1(); //alerts 'function' because test2 is a function.

现场演示

将此与

 function test1() { alert(typeof test1) };

 alert(typeof test1); //alerts 'function'

 test1(); //alerts 'function'

有了这些知识,让我们尝试分析你的代码。

当你有这样的代码时,

    function(msg) { alert(msg); }

您创建了一个函数表达式。您可以通过将其括在括号内来执行此函数表达式。

    (function(msg) { alert(msg); })('SO'); //alerts SO.

答案 2

它被称为自调用函数。

调用时正在执行的操作是返回函数对象。当您追加到它时,它将被调用并执行正文中的任何内容。表示语句的结尾,这就是第二次调用失败的原因。(function(){})();