我读了一些关于闭包的帖子,到处都看到了这个,但是没有明确的解释它是如何工作的——每次我都被告知要使用它…:

// 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)})

然后将创建一个新的未命名函数,如function ""(msg)…

但为什么这行不通呢?

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

为什么要在同一条线上?

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


当前回答

匿名函数是动态声明的函数 运行时。它们被称为匿名函数,因为它们不是 以与普通函数相同的方式命名。

匿名函数使用函数操作符声明 函数声明的。可以使用函数操作符to 在任何可以放置表达式的地方创建一个新函数。为 例如,您可以将一个新函数声明为参数 函数调用或分配另一个对象的属性。

下面是一个命名函数的典型例子:

function flyToTheMoon() {
    alert("Zoom! Zoom! Zoom!"); 
}

flyToTheMoon(); 

下面是创建匿名函数的相同示例:

var flyToTheMoon = function() {
   alert("Zoom! Zoom! Zoom!"); 
}

flyToTheMoon();

详情请浏览http://helephant.com/2008/08/23/javascript-anonymous-functions/

其他回答

我对提问者问题的理解是:

这个魔法是如何起作用的:

(function(){}) ('input')   // Used in his example

我可能错了。然而,人们熟悉的通常做法是:

(function(){}('input') )

原因是JavaScript括号AKA()不能包含语句,当解析器遇到function关键字时,它知道将其解析为函数表达式而不是函数声明。

来源:博客文章立即调用函数表达式(IIFE)

在函数定义之后删除分号。

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

以上应该可以工作。

DEMO页面:https://jsfiddle.net/e7ooeq6m/

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

jQuery和$ questions

编辑:

如果查看ECMA脚本规范,可以使用3种方式定义函数。(第98页,第13节函数定义)

1. 使用函数构造函数

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

2. Using Function声明。

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脚本规范:

FunctionDeclaration: 函数标识符(FormalParameterListopt){函数体 } FunctionExpression: function Identifieropt (FormalParameterListopt){FunctionBody }

如果你注意到,'identifier'对于函数表达式是可选的。当你不给出标识符时,你创建了一个匿名函数。这并不意味着您不能指定标识符。

这意味着以下是有效的。

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.

它不起作用的简单原因不是因为;表示匿名函数结束。这是因为在函数调用的末尾没有(),它就不是函数调用。也就是说,

function help() {return true;}

如果调用result = help();这是对函数的调用,返回true。

如果你拨打result = help;这不是电话。在这种分配中,帮助被视为要分配给结果的数据。

你所做的是通过添加分号来声明/实例化一个匿名函数,

(function (msg) { /* Code here */ });

然后尝试在另一个语句中调用它,只使用括号…显然,因为函数没有名称,但这将不起作用:

('SO');

解释器将第二行上的括号视为一个新的指令/语句,因此它不起作用,即使你这样做:

(function (msg){/*code here*/});('SO');

它仍然不能工作,但当您删除分号时,它可以工作,因为解释器会忽略空白和空格,并将完整的代码视为一条语句。

(function (msg){/*code here*/})        // This space is ignored by the interpreter
('SO');

Conclusion: a function call is not a function call without the () on the end unless under specific conditions such as being invoked by another function, that is, onload='help' would execute the help function even though the parentheses were not included. I believe setTimeout and setInterval also allow this type of function call too, and I also believe that the interpreter adds the parentheses behind the scenes anyhow which brings us back to "a function call is not a function call without the parentheses".

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

这是一种使用匿名函数作为闭包的常见方法,许多JavaScript框架都使用这种方法。

编译代码时自动调用此函数。

如果放置;在第一行,编译器将其视为两个不同的行。所以你不能得到和上面一样的结果。

这也可以写成:

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

要了解更多细节,请参阅JavaScript/匿名函数。

匿名函数是动态声明的函数 运行时。它们被称为匿名函数,因为它们不是 以与普通函数相同的方式命名。

匿名函数使用函数操作符声明 函数声明的。可以使用函数操作符to 在任何可以放置表达式的地方创建一个新函数。为 例如,您可以将一个新函数声明为参数 函数调用或分配另一个对象的属性。

下面是一个命名函数的典型例子:

function flyToTheMoon() {
    alert("Zoom! Zoom! Zoom!"); 
}

flyToTheMoon(); 

下面是创建匿名函数的相同示例:

var flyToTheMoon = function() {
   alert("Zoom! Zoom! Zoom!"); 
}

flyToTheMoon();

详情请浏览http://helephant.com/2008/08/23/javascript-anonymous-functions/