javascript - 相同的行, 你为什么需要要调用一个匿名函数?

  显示原文与译文双语对照的内容

我在阅读一些职位有关闭包和看到这些东西都在那个地方,但是没有解释它是如何工作- 只要每次我收到通知,让我用它- -:


//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');

为什么需要在同一行上?

请告诉我一些帖子或者给我解释?

时间:

它被称为self-invoked函数。

当调用 (function(){}) 时,你正在执行的操作返回一个函数对象。 将 () 附加到它时,会调用它,并执行体内的任何内容。 ; 表示语句的结束,这就是 2和调用失败的原因。

这里有一篇关于模式的好文章。 我相信还有其他人。

我发现困惑的一件事是"( ) 是分组操作符。

下面是你的基本声明函数。

例 1:


var message = 'SO';

function foo(msg) {
 alert(msg);
}

foo(message);

函数是对象,可以分组。 让我们在函数周围抛出 parens 。

例 2:


var message = 'SO';

function foo(msg) {//declares foo
 alert(msg);
}

(foo)(message);//calls foo

现在,我们可以使用基本替换来声明它,而不是声明和调用同一个函数。

例如 3 。


var message = 'SO';

(function foo(msg) {
 alert(msg);
})(message);//declares & calls foo

最后,我们不需要额外的foo,因为我们没有使用名字来调用它 ! 函数可以是匿名的。

例如 4.


var message = 'SO';

(function (msg) {//remove unnecessary reference to foo
 alert(msg);
})(message);

要回答你的问题,请参考示例 2. 你的第一行声明了一些未命名的函数,并将它的分组,但不调用它。 第二行将字符串分组。 两者都不做任何事情。首先( vincent示例) 。


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

(foo); 
(msg);//Still nothing.

但是

 
(foo)
(msg);//works

 

匿名函数不是名为""的函数。 它只是一个没有名字的函数。

JavaScript中的其他值一样,函数不需要创建名称。 尽管将它绑定到一个名称,就像其他值一样有用。

但与其他值一样,你有时想要使用它而不将它的绑定到名称。 这是self-invoking模式。

这是一个函数和一个数字,没有绑定,它们没有做任何事情,也不能被使用:


function(){ alert("plop"); }
2;

因此,我们必须将它们存储在变量中,以便能够使用它们,就像其他值一样:


var f = function(){ alert("plop"); }
var n = 2;

你还可以使用 syntatic sugar将函数绑定到变量:


function f(){ alert("plop"); }
var n = 2;

但是如果命名它们不是必需的,并且会导致更多的混乱和可读性,你就可以直接使用它们。


(function(){ alert("plop"); })();//will display"plop"
alert(2 + 3);//will display 5

在这里,我的函数和数字没有绑定到变量,但它们仍然可以使用。

就像这样,self-invoking函数没有真正的价值。 但是你必须记住,JavaScript作用域分隔符是函数而不是块( {} ) 。

因此self-invoking函数实际上与 C++,C# 或者Java块具有相同的含义。 这意味着内部创建的变量不会在作用域之外。 这在JavaScript中非常有用,以免污染全局作用域。

这就是JavaScript的工作原理。 你可以声明一个命名函数:


function foo(msg){
 alert(msg);
}

然后叫它:

 
foo("Hi!");

 

或者,你可以声明一个匿名函数:


var foo = function (msg) {
 alert(msg);
}

然后调用:

 
foo("Hi!");

 

或者,你不能将函数绑定到名称:


(function(msg){
 alert(msg);
 })("Hi!");

函数还可以返回函数:


function make_foo() {
 return function(msg){ alert(msg) };
}

(make_foo())("Hi!");

大家是毫无意义的,任何与"var" make_foo 将被掩上的正文由 make_foo 所返回的每个函数中定义的变量。 这是一个闭包,并且它意味着所做的任何更改该值增加1 函数将由另一个就可见。

如果需要,这允许你封装信息:


function make_greeter(msg){
 return function() { alert(msg) };
}

var hello = make_greeter("Hello!");

hello();

这就是每种编程语言的几乎每一种语言。

你所显示的代码


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

由两个语句组成。 第一个表达式是生成一个 function object (which will then be garbage collected because it is not saved)的表达式。 第二个表达式是生成字符串的表达式。 要将函数应用到字符串,你需要在创建函数时将字符串作为参数传递给函数,或者你需要实际将函数存储在变量中,以便以后在空闲时应用它。 就像这样:


var f = (function (msg){alert(msg)});
f('SO');

注意,通过将匿名函数( 一个lambda函数) 存储在变量中,你可以有效地给它命名。 因此,你也可以定义一个常规函数:


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

这个答案并不是与问题相关的,但是你可能会发现这种语法特性对于函数来说不是特别重要。 例如我们可以总是这样做:


alert(
 {foo:"I am foo", bar:"I am bar"}.foo
);//alerts"I am foo"

函数相关。因为它们是从函数继承的对象,所以我们可以执行以下操作:


Function.prototype.foo = function () {
 return function () {
 alert("foo");
 };
};

var bar = (function () {}).foo();

bar();//alerts foo

你知道,我们甚至不用用括号来包围函数来执行它们。 无论如何,只要我们尝试将结果分配给变量。


var x = function () {} ();//this function is executed but does nothing

function () {} ();//syntax error

当你声明函数时,你可以使用函数来调用 new 运算符并获得一个对象。 以下是等价的:


var obj = new function () {
 this.foo ="bar";
};

var obj = {
 foo :"bar"
};

还有一个属性JavaScript函数。 如果你想递归调用相同的匿名函数。


(function forInternalOnly(){

//you can use forInternalOnly to call this anonymous function
///forInternalOnly can be used inside function only, like
 var result = forInternalOnly();
})();

//this will not work
forInternalOnly();//no such a method exist

在前面的评论中:


function() {
 alert("hello");
}();

未分配给变量时,产生语法错误。 代码被解析为 function statement (or definition),它在语法上不正确地显示右括号。 在函数部分周围添加括号告诉解释器( 和程序员) 是一个 function expression (or invocation),如


(function() {
 alert("hello");
})();

这是一个self-invoking函数,意味着它是匿名创建的,并立即运行,因为调用发生在声明的同一行。 这个self-invoking函数是用熟悉的语法来调用no-argument函数来表示的,并且在函数的名称周围加上了括号: (myFunction)();

有一个很好的讨论JavaScript函数语法

我对asker问题的理解是:

这个魔术如何工作:


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

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


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

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

来源:博客文章 Immediately-Invoked函数表达式( 使用寿命)

...