我读了一些关于闭包的帖子,到处都看到了这个,但是没有明确的解释它是如何工作的——每次我都被告知要使用它…:
// 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');
为什么要在同一条线上?
你能给我指出一些帖子或者给我一个解释吗?
这就是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!");
make_foo函数体中任何用“var”定义的变量都将被make_foo返回的每个函数关闭,这是毫无意义的。这是一个闭包,这意味着一个函数对值所做的任何更改都将被另一个函数可见。
这让你可以封装信息,如果你想:
function make_greeter(msg){
return function() { alert(msg) };
}
var hello = make_greeter("Hello!");
hello();
除了Java,几乎所有编程语言都是这样工作的。
我感到困惑的一件事是“()”是分组操作符。
这是你声明的基本函数。
例1:
var message = 'SO';
function foo(msg) {
alert(msg);
}
foo(message);
函数是对象,可以分组。我们在函数周围加上括号。
例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。第一行声明了一些无名函数并对其进行分组,但不调用它。第二行对字符串进行分组。两者都不做任何事。(文森特的第一个例子。)
(function (msg){alert(msg)});
('SO'); // nothing.
(foo);
(msg); //Still nothing.
But
(foo)
(msg); //works
综上所述:
function() {
alert("hello");
}();
当未赋值给变量时,将产生语法错误。代码被解析为函数语句(或定义),这使得闭括号在语法上不正确。在函数部分周围添加圆括号告诉解释器(和程序员)这是一个函数表达式(或调用),如
(function() {
alert("hello");
})();
这是一个自调用函数,这意味着它是匿名创建的并立即运行,因为调用发生在声明它的同一行中。这个自调用函数使用熟悉的语法指示为调用无参数函数,在函数名周围加上括号:(myFunction)();。
有一个很好的SO JavaScript函数语法讨论。